Version 2.3.2-dev.0.0

Merge commit '21f32e7383ded189de06beff6f26d543b4bd36dd' into dev
diff --git a/CHANGELOG.md b/CHANGELOG.md
index e2243c8..4de047e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,18 +1,31 @@
+## 2.3.2-dev.0.0
+
+### Tools
+
+#### Linter
+
+Updated the linter to `0.1.89`, which includes the following changes:
+
+* Broadened `prefer_null_aware_operators` to work beyond local variables.
+* Added `prefer_if_null_operators`.
+* Fixed `prefer_contains` false positives.
+* Fixed `unnecessary_parenthesis` false positives.
+
 ## 2.3.1-dev.0.0
 
-### Core library changes
+### Core libraries
 
 #### `dart:async`
-* BREAKING CHANGE:
-  Fixes bug in `StreamIterator` which allowed constructor argument to be `null`.
-  Also allowed `await for` on a `null` stream. This is now a runtime error.
+* **Breaking change:**
+  Fixed bug in `StreamIterator` that allowed constructor argument to be `null`
+  and allowed `await for` on a `null` stream. This is now a runtime error.
 
 #### `dart:core`
 
-* **Breaking change**: The `RegExp` interface has been extended with two new
+* **Breaking change:** The `RegExp` interface has been extended with two new
   constructor named parameters:
 
-  * `unicode:` (`bool`, default: `false`), for Unicode patterns , and
+  * `unicode:` (`bool`, default: `false`), for Unicode patterns
   * `dotAll:` (`bool`, default: `false`), to change the matching behavior of
     '.' to also match line terminating characters.
 
@@ -23,8 +36,8 @@
   now return a more specific subtype, `RegExpMatch`, which adds two features:
 
   * `Iterable<String> groupNames`, a property that contains the names of all
-    named capture groups, and
-  * `String namedGroup(String name)`: a method that retrieves the match for
+    named capture groups
+  * `String namedGroup(String name)`, a method that retrieves the match for
     the given named capture group
 
   This change only affects implementers of the `RegExp` interface; current
@@ -32,9 +45,22 @@
 
 #### `dart:isolate`
 
-* BREAKING CHANGE: The `await for` allowed `null` as a stream due to a bug
+* **Breaking change:** The `await for` allowed `null` as a stream due to a bug
   in `StreamIterator` class. This bug has now been fixed.
 
+## 2.3.1 - 2019-05-21
+
+This is a patch version release with bug fixes.
+
+### Tools
+
+#### dart2js
+
+* Fixed a bug that caused the compiler to crash when it compiled UI-as-code
+  features within fields (Issue [36864][]).
+
+[36864]: https://github.com/dart-lang/sdk/issues/36864
+
 ## 2.3.0 - 2019-05-08
 
 The focus in this release is on the new "UI-as-code" language features which
diff --git a/DEPS b/DEPS
index 208ee7a..e9f2353 100644
--- a/DEPS
+++ b/DEPS
@@ -96,7 +96,7 @@
   "intl_tag": "0.15.7",
   "jinja2_rev": "2222b31554f03e62600cd7e383376a7c187967a1",
   "json_rpc_2_tag": "2.0.9",
-  "linter_tag": "0.1.87",
+  "linter_tag": "0.1.89",
   "logging_tag": "0.11.3+2",
   "markupsafe_rev": "8f45f5cfa0009d2a70589bcda0349b8cb2b72783",
   "markdown_tag": "2.0.3",
@@ -157,7 +157,7 @@
   Var("dart_root") + "/tools/sdks": {
       "packages": [{
           "package": "dart/dart-sdk/${{platform}}",
-          "version": "version:2.2.1-dev.3.1",
+          "version": "version:2.3.0",
       }],
       "dep_type": "cipd",
   },
diff --git a/WATCHLISTS b/WATCHLISTS
index 538f457..ea5b5d0 100644
--- a/WATCHLISTS
+++ b/WATCHLISTS
@@ -21,9 +21,6 @@
     'front_end': {
       'filepath': '^pkg/front_end',
     },
-    'http': {
-      'filepath': '^sdk/lib/_http',
-    },
     'kernel': {
       'filepath': '^pkg/kernel',
     },
@@ -68,11 +65,10 @@
   },
 
   'WATCHLISTS': {
-    'build': [ 'zra@google.com', 'keertip@google.com' ],
+    'build': [ 'keertip@google.com' ],
     'dart2js': [ 'johnniwinther@google.com', 'sigmund@google.com',
                  'sra@google.com'],
     'front_end': [ 'dart-fe-team+reviews@google.com' ],
-    'http': [ 'zra@google.com' ],
     'kernel': [ 'karlklose@google.com', 'jensj@google.com', 'kmillikin@google.com',
                 'alexmarkov@google.com' ],
     'messages_review': [ 'dart-uxr+reviews@google.com' ],
diff --git a/pkg/analysis_server/doc/api.html b/pkg/analysis_server/doc/api.html
index c1d8eb8..918ff0b 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.26.0
+  1.26.1
 </h1>
 <p>
   This document contains a specification of the API provided by the
diff --git a/pkg/analysis_server/lib/lsp_protocol/protocol_custom_generated.dart b/pkg/analysis_server/lib/lsp_protocol/protocol_custom_generated.dart
index dc8817d..bfa8c77 100644
--- a/pkg/analysis_server/lib/lsp_protocol/protocol_custom_generated.dart
+++ b/pkg/analysis_server/lib/lsp_protocol/protocol_custom_generated.dart
@@ -14,6 +14,7 @@
 import 'dart:core' hide deprecated;
 import 'dart:core' as core show deprecated;
 import 'dart:convert' show JsonEncoder;
+
 import 'package:analysis_server/lsp_protocol/protocol_special.dart';
 import 'package:analysis_server/src/protocol/protocol_internal.dart'
     show listEqual, mapEqual;
@@ -21,7 +22,141 @@
 
 const jsonEncoder = const JsonEncoder.withIndent('    ');
 
+class AnalyzerStatusParams implements ToJsonable {
+  static const jsonHandler = const LspJsonHandler(
+      AnalyzerStatusParams.canParse, AnalyzerStatusParams.fromJson);
+
+  AnalyzerStatusParams(this.isAnalyzing) {
+    if (isAnalyzing == null) {
+      throw 'isAnalyzing is required but was not provided';
+    }
+  }
+  static AnalyzerStatusParams fromJson(Map<String, dynamic> json) {
+    final isAnalyzing = json['isAnalyzing'];
+    return new AnalyzerStatusParams(isAnalyzing);
+  }
+
+  final bool isAnalyzing;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['isAnalyzing'] =
+        isAnalyzing ?? (throw 'isAnalyzing is required but was not set');
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('isAnalyzing') &&
+        obj['isAnalyzing'] is bool;
+  }
+
+  @override
+  bool operator ==(other) {
+    if (other is AnalyzerStatusParams) {
+      return isAnalyzing == other.isAnalyzing && true;
+    }
+    return false;
+  }
+
+  @override
+  int get hashCode {
+    int hash = 0;
+    hash = JenkinsSmiHash.combine(hash, isAnalyzing.hashCode);
+    return JenkinsSmiHash.finish(hash);
+  }
+
+  @override
+  String toString() => jsonEncoder.convert(toJson());
+}
+
+class CompletionItemResolutionInfo implements ToJsonable {
+  static const jsonHandler = const LspJsonHandler(
+      CompletionItemResolutionInfo.canParse,
+      CompletionItemResolutionInfo.fromJson);
+
+  CompletionItemResolutionInfo(
+      this.file, this.offset, this.libraryId, this.autoImportDisplayUri) {
+    if (file == null) {
+      throw 'file is required but was not provided';
+    }
+    if (offset == null) {
+      throw 'offset is required but was not provided';
+    }
+    if (libraryId == null) {
+      throw 'libraryId is required but was not provided';
+    }
+    if (autoImportDisplayUri == null) {
+      throw 'autoImportDisplayUri is required but was not provided';
+    }
+  }
+  static CompletionItemResolutionInfo fromJson(Map<String, dynamic> json) {
+    final file = json['file'];
+    final offset = json['offset'];
+    final libraryId = json['libraryId'];
+    final autoImportDisplayUri = json['autoImportDisplayUri'];
+    return new CompletionItemResolutionInfo(
+        file, offset, libraryId, autoImportDisplayUri);
+  }
+
+  final String autoImportDisplayUri;
+  final String file;
+  final num libraryId;
+  final num offset;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['file'] = file ?? (throw 'file is required but was not set');
+    __result['offset'] = offset ?? (throw 'offset is required but was not set');
+    __result['libraryId'] =
+        libraryId ?? (throw 'libraryId is required but was not set');
+    __result['autoImportDisplayUri'] = autoImportDisplayUri ??
+        (throw 'autoImportDisplayUri is required but was not set');
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('file') &&
+        obj['file'] is String &&
+        obj.containsKey('offset') &&
+        obj['offset'] is num &&
+        obj.containsKey('libraryId') &&
+        obj['libraryId'] is num &&
+        obj.containsKey('autoImportDisplayUri') &&
+        obj['autoImportDisplayUri'] is String;
+  }
+
+  @override
+  bool operator ==(other) {
+    if (other is CompletionItemResolutionInfo) {
+      return file == other.file &&
+          offset == other.offset &&
+          libraryId == other.libraryId &&
+          autoImportDisplayUri == other.autoImportDisplayUri &&
+          true;
+    }
+    return false;
+  }
+
+  @override
+  int get hashCode {
+    int hash = 0;
+    hash = JenkinsSmiHash.combine(hash, file.hashCode);
+    hash = JenkinsSmiHash.combine(hash, offset.hashCode);
+    hash = JenkinsSmiHash.combine(hash, libraryId.hashCode);
+    hash = JenkinsSmiHash.combine(hash, autoImportDisplayUri.hashCode);
+    return JenkinsSmiHash.finish(hash);
+  }
+
+  @override
+  String toString() => jsonEncoder.convert(toJson());
+}
+
 class DartDiagnosticServer implements ToJsonable {
+  static const jsonHandler = const LspJsonHandler(
+      DartDiagnosticServer.canParse, DartDiagnosticServer.fromJson);
+
   DartDiagnosticServer(this.port) {
     if (port == null) {
       throw 'port is required but was not provided';
diff --git a/pkg/analysis_server/lib/lsp_protocol/protocol_generated.dart b/pkg/analysis_server/lib/lsp_protocol/protocol_generated.dart
index 116d1e3..8ae18ae 100644
--- a/pkg/analysis_server/lib/lsp_protocol/protocol_generated.dart
+++ b/pkg/analysis_server/lib/lsp_protocol/protocol_generated.dart
@@ -14,6 +14,7 @@
 import 'dart:core' hide deprecated;
 import 'dart:core' as core show deprecated;
 import 'dart:convert' show JsonEncoder;
+import 'package:analysis_server/lsp_protocol/protocol_custom_generated.dart';
 import 'package:analysis_server/lsp_protocol/protocol_special.dart';
 import 'package:analysis_server/src/protocol/protocol_internal.dart'
     show listEqual, mapEqual;
@@ -84,36 +85,48 @@
   static const jsonHandler = const LspJsonHandler(
       ApplyWorkspaceEditResponse.canParse, ApplyWorkspaceEditResponse.fromJson);
 
-  ApplyWorkspaceEditResponse(this.applied) {
+  ApplyWorkspaceEditResponse(this.applied, this.failureReason) {
     if (applied == null) {
       throw 'applied is required but was not provided';
     }
   }
   static ApplyWorkspaceEditResponse fromJson(Map<String, dynamic> json) {
     final applied = json['applied'];
-    return new ApplyWorkspaceEditResponse(applied);
+    final failureReason = json['failureReason'];
+    return new ApplyWorkspaceEditResponse(applied, failureReason);
   }
 
   /// Indicates whether the edit was applied or not.
   final bool applied;
 
+  /// An optional textual description for why the edit was not applied. This may
+  /// be used may be used by the server for diagnostic logging or to provide a
+  /// suitable error for a request that triggered the edit.
+  final String failureReason;
+
   Map<String, dynamic> toJson() {
     Map<String, dynamic> __result = {};
     __result['applied'] =
         applied ?? (throw 'applied is required but was not set');
+    if (failureReason != null) {
+      __result['failureReason'] = failureReason;
+    }
     return __result;
   }
 
   static bool canParse(Object obj) {
     return obj is Map<String, dynamic> &&
         obj.containsKey('applied') &&
-        obj['applied'] is bool;
+        obj['applied'] is bool &&
+        (obj['failureReason'] == null || obj['failureReason'] is String);
   }
 
   @override
   bool operator ==(other) {
     if (other is ApplyWorkspaceEditResponse) {
-      return applied == other.applied && true;
+      return applied == other.applied &&
+          failureReason == other.failureReason &&
+          true;
     }
     return false;
   }
@@ -122,6 +135,7 @@
   int get hashCode {
     int hash = 0;
     hash = JenkinsSmiHash.combine(hash, applied.hashCode);
+    hash = JenkinsSmiHash.combine(hash, failureReason.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
 
@@ -1497,7 +1511,9 @@
         json['commitCharacters']?.map((item) => item)?.cast<String>()?.toList();
     final command =
         json['command'] != null ? Command.fromJson(json['command']) : null;
-    final data = json['data'];
+    final data = json['data'] != null
+        ? CompletionItemResolutionInfo.fromJson(json['data'])
+        : null;
     return new CompletionItem(
         label,
         kind,
@@ -1536,9 +1552,9 @@
   /// will be ignored.
   final List<String> commitCharacters;
 
-  /// An data entry field that is preserved on a completion item between a
+  /// A data entry field that is preserved on a completion item between a
   /// completion and a completion resolve request.
-  final dynamic data;
+  final CompletionItemResolutionInfo data;
 
   /// Indicates if this item is deprecated.
   final bool deprecated;
@@ -1572,7 +1588,8 @@
   final InsertTextFormat insertTextFormat;
 
   /// The kind of this completion item. Based of the kind an icon is chosen by
-  /// the editor.
+  /// the editor. The standardized set of available values is defined in
+  /// `CompletionItemKind`.
   final CompletionItemKind kind;
 
   /// The label of this completion item. By default also the text that is
@@ -1670,7 +1687,8 @@
             (obj['commitCharacters'] is List &&
                 (obj['commitCharacters'].every((item) => item is String)))) &&
         (obj['command'] == null || Command.canParse(obj['command'])) &&
-        (obj['data'] == null || true);
+        (obj['data'] == null ||
+            CompletionItemResolutionInfo.canParse(obj['data']));
   }
 
   @override
@@ -1992,22 +2010,34 @@
       CompletionRegistrationOptions.canParse,
       CompletionRegistrationOptions.fromJson);
 
-  CompletionRegistrationOptions(
-      this.triggerCharacters, this.resolveProvider, this.documentSelector);
+  CompletionRegistrationOptions(this.triggerCharacters,
+      this.allCommitCharacters, this.resolveProvider, this.documentSelector);
   static CompletionRegistrationOptions fromJson(Map<String, dynamic> json) {
     final triggerCharacters = json['triggerCharacters']
         ?.map((item) => item)
         ?.cast<String>()
         ?.toList();
+    final allCommitCharacters = json['allCommitCharacters']
+        ?.map((item) => item)
+        ?.cast<String>()
+        ?.toList();
     final resolveProvider = json['resolveProvider'];
     final documentSelector = json['documentSelector']
         ?.map((item) => item != null ? DocumentFilter.fromJson(item) : null)
         ?.cast<DocumentFilter>()
         ?.toList();
-    return new CompletionRegistrationOptions(
-        triggerCharacters, resolveProvider, documentSelector);
+    return new CompletionRegistrationOptions(triggerCharacters,
+        allCommitCharacters, resolveProvider, documentSelector);
   }
 
+  /// The list of all possible characters that commit a completion. This field
+  /// can be used if clients don't support individual commmit characters per
+  /// completion item. See
+  /// `ClientCapabilities.textDocument.completion.completionItem.commitCharactersSupport`
+  ///
+  /// Since 3.2.0
+  final List<String> allCommitCharacters;
+
   /// A document selector to identify the scope of the registration. If set to
   /// null the document selector provided on the client side will be used.
   final List<DocumentFilter> documentSelector;
@@ -2033,6 +2063,9 @@
     if (triggerCharacters != null) {
       __result['triggerCharacters'] = triggerCharacters;
     }
+    if (allCommitCharacters != null) {
+      __result['allCommitCharacters'] = allCommitCharacters;
+    }
     if (resolveProvider != null) {
       __result['resolveProvider'] = resolveProvider;
     }
@@ -2045,6 +2078,10 @@
         (obj['triggerCharacters'] == null ||
             (obj['triggerCharacters'] is List &&
                 (obj['triggerCharacters'].every((item) => item is String)))) &&
+        (obj['allCommitCharacters'] == null ||
+            (obj['allCommitCharacters'] is List &&
+                (obj['allCommitCharacters']
+                    .every((item) => item is String)))) &&
         (obj['resolveProvider'] == null || obj['resolveProvider'] is bool) &&
         obj.containsKey('documentSelector') &&
         (obj['documentSelector'] == null ||
@@ -2058,6 +2095,8 @@
     if (other is CompletionRegistrationOptions) {
       return listEqual(triggerCharacters, other.triggerCharacters,
               (String a, String b) => a == b) &&
+          listEqual(allCommitCharacters, other.allCommitCharacters,
+              (String a, String b) => a == b) &&
           resolveProvider == other.resolveProvider &&
           documentSelector == other.documentSelector &&
           true;
@@ -2069,6 +2108,7 @@
   int get hashCode {
     int hash = 0;
     hash = JenkinsSmiHash.combine(hash, triggerCharacters.hashCode);
+    hash = JenkinsSmiHash.combine(hash, allCommitCharacters.hashCode);
     hash = JenkinsSmiHash.combine(hash, resolveProvider.hashCode);
     hash = JenkinsSmiHash.combine(hash, documentSelector.hashCode);
     return JenkinsSmiHash.finish(hash);
@@ -2889,8 +2929,7 @@
   String toString() => jsonEncoder.convert(toJson());
 }
 
-/// Describe options to be used when registering for text document change
-/// events.
+/// Describe options to be used when registering for file system change events.
 class DidChangeWatchedFilesRegistrationOptions implements ToJsonable {
   static const jsonHandler = const LspJsonHandler(
       DidChangeWatchedFilesRegistrationOptions.canParse,
@@ -7077,7 +7116,8 @@
   final Either2<num, String> id;
   final String jsonrpc;
 
-  /// The result of a request. This can be omitted in the case of an error.
+  /// The result of a request. This member is REQUIRED on success. This member
+  /// MUST NOT exist if there was an error invoking the method.
   final dynamic result;
 
   Map<String, dynamic> toJson() {
@@ -7202,6 +7242,7 @@
       this.documentLinkProvider,
       this.colorProvider,
       this.foldingRangeProvider,
+      this.declarationProvider,
       this.executeCommandProvider,
       this.workspace,
       this.experimental);
@@ -7226,12 +7267,8 @@
         ? SignatureHelpOptions.fromJson(json['signatureHelpProvider'])
         : null;
     final definitionProvider = json['definitionProvider'];
-    final typeDefinitionProvider = json['typeDefinitionProvider'] is bool
-        ? new Either2<bool, dynamic>.t1(json['typeDefinitionProvider'])
-        : (new Either2<bool, dynamic>.t2(json['typeDefinitionProvider']));
-    final implementationProvider = json['implementationProvider'] is bool
-        ? new Either2<bool, dynamic>.t1(json['implementationProvider'])
-        : (new Either2<bool, dynamic>.t2(json['implementationProvider']));
+    final typeDefinitionProvider = json['typeDefinitionProvider'];
+    final implementationProvider = json['implementationProvider'];
     final referencesProvider = json['referencesProvider'];
     final documentHighlightProvider = json['documentHighlightProvider'];
     final documentSymbolProvider = json['documentSymbolProvider'];
@@ -7269,27 +7306,9 @@
     final documentLinkProvider = json['documentLinkProvider'] != null
         ? DocumentLinkOptions.fromJson(json['documentLinkProvider'])
         : null;
-    final colorProvider = json['colorProvider'] is bool
-        ? new Either3<bool, ColorProviderOptions, dynamic>.t1(
-            json['colorProvider'])
-        : (ColorProviderOptions.canParse(json['colorProvider'])
-            ? new Either3<bool, ColorProviderOptions, dynamic>.t2(
-                json['colorProvider'] != null
-                    ? ColorProviderOptions.fromJson(json['colorProvider'])
-                    : null)
-            : (new Either3<bool, ColorProviderOptions, dynamic>.t3(
-                json['colorProvider'])));
-    final foldingRangeProvider = json['foldingRangeProvider'] is bool
-        ? new Either3<bool, FoldingRangeProviderOptions, dynamic>.t1(
-            json['foldingRangeProvider'])
-        : (FoldingRangeProviderOptions.canParse(json['foldingRangeProvider'])
-            ? new Either3<bool, FoldingRangeProviderOptions, dynamic>.t2(
-                json['foldingRangeProvider'] != null
-                    ? FoldingRangeProviderOptions.fromJson(
-                        json['foldingRangeProvider'])
-                    : null)
-            : (new Either3<bool, FoldingRangeProviderOptions, dynamic>.t3(
-                json['foldingRangeProvider'])));
+    final colorProvider = json['colorProvider'];
+    final foldingRangeProvider = json['foldingRangeProvider'];
+    final declarationProvider = json['declarationProvider'];
     final executeCommandProvider = json['executeCommandProvider'] != null
         ? ExecuteCommandOptions.fromJson(json['executeCommandProvider'])
         : null;
@@ -7318,6 +7337,7 @@
         documentLinkProvider,
         colorProvider,
         foldingRangeProvider,
+        declarationProvider,
         executeCommandProvider,
         workspace,
         experimental);
@@ -7334,11 +7354,16 @@
   /// The server provides color provider support.
   ///
   /// Since 3.6.0
-  final Either3<bool, ColorProviderOptions, dynamic> colorProvider;
+  final dynamic colorProvider;
 
   /// The server provides completion support.
   final CompletionOptions completionProvider;
 
+  /// The server provides go to declaration support.
+  ///
+  /// Since 3.14.0
+  final dynamic declarationProvider;
+
   /// The server provides goto definition support.
   final bool definitionProvider;
 
@@ -7369,8 +7394,7 @@
   /// The server provides folding provider support.
   ///
   /// Since 3.10.0
-  final Either3<bool, FoldingRangeProviderOptions, dynamic>
-      foldingRangeProvider;
+  final dynamic foldingRangeProvider;
 
   /// The server provides hover support.
   final bool hoverProvider;
@@ -7378,7 +7402,7 @@
   /// The server provides Goto Implementation support.
   ///
   /// Since 3.6.0
-  final Either2<bool, dynamic> implementationProvider;
+  final dynamic implementationProvider;
 
   /// The server provides find references support.
   final bool referencesProvider;
@@ -7400,7 +7424,7 @@
   /// The server provides Goto Type Definition support.
   ///
   /// Since 3.6.0
-  final Either2<bool, dynamic> typeDefinitionProvider;
+  final dynamic typeDefinitionProvider;
 
   /// Workspace specific server capabilities
   final ServerCapabilitiesWorkspace workspace;
@@ -7472,6 +7496,9 @@
     if (foldingRangeProvider != null) {
       __result['foldingRangeProvider'] = foldingRangeProvider;
     }
+    if (declarationProvider != null) {
+      __result['declarationProvider'] = declarationProvider;
+    }
     if (executeCommandProvider != null) {
       __result['executeCommandProvider'] = executeCommandProvider;
     }
@@ -7496,10 +7523,8 @@
             SignatureHelpOptions.canParse(obj['signatureHelpProvider'])) &&
         (obj['definitionProvider'] == null ||
             obj['definitionProvider'] is bool) &&
-        (obj['typeDefinitionProvider'] == null ||
-            (obj['typeDefinitionProvider'] is bool || true)) &&
-        (obj['implementationProvider'] == null ||
-            (obj['implementationProvider'] is bool || true)) &&
+        (obj['typeDefinitionProvider'] == null || true) &&
+        (obj['implementationProvider'] == null || true) &&
         (obj['referencesProvider'] == null ||
             obj['referencesProvider'] is bool) &&
         (obj['documentHighlightProvider'] == null ||
@@ -7525,15 +7550,9 @@
                 RenameOptions.canParse(obj['renameProvider']))) &&
         (obj['documentLinkProvider'] == null ||
             DocumentLinkOptions.canParse(obj['documentLinkProvider'])) &&
-        (obj['colorProvider'] == null ||
-            (obj['colorProvider'] is bool ||
-                ColorProviderOptions.canParse(obj['colorProvider']) ||
-                true)) &&
-        (obj['foldingRangeProvider'] == null ||
-            (obj['foldingRangeProvider'] is bool ||
-                FoldingRangeProviderOptions.canParse(
-                    obj['foldingRangeProvider']) ||
-                true)) &&
+        (obj['colorProvider'] == null || true) &&
+        (obj['foldingRangeProvider'] == null || true) &&
+        (obj['declarationProvider'] == null || true) &&
         (obj['executeCommandProvider'] == null ||
             ExecuteCommandOptions.canParse(obj['executeCommandProvider'])) &&
         (obj['workspace'] == null ||
@@ -7566,6 +7585,7 @@
           documentLinkProvider == other.documentLinkProvider &&
           colorProvider == other.colorProvider &&
           foldingRangeProvider == other.foldingRangeProvider &&
+          declarationProvider == other.declarationProvider &&
           executeCommandProvider == other.executeCommandProvider &&
           workspace == other.workspace &&
           experimental == other.experimental &&
@@ -7599,6 +7619,7 @@
     hash = JenkinsSmiHash.combine(hash, documentLinkProvider.hashCode);
     hash = JenkinsSmiHash.combine(hash, colorProvider.hashCode);
     hash = JenkinsSmiHash.combine(hash, foldingRangeProvider.hashCode);
+    hash = JenkinsSmiHash.combine(hash, declarationProvider.hashCode);
     hash = JenkinsSmiHash.combine(hash, executeCommandProvider.hashCode);
     hash = JenkinsSmiHash.combine(hash, workspace.hashCode);
     hash = JenkinsSmiHash.combine(hash, experimental.hashCode);
@@ -11205,16 +11226,20 @@
   /// TextDocumentSyncKind.None.
   final TextDocumentSyncKind change;
 
-  /// Open and close notifications are sent to the server.
+  /// Open and close notifications are sent to the server. If omitted open close
+  /// notification should not be sent.
   final bool openClose;
 
-  /// Save notifications are sent to the server.
+  /// If present save notifications are sent to the server. If omitted the
+  /// notification should not be sent.
   final SaveOptions save;
 
-  /// Will save notifications are sent to the server.
+  /// If present will save notifications are sent to the server. If omitted the
+  /// notification should not be sent.
   final bool willSave;
 
-  /// Will save wait until requests are sent to the server.
+  /// If present will save wait until requests are sent to the server. If
+  /// omitted the request should not be sent.
   final bool willSaveWaitUntil;
 
   Map<String, dynamic> toJson() {
@@ -12258,7 +12283,8 @@
     return new WorkspaceFolder(uri, name);
   }
 
-  /// The name of the workspace folder. Defaults to the uri's basename.
+  /// The name of the workspace folder. Used to refer to this workspace folder
+  /// in the user interface.
   final String name;
 
   /// The associated URI for this workspace folder.
diff --git a/pkg/analysis_server/lib/protocol/protocol_constants.dart b/pkg/analysis_server/lib/protocol/protocol_constants.dart
index 35174b9..af958c9 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.26.0';
+const String PROTOCOL_VERSION = '1.26.1';
 
 const String ANALYSIS_NOTIFICATION_ANALYZED_FILES = 'analysis.analyzedFiles';
 const String ANALYSIS_NOTIFICATION_ANALYZED_FILES_DIRECTORIES = 'directories';
diff --git a/pkg/analysis_server/lib/src/analysis_server.dart b/pkg/analysis_server/lib/src/analysis_server.dart
index 4eb8f59..ca242a8 100644
--- a/pkg/analysis_server/lib/src/analysis_server.dart
+++ b/pkg/analysis_server/lib/src/analysis_server.dart
@@ -54,7 +54,6 @@
 import 'package:analyzer/instrumentation/instrumentation.dart';
 import 'package:analyzer/src/context/builder.dart';
 import 'package:analyzer/src/context/context_root.dart';
-import 'package:analyzer/src/dart/analysis/byte_store.dart';
 import 'package:analyzer/src/dart/analysis/driver.dart' as nd;
 import 'package:analyzer/src/dart/analysis/file_state.dart' as nd;
 import 'package:analyzer/src/dart/analysis/performance_logger.dart';
@@ -147,12 +146,6 @@
 
   PerformanceLog _analysisPerformanceLogger;
 
-  ByteStore byteStore;
-  nd.AnalysisDriverScheduler analysisDriverScheduler;
-
-  DeclarationsTracker declarationsTracker;
-  DeclarationsTrackerData declarationsTrackerData;
-
   /// The controller for [onAnalysisSetChanged].
   final StreamController _onAnalysisSetChangedController =
       new StreamController.broadcast(sync: true);
@@ -374,13 +367,6 @@
         resourceProvider.pathContext.normalize(path) == path;
   }
 
-  /// Notify the declarations tracker that the file with the given [path] was
-  /// changed - added, updated, or removed.  Schedule processing of the file.
-  void notifyDeclarationsTracker(String path) {
-    declarationsTracker.changeFile(path);
-    analysisDriverScheduler.notify(null);
-  }
-
   /// Read all files, resolve all URIs, and perform required analysis in
   /// all current analysis drivers.
   void reanalyze() {
@@ -509,7 +495,7 @@
       throw new RequestFailure(
           new Response.unsupportedFeature(requestId, e.message));
     }
-    _addContextsToDeclarationsTracker();
+    addContextsToDeclarationsTracker();
   }
 
   /// Implementation for `analysis.setSubscriptions`.
@@ -576,7 +562,11 @@
   /// Returns `true` if errors should be reported for [file] with the given
   /// absolute path.
   bool shouldSendErrorsNotificationFor(String file) {
-    return contextManager.isInAnalysisRoot(file);
+    // Errors should not be reported for things that are explicitly skipped
+    // during normal analysis (for example dot folders are skipped over in
+    // _handleWatchEventImpl).
+    return contextManager.isInAnalysisRoot(file) &&
+        !contextManager.isContainedInDotFolder(file);
   }
 
   Future<void> shutdown() {
@@ -687,13 +677,6 @@
 //    });
   }
 
-  void _addContextsToDeclarationsTracker() {
-    for (var driver in driverMap.values) {
-      declarationsTracker.addContext(driver.analysisContext);
-      driver.resetUriResolution();
-    }
-  }
-
   /// Return the path to the location of the byte store on disk, or `null` if
   /// there is no on-disk byte store.
   String _getByteStorePath() {
diff --git a/pkg/analysis_server/lib/src/analysis_server_abstract.dart b/pkg/analysis_server/lib/src/analysis_server_abstract.dart
index 3ed2774..c56a762 100644
--- a/pkg/analysis_server/lib/src/analysis_server_abstract.dart
+++ b/pkg/analysis_server/lib/src/analysis_server_abstract.dart
@@ -8,6 +8,7 @@
 import 'package:analysis_server/src/analysis_server.dart';
 import 'package:analysis_server/src/collections.dart';
 import 'package:analysis_server/src/context_manager.dart';
+import 'package:analysis_server/src/domains/completion/available_suggestions.dart';
 import 'package:analysis_server/src/server/diagnostic_server.dart';
 import 'package:analysis_server/src/services/correction/namespace.dart';
 import 'package:analysis_server/src/services/search/element_visitors.dart';
@@ -27,7 +28,9 @@
 import 'package:analyzer/src/dart/analysis/status.dart' as nd;
 import 'package:analyzer/src/dart/ast/element_locator.dart';
 import 'package:analyzer/src/dart/ast/utilities.dart';
+import 'package:analyzer/src/dartdoc/dartdoc_directive_info.dart';
 import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/services/available_declarations.dart';
 import 'package:analyzer/src/util/glob.dart';
 
 /// Implementations of [AbstractAnalysisServer] implement a server that listens
@@ -40,6 +43,13 @@
   /// context directories.
   ContextManager contextManager;
 
+  ByteStore byteStore;
+
+  nd.AnalysisDriverScheduler analysisDriverScheduler;
+
+  DeclarationsTracker declarationsTracker;
+  DeclarationsTrackerData declarationsTrackerData;
+
   /// The DiagnosticServer for this AnalysisServer. If available, it can be used
   /// to start an http diagnostics server or return the port for an existing
   /// server.
@@ -124,6 +134,13 @@
     return new DateTime.now().difference(start);
   }
 
+  void addContextsToDeclarationsTracker() {
+    for (var driver in driverMap.values) {
+      declarationsTracker.addContext(driver.analysisContext);
+      driver.resetUriResolution();
+    }
+  }
+
   /// If the state location can be accessed, return the file byte store,
   /// otherwise return the memory byte store.
   ByteStore createByteStore(ResourceProvider resourceProvider) {
@@ -170,6 +187,13 @@
     return null;
   }
 
+  DartdocDirectiveInfo getDartdocDirectiveInfoFor(ResolvedUnitResult result) {
+    return declarationsTracker
+            .getContext(result.session.analysisContext)
+            ?.dartdocDirectiveInfo ??
+        new DartdocDirectiveInfo();
+  }
+
   /// Return a [Future] that completes with the [Element] at the given
   /// [offset] of the given [file], or with `null` if there is no node at the
   /// [offset] or the node does not have an element.
@@ -260,4 +284,11 @@
         .getResult(path, sendCachedToStream: sendCachedToStream)
         .catchError((_) => null);
   }
+
+  /// Notify the declarations tracker that the file with the given [path] was
+  /// changed - added, updated, or removed.  Schedule processing of the file.
+  void notifyDeclarationsTracker(String path) {
+    declarationsTracker.changeFile(path);
+    analysisDriverScheduler.notify(null);
+  }
 }
diff --git a/pkg/analysis_server/lib/src/context_manager.dart b/pkg/analysis_server/lib/src/context_manager.dart
index 5066368..fa1d36f 100644
--- a/pkg/analysis_server/lib/src/context_manager.dart
+++ b/pkg/analysis_server/lib/src/context_manager.dart
@@ -287,6 +287,12 @@
   List<AnalysisDriver> getDriversInAnalysisRoot(Folder analysisRoot);
 
   /**
+   * Determine whether the given [path], when interpreted relative to innermost
+   * context root, contains a folder whose name starts with '.'.
+   */
+  bool isContainedInDotFolder(String path);
+
+  /**
    * Return `true` if the given [path] is ignored by a [ContextInfo] whose
    * folder contains it.
    */
@@ -556,6 +562,15 @@
     return drivers;
   }
 
+  /**
+   * Determine whether the given [path], when interpreted relative to innermost
+   * context root, contains a folder whose name starts with '.'.
+   */
+  bool isContainedInDotFolder(String path) {
+    ContextInfo info = _getInnermostContextInfoFor(path);
+    return info != null && _isContainedInDotFolder(info.folder.path, path);
+  }
+
   @override
   bool isIgnored(String path) {
     ContextInfo info = rootInfo;
@@ -870,7 +885,7 @@
   }
 
   /**
-   * Use the given analysis [driver] to analyze the content of the 
+   * Use the given analysis [driver] to analyze the content of the
    * AndroidManifest file at the given [path].
    */
   void _analyzeManifestFile(AnalysisDriver driver, String path) {
diff --git a/pkg/analysis_server/lib/src/domain_analysis.dart b/pkg/analysis_server/lib/src/domain_analysis.dart
index e967188..78f7301 100644
--- a/pkg/analysis_server/lib/src/domain_analysis.dart
+++ b/pkg/analysis_server/lib/src/domain_analysis.dart
@@ -21,7 +21,6 @@
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/error/error.dart' as engine;
 import 'package:analyzer/src/dart/analysis/driver.dart';
-import 'package:analyzer/src/dartdoc/dartdoc_directive_info.dart';
 import 'package:analyzer/src/generated/engine.dart' as engine;
 import 'package:analyzer_plugin/protocol/protocol.dart' as plugin;
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
@@ -89,7 +88,7 @@
     List<HoverInformation> hovers = <HoverInformation>[];
     if (unit != null) {
       HoverInformation hoverInformation = new DartUnitHoverComputer(
-              _getDartdocDirectiveInfoFor(result), unit, params.offset)
+              server.getDartdocDirectiveInfoFor(result), unit, params.offset)
           .compute();
       if (hoverInformation != null) {
         hovers.add(hoverInformation);
@@ -279,7 +278,7 @@
     // Ensure the offset provided is a valid location in the file.
     final unit = result.unit;
     final computer = new DartUnitSignatureComputer(
-        _getDartdocDirectiveInfoFor(result), unit, params.offset);
+        server.getDartdocDirectiveInfoFor(result), unit, params.offset);
     if (!computer.offsetIsValid) {
       server.sendResponse(new Response.getSignatureInvalidOffset(request));
       return;
@@ -509,12 +508,4 @@
     server.updateOptions(updaters);
     return new AnalysisUpdateOptionsResult().toResponse(request.id);
   }
-
-  DartdocDirectiveInfo _getDartdocDirectiveInfoFor(ResolvedUnitResult result) {
-    // TODO(brianwilkerson) Consider moving this to AnalysisServer.
-    return server.declarationsTracker
-            .getContext(result.session.analysisContext)
-            ?.dartdocDirectiveInfo ??
-        new DartdocDirectiveInfo();
-  }
 }
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 bee0613..ce8b297 100644
--- a/pkg/analysis_server/lib/src/domains/completion/available_suggestions.dart
+++ b/pkg/analysis_server/lib/src/domains/completion/available_suggestions.dart
@@ -148,7 +148,7 @@
 
 protocol.Element _protocolElement(Declaration declaration) {
   return protocol.Element(
-    _protocolElementKind(declaration.kind),
+    protocolElementKind(declaration.kind),
     declaration.name,
     _protocolElementFlags(declaration),
     location: protocol.Location(
@@ -173,7 +173,12 @@
   );
 }
 
-protocol.ElementKind _protocolElementKind(DeclarationKind kind) {
+// TODO(dantup): We need to expose this because the Declarations code currently
+// returns declarations with DeclarationKinds but the DartCompletionManager
+// gives us a list of "included ElementKinds". Maybe it would be better to expose
+// includedDeclarationKinds and then just map that list to ElementKinds once in
+// domain_completion for the original protocol?
+protocol.ElementKind protocolElementKind(DeclarationKind kind) {
   switch (kind) {
     case DeclarationKind.CLASS:
       return protocol.ElementKind.CLASS;
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 728bb580..c6a3ef7 100644
--- a/pkg/analysis_server/lib/src/edit/fix/dartfix_info.dart
+++ b/pkg/analysis_server/lib/src/edit/fix/dartfix_info.dart
@@ -35,23 +35,10 @@
   //
   const DartFixInfo(
     'double-to-int',
-    'Find double literals ending in .0 and remove the .0\n'
+    'Find double literals ending in .0 and remove the .0 '
     'wherever double context can be inferred.',
     PreferIntLiteralsFix.task,
   ),
-  //
-  // 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.',
-    NonNullableFix.task,
-    isDefault: false,
-  ),
   const DartFixInfo(
     'use-spread-collections',
     'Convert to using collection spread operators.',
@@ -70,6 +57,18 @@
     PreferForElementsToMapFromIterableFix.task,
     isDefault: false,
   ),
+  //
+  // 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'
+    'This requires the experimental non-nullable flag to be enabled.',
+    NonNullableFix.task,
+    isDefault: false,
+  ),
 ];
 
 /// [DartFixInfo] represents a fix that can be applied by [EditDartFix].
diff --git a/pkg/analysis_server/lib/src/edit/fix/fix_lint_task.dart b/pkg/analysis_server/lib/src/edit/fix/fix_lint_task.dart
index 0885046..0a68bcf 100644
--- a/pkg/analysis_server/lib/src/edit/fix/fix_lint_task.dart
+++ b/pkg/analysis_server/lib/src/edit/fix/fix_lint_task.dart
@@ -18,71 +18,6 @@
 import 'package:front_end/src/scanner/token.dart';
 import 'package:source_span/src/span.dart';
 
-/// A task for fixing a particular lint.
-/// Subclasses should implement [applyLocalFixes] and [applyRemainingFixes]
-/// and may override any of the reportSomething() methods as needed.
-abstract class FixLintTask implements ErrorReporter {
-  final DartFixListener listener;
-
-  @override
-  Source source;
-
-  FixLintTask(this.listener);
-
-  /// Apply fixes for the current compilation unit.
-  Future<void> applyLocalFixes(ResolvedUnitResult result);
-
-  /// Apply any fixes remaining after all local changes have been applied.
-  Future<void> applyRemainingFixes();
-
-  @override
-  void reportError(AnalysisError error) {
-    // ignored
-  }
-
-  @override
-  void reportErrorForElement(ErrorCode errorCode, Element element,
-      [List<Object> arguments]) {
-    // ignored
-  }
-
-  @override
-  void reportErrorForNode(ErrorCode errorCode, AstNode node,
-      [List<Object> arguments]) {
-    // ignored
-  }
-
-  @override
-  void reportErrorForOffset(ErrorCode errorCode, int offset, int length,
-      [List<Object> arguments]) {
-    // ignored
-  }
-
-  @override
-  void reportErrorForSpan(ErrorCode errorCode, SourceSpan span,
-      [List<Object> arguments]) {
-    // ignored
-  }
-
-  @override
-  void reportErrorForToken(ErrorCode errorCode, Token token,
-      [List<Object> arguments]) {
-    // ignored
-  }
-
-  @override
-  void reportErrorMessage(
-      ErrorCode errorCode, int offset, int length, Message message) {
-    // ignored
-  }
-
-  @override
-  void reportTypeErrorForNode(
-      ErrorCode errorCode, AstNode node, List<Object> arguments) {
-    // ignored
-  }
-}
-
 /// A processor used by [EditDartFix] to manage [FixLintTask]s.
 mixin FixLintProcessor {
   final linters = <Linter>[];
@@ -168,3 +103,68 @@
     lint.reporter = task;
   }
 }
+
+/// A task for fixing a particular lint.
+/// Subclasses should implement [applyLocalFixes] and [applyRemainingFixes]
+/// and may override any of the reportSomething() methods as needed.
+abstract class FixLintTask implements ErrorReporter {
+  final DartFixListener listener;
+
+  @override
+  Source source;
+
+  FixLintTask(this.listener);
+
+  /// Apply fixes for the current compilation unit.
+  Future<void> applyLocalFixes(ResolvedUnitResult result);
+
+  /// Apply any fixes remaining after all local changes have been applied.
+  Future<void> applyRemainingFixes();
+
+  @override
+  void reportError(AnalysisError error) {
+    // ignored
+  }
+
+  @override
+  void reportErrorForElement(ErrorCode errorCode, Element element,
+      [List<Object> arguments]) {
+    // ignored
+  }
+
+  @override
+  void reportErrorForNode(ErrorCode errorCode, AstNode node,
+      [List<Object> arguments]) {
+    // ignored
+  }
+
+  @override
+  void reportErrorForOffset(ErrorCode errorCode, int offset, int length,
+      [List<Object> arguments]) {
+    // ignored
+  }
+
+  @override
+  void reportErrorForSpan(ErrorCode errorCode, SourceSpan span,
+      [List<Object> arguments]) {
+    // ignored
+  }
+
+  @override
+  void reportErrorForToken(ErrorCode errorCode, Token token,
+      [List<Object> arguments]) {
+    // ignored
+  }
+
+  @override
+  void reportErrorMessage(
+      ErrorCode errorCode, int offset, int length, Message message) {
+    // ignored
+  }
+
+  @override
+  void reportTypeErrorForNode(
+      ErrorCode errorCode, AstNode node, List<Object> arguments) {
+    // ignored
+  }
+}
diff --git a/pkg/analysis_server/lib/src/lsp/constants.dart b/pkg/analysis_server/lib/src/lsp/constants.dart
index 2c4999c..904feeb 100644
--- a/pkg/analysis_server/lib/src/lsp/constants.dart
+++ b/pkg/analysis_server/lib/src/lsp/constants.dart
@@ -9,9 +9,14 @@
   /// A list of all commands IDs that can be sent to the client to inform which
   /// commands should be sent to the server for execution (as opposed to being
   /// executed in the local plugin).
-  static const serverSupportedCommands = [sortMembers, organizeImports];
+  static const serverSupportedCommands = [
+    sortMembers,
+    organizeImports,
+    sendWorkspaceEdit,
+  ];
   static const sortMembers = 'edit.sortMembers';
   static const organizeImports = 'edit.organizeImports';
+  static const sendWorkspaceEdit = 'edit.sendWorkspaceEdit';
 }
 
 /// CodeActionKinds supported by the server that are not declared in the LSP spec.
@@ -41,7 +46,6 @@
   static const FileHasErrors = const ErrorCodes(-32008);
   static const ClientFailedToApplyEdit = const ErrorCodes(-32009);
   static const RenameNotValid = const ErrorCodes(-32010);
-  static const ServerShuttingDown = const ErrorCodes(-32011);
 
   /// An error raised when the server detects that the server and client are out
   /// of sync and cannot recover. For example if a textDocument/didChange notification
@@ -60,4 +64,5 @@
 
 abstract class CustomMethods {
   static const DiagnosticServer = const Method('dart/diagnosticServer');
+  static const AnalyzerStatus = const Method(r'$/analyzerStatus');
 }
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/commands/organize_imports.dart b/pkg/analysis_server/lib/src/lsp/handlers/commands/organize_imports.dart
index 674201f..9c4b4d6 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/commands/organize_imports.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/commands/organize_imports.dart
@@ -49,7 +49,7 @@
       final organizer = new DirectiveOrganizer(code, unit, result.errors);
       final edits = organizer.organize();
 
-      return sendEditsToClient(docIdentifier, unit, edits);
+      return sendSourceEditsToClient(docIdentifier, unit, edits);
     });
   }
 }
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/commands/send_workspace_edit.dart b/pkg/analysis_server/lib/src/lsp/handlers/commands/send_workspace_edit.dart
new file mode 100644
index 0000000..99b061f
--- /dev/null
+++ b/pkg/analysis_server/lib/src/lsp/handlers/commands/send_workspace_edit.dart
@@ -0,0 +1,42 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+
+import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
+import 'package:analysis_server/lsp_protocol/protocol_special.dart';
+import 'package:analysis_server/src/lsp/constants.dart';
+import 'package:analysis_server/src/lsp/handlers/commands/simple_edit_handler.dart';
+import 'package:analysis_server/src/lsp/lsp_analysis_server.dart';
+
+/// This command allows a client to request the server send it a
+/// workspace/applyEdit command, simply passing through the edits provided
+/// by the client. This is to handle completion items that need to make edits
+/// in files other than those containing the completion (not natively supported
+/// by LSP). The edits are put into the [CompletionItem]s command field/
+/// args and when the client calls the server to execute that command, the server
+/// will call the client to execute workspace/applyEdit.
+class SendWorkspaceEditCommandHandler extends SimpleEditCommandHandler {
+  SendWorkspaceEditCommandHandler(LspAnalysisServer server) : super(server);
+
+  @override
+  String get commandName => 'Send Workspace Edit';
+
+  @override
+  Future<ErrorOr<void>> handle(List<dynamic> arguments) async {
+    if (arguments == null ||
+        arguments.length != 1 ||
+        arguments[0] is! Map<String, dynamic>) {
+      return ErrorOr.error(new ResponseError(
+        ServerErrorCodes.InvalidCommandArguments,
+        '$commandName requires a single List argument of WorkspaceEdit',
+        null,
+      ));
+    }
+
+    final workspaceEdit = WorkspaceEdit.fromJson(arguments[0]);
+
+    return await sendWorkspaceEditToClient(workspaceEdit);
+  }
+}
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/commands/simple_edit_handler.dart b/pkg/analysis_server/lib/src/lsp/handlers/commands/simple_edit_handler.dart
index 64c5877..0e60476 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/commands/simple_edit_handler.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/commands/simple_edit_handler.dart
@@ -23,7 +23,7 @@
 
   String get commandName;
 
-  Future<ErrorOr<void>> sendEditsToClient(
+  Future<ErrorOr<void>> sendSourceEditsToClient(
       VersionedTextDocumentIdentifier docIdentifier,
       CompilationUnit unit,
       List<SourceEdit> edits) async {
@@ -38,6 +38,11 @@
       [new FileEditInformation(docIdentifier, unit.lineInfo, edits)],
     );
 
+    return sendWorkspaceEditToClient(workspaceEdit);
+  }
+
+  Future<ErrorOr<void>> sendWorkspaceEditToClient(
+      WorkspaceEdit workspaceEdit) async {
     // Send the edit to the client via a applyEdit request (this is a request
     // from server -> client and the client will provide a response).
     final editResponse = await server.sendRequest(Method.workspace_applyEdit,
@@ -63,7 +68,8 @@
     } else {
       return error(
         ServerErrorCodes.ClientFailedToApplyEdit,
-        'Client failed to apply workspace edit for $commandName',
+        'Client failed to apply workspace edit for $commandName '
+        '(reason: ${editResponseResult.failureReason ?? 'Client did not provide a reason'})',
         workspaceEdit.toString(),
       );
     }
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/commands/sort_members.dart b/pkg/analysis_server/lib/src/lsp/handlers/commands/sort_members.dart
index 680d466..e1aba44 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/commands/sort_members.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/commands/sort_members.dart
@@ -55,6 +55,6 @@
 
     final sorter = new MemberSorter(code, unit);
     final edits = sorter.sort();
-    return await sendEditsToClient(docIdentifier, unit, edits);
+    return await sendSourceEditsToClient(docIdentifier, unit, edits);
   }
 }
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_code_actions.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_code_actions.dart
index c55a22e..b7b5f72 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_code_actions.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_code_actions.dart
@@ -34,6 +34,10 @@
 
   Future<ErrorOr<List<Either2<Command, CodeAction>>>> handle(
       CodeActionParams params) async {
+    if (!isDartDocument(params.textDocument)) {
+      return success(const []);
+    }
+
     final capabilities = server?.clientCapabilities?.textDocument?.codeAction;
 
     final clientSupportsLiteralCodeActions =
@@ -88,7 +92,7 @@
       assist.change.message,
       CodeActionKind.Refactor,
       const [],
-      createWorkspaceEdit(server, assist.change),
+      createWorkspaceEdit(server, assist.change.edits),
       null,
     ));
   }
@@ -103,7 +107,7 @@
       fix.change.message,
       CodeActionKind.QuickFix,
       [diagnostic],
-      createWorkspaceEdit(server, fix.change),
+      createWorkspaceEdit(server, fix.change.edits),
       null,
     ));
   }
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_completion.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_completion.dart
index 67a3fa8..ea2b0a2 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_completion.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_completion.dart
@@ -7,6 +7,8 @@
 
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
 import 'package:analysis_server/lsp_protocol/protocol_special.dart';
+import 'package:analysis_server/protocol/protocol_generated.dart';
+import 'package:analysis_server/src/domains/completion/available_suggestions.dart';
 import 'package:analysis_server/src/lsp/handlers/handlers.dart';
 import 'package:analysis_server/src/lsp/lsp_analysis_server.dart';
 import 'package:analysis_server/src/lsp/mapping.dart';
@@ -15,6 +17,7 @@
 import 'package:analysis_server/src/services/completion/completion_performance.dart';
 import 'package:analysis_server/src/services/completion/dart/completion_manager.dart';
 import 'package:analyzer/dart/analysis/results.dart';
+import 'package:analyzer_plugin/protocol/protocol_common.dart';
 
 // If the client does not provide capabilities.completion.completionItemKind.valueSet
 // then we must never send a kind that's not in this list.
@@ -41,7 +44,11 @@
 
 class CompletionHandler
     extends MessageHandler<CompletionParams, List<CompletionItem>> {
-  CompletionHandler(LspAnalysisServer server) : super(server);
+  final bool suggestFromUnimportedLibraries;
+  CompletionHandler(
+      LspAnalysisServer server, this.suggestFromUnimportedLibraries)
+      : super(server);
+
   Method get handlesMessage => Method.textDocument_completion;
 
   @override
@@ -49,6 +56,10 @@
       CompletionParams.jsonHandler;
 
   Future<ErrorOr<List<CompletionItem>>> handle(CompletionParams params) async {
+    if (!isDartDocument(params.textDocument)) {
+      return success(const []);
+    }
+
     final completionCapabilities =
         server?.clientCapabilities?.textDocument?.completion;
 
@@ -58,6 +69,9 @@
                 completionCapabilities.completionItemKind.valueSet)
             : defaultSupportedCompletionKinds;
 
+    final includeSuggestionSets = suggestFromUnimportedLibraries &&
+        server?.clientCapabilities?.workspace?.applyEdit == true;
+
     final pos = params.position;
     final path = pathOfDoc(params.textDocument);
     final unit = await path.mapResult(requireResolvedUnit);
@@ -65,6 +79,7 @@
     return offset.mapResult((offset) => _getItems(
           completionCapabilities,
           clientSupportedCompletionKinds,
+          includeSuggestionSets,
           unit.result,
           offset,
         ));
@@ -73,6 +88,7 @@
   Future<ErrorOr<List<CompletionItem>>> _getItems(
     TextDocumentClientCapabilitiesCompletion completionCapabilities,
     HashSet<CompletionItemKind> clientSupportedCompletionKinds,
+    bool includeSuggestionSets,
     ResolvedUnitResult unit,
     int offset,
   ) async {
@@ -84,16 +100,21 @@
     final completionRequest =
         new CompletionRequestImpl(unit, offset, performance);
 
+    Set<ElementKind> includedElementKinds;
+    List<IncludedSuggestionRelevanceTag> includedSuggestionRelevanceTags;
+    if (includeSuggestionSets) {
+      includedElementKinds = Set<ElementKind>();
+      includedSuggestionRelevanceTags = <IncludedSuggestionRelevanceTag>[];
+    }
+
     try {
-      CompletionContributor contributor = new DartCompletionManager();
-      final items = await contributor.computeSuggestions(completionRequest);
-
-      performance.notificationCount = 1;
-      performance.suggestionCountFirst = items.length;
-      performance.suggestionCountLast = items.length;
-      performance.complete();
-
-      return success(items
+      CompletionContributor contributor = new DartCompletionManager(
+        includedElementKinds: includedElementKinds,
+        includedSuggestionRelevanceTags: includedSuggestionRelevanceTags,
+      );
+      final suggestions =
+          await contributor.computeSuggestions(completionRequest);
+      final results = suggestions
           .map((item) => toCompletionItem(
                 completionCapabilities,
                 clientSupportedCompletionKinds,
@@ -102,7 +123,54 @@
                 completionRequest.replacementOffset,
                 completionRequest.replacementLength,
               ))
-          .toList());
+          .toList();
+
+      // Now compute items in suggestion sets.
+      List<IncludedSuggestionSet> includedSuggestionSets =
+          includedElementKinds == null || unit == null
+              ? const []
+              : computeIncludedSetList(
+                  server.declarationsTracker,
+                  unit,
+                );
+
+      includedSuggestionSets.forEach((includedSet) {
+        final library = server.declarationsTracker.getLibrary(includedSet.id);
+        if (library == null) {
+          return;
+        }
+
+        // Make a fast lookup for tag relevance.
+        final tagBoosts = <String, int>{};
+        includedSuggestionRelevanceTags
+            .forEach((t) => tagBoosts[t.tag] = t.relevanceBoost);
+
+        final setResults = library.declarations
+            // Filter to only the kinds we should return.
+            .where((item) =>
+                includedElementKinds.contains(protocolElementKind(item.kind)))
+            .map((item) => declarationToCompletionItem(
+                  completionCapabilities,
+                  clientSupportedCompletionKinds,
+                  unit.path,
+                  offset,
+                  includedSet,
+                  library,
+                  tagBoosts,
+                  unit.lineInfo,
+                  item,
+                  completionRequest.replacementOffset,
+                  completionRequest.replacementLength,
+                ));
+        results.addAll(setResults);
+      });
+
+      performance.notificationCount = 1;
+      performance.suggestionCountFirst = results.length;
+      performance.suggestionCountLast = results.length;
+      performance.complete();
+
+      return success(results);
     } on AbortCompletion {
       return success([]);
     }
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_completion_resolve.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_completion_resolve.dart
new file mode 100644
index 0000000..df26ab8
--- /dev/null
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_completion_resolve.dart
@@ -0,0 +1,172 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+
+import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
+import 'package:analysis_server/lsp_protocol/protocol_special.dart';
+import 'package:analysis_server/src/lsp/constants.dart';
+import 'package:analysis_server/src/lsp/handlers/handlers.dart';
+import 'package:analysis_server/src/lsp/lsp_analysis_server.dart';
+import 'package:analysis_server/src/lsp/mapping.dart';
+import 'package:analyzer/dart/analysis/session.dart';
+import 'package:analyzer/dart/element/element.dart' as analyzer;
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
+
+class CompletionResolveHandler
+    extends MessageHandler<CompletionItem, CompletionItem> {
+  ///
+  /// The latest completion item we were asked to resolve. We use it to abort
+  /// previous requests.
+  ///
+  CompletionItem _latestCompletionItem;
+
+  CompletionResolveHandler(LspAnalysisServer server) : super(server);
+
+  Method get handlesMessage => Method.completionItem_resolve;
+
+  @override
+  LspJsonHandler<CompletionItem> get jsonHandler => CompletionItem.jsonHandler;
+
+  Future<ErrorOr<CompletionItem>> handle(CompletionItem item) async {
+    // If this isn't an item with resolution data, return the same item back.
+    if (item.data == null) {
+      return success(item);
+    }
+
+    final data = item.data;
+    final lineInfo = server.getLineInfo(data.file);
+    if (lineInfo == null) {
+      return error(
+        ErrorCodes.InternalError,
+        'Line info not available for ${data.file}',
+        null,
+      );
+    }
+
+    // TODO(dantup): This logic is all repeated from domain_completion and needs
+    // extracting (with support for the different types of responses between
+    // the servers). Where is an appropriate place to put it?
+
+    var library = server.declarationsTracker.getLibrary(data.libraryId);
+    if (library == null) {
+      return error(
+        ErrorCodes.InvalidParams,
+        'Library ID is not valid: ${data.libraryId}',
+        data.libraryId.toString(),
+      );
+    }
+
+    // The label might be `MyEnum.myValue`, but we import only `MyEnum`.
+    var requestedName = item.label;
+    if (requestedName.contains('.')) {
+      requestedName = requestedName.substring(
+        0,
+        requestedName.indexOf('.'),
+      );
+    }
+
+    const timeout = Duration(milliseconds: 1000);
+    var timer = Stopwatch()..start();
+    _latestCompletionItem = item;
+    while (item == _latestCompletionItem && timer.elapsed < timeout) {
+      try {
+        var analysisDriver = server.getAnalysisDriver(data.file);
+        var session = analysisDriver.currentSession;
+
+        var fileElement = await session.getUnitElement(data.file);
+        var libraryPath = fileElement.element.librarySource.fullName;
+
+        var resolvedLibrary = await session.getResolvedLibrary(libraryPath);
+
+        analyzer.LibraryElement requestedLibraryElement;
+        try {
+          requestedLibraryElement = await session.getLibraryByUri(
+            library.uriStr,
+          );
+        } on ArgumentError catch (e) {
+          return error(
+            ErrorCodes.InvalidParams,
+            'Invalid library URI: ${library.uriStr}',
+            '$e',
+          );
+        }
+
+        var requestedElement =
+            requestedLibraryElement.exportNamespace.get(requestedName);
+        if (requestedElement == null) {
+          return error(
+            ErrorCodes.InvalidParams,
+            'No such element: $requestedName',
+            requestedName,
+          );
+        }
+
+        var newLabel = item.label;
+        final builder = DartChangeBuilder(session);
+        await builder.addFileEdit(libraryPath, (builder) {
+          final result = builder.importLibraryElement(
+            targetLibrary: resolvedLibrary,
+            targetPath: libraryPath,
+            targetOffset: data.offset,
+            requestedLibrary: requestedLibraryElement,
+            requestedElement: requestedElement,
+          );
+          if (result.prefix != null) {
+            newLabel = '${result.prefix}.$newLabel';
+          }
+        });
+
+        final changes = builder.sourceChange;
+        final thisFilesChanges =
+            changes.edits.where((e) => e.file == data.file).toList();
+        final otherFilesChanges =
+            changes.edits.where((e) => e.file != data.file).toList();
+
+        // If this completion involves editing other files, we'll need to build
+        // a command that the client will call to apply those edits later.
+        Command command;
+        if (otherFilesChanges.isNotEmpty) {
+          final workspaceEdit = createWorkspaceEdit(server, otherFilesChanges);
+          command = Command(
+              'Add import', Commands.sendWorkspaceEdit, [workspaceEdit]);
+        }
+
+        return success(CompletionItem(
+          newLabel,
+          item.kind,
+          data.autoImportDisplayUri != null
+              ? "Auto import from '${data.autoImportDisplayUri}'\n\n${item.detail ?? ''}"
+                  .trim()
+              : item.detail,
+          item.documentation,
+          item.deprecated,
+          item.preselect,
+          item.sortText,
+          item.filterText,
+          newLabel,
+          item.insertTextFormat,
+          item.textEdit,
+          thisFilesChanges
+              .expand((change) =>
+                  change.edits.map((edit) => toTextEdit(lineInfo, edit)))
+              .toList(),
+          item.commitCharacters,
+          command ?? item.command,
+          item.data,
+        ));
+      } on InconsistentAnalysisException {
+        // Loop around to try again.
+      }
+    }
+
+    // Timeout or abort, send the empty response.
+
+    return error(
+      ErrorCodes.RequestCancelled,
+      'Request was cancelled for taking too long or another request being received',
+      null,
+    );
+  }
+}
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_definition.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_definition.dart
index 51f7b2f..ead355a 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_definition.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_definition.dart
@@ -24,6 +24,10 @@
 
   Future<ErrorOr<List<Location>>> handle(
       TextDocumentPositionParams params) async {
+    if (!isDartDocument(params.textDocument)) {
+      return success(const []);
+    }
+
     final pos = params.position;
     final path = pathOfDoc(params.textDocument);
     final unit = await path.mapResult(requireResolvedUnit);
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_document_highlights.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_document_highlights.dart
index c2fabbd..5be52b6 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_document_highlights.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_document_highlights.dart
@@ -23,6 +23,10 @@
 
   Future<ErrorOr<List<DocumentHighlight>>> handle(
       TextDocumentPositionParams params) async {
+    if (!isDartDocument(params.textDocument)) {
+      return success(const []);
+    }
+
     final pos = params.position;
     final path = pathOfDoc(params.textDocument);
     final unit = await path.mapResult(requireResolvedUnit);
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_document_symbols.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_document_symbols.dart
index 6c5b120..a4c623b 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_document_symbols.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_document_symbols.dart
@@ -49,6 +49,12 @@
 
   Future<ErrorOr<Either2<List<DocumentSymbol>, List<SymbolInformation>>>>
       handle(DocumentSymbolParams params) async {
+    if (!isDartDocument(params.textDocument)) {
+      return success(
+        Either2<List<DocumentSymbol>, List<SymbolInformation>>.t2([]),
+      );
+    }
+
     final symbolCapabilities =
         server?.clientCapabilities?.textDocument?.documentSymbol;
 
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_execute_command.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_execute_command.dart
index b40f4b4..c440afe 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_execute_command.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_execute_command.dart
@@ -8,6 +8,7 @@
 import 'package:analysis_server/lsp_protocol/protocol_special.dart';
 import 'package:analysis_server/src/lsp/constants.dart';
 import 'package:analysis_server/src/lsp/handlers/commands/organize_imports.dart';
+import 'package:analysis_server/src/lsp/handlers/commands/send_workspace_edit.dart';
 import 'package:analysis_server/src/lsp/handlers/commands/sort_members.dart';
 import 'package:analysis_server/src/lsp/handlers/handlers.dart';
 import 'package:analysis_server/src/lsp/lsp_analysis_server.dart';
@@ -21,6 +22,8 @@
       : commandHandlers = {
           Commands.sortMembers: new SortMembersCommandHandler(server),
           Commands.organizeImports: new OrganizeImportsCommandHandler(server),
+          Commands.sendWorkspaceEdit:
+              new SendWorkspaceEditCommandHandler(server),
         },
         super(server);
 
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_folding.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_folding.dart
index 50d8ca3..7ad848d 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_folding.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_folding.dart
@@ -21,6 +21,10 @@
       FoldingRangeParams.jsonHandler;
 
   Future<ErrorOr<List<FoldingRange>>> handle(FoldingRangeParams params) async {
+    if (!isDartDocument(params.textDocument)) {
+      return success(const []);
+    }
+
     final path = pathOfDoc(params.textDocument);
     final unit = await path.mapResult(requireUnresolvedUnit);
 
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_hover.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_hover.dart
index 7d0db4f..bd70948 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_hover.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_hover.dart
@@ -14,7 +14,6 @@
 import 'package:analysis_server/src/lsp/mapping.dart';
 import 'package:analyzer/dart/analysis/results.dart';
 import 'package:analyzer/source/line_info.dart';
-import 'package:analyzer/src/dartdoc/dartdoc_directive_info.dart';
 
 class HoverHandler extends MessageHandler<TextDocumentPositionParams, Hover> {
   HoverHandler(LspAnalysisServer server) : super(server);
@@ -25,6 +24,10 @@
       TextDocumentPositionParams.jsonHandler;
 
   Future<ErrorOr<Hover>> handle(TextDocumentPositionParams params) async {
+    if (!isDartDocument(params.textDocument)) {
+      return success(null);
+    }
+
     final pos = params.position;
     final path = pathOfDoc(params.textDocument);
     final unit = await path.mapResult(requireResolvedUnit);
@@ -84,14 +87,7 @@
 
   ErrorOr<Hover> _getHover(ResolvedUnitResult unit, int offset) {
     final hover = new DartUnitHoverComputer(
-            // TODO(brianwilkerson) Add declarationsTracker to server in order to
-            //  enable dartdoc processing.
-//            server.declarationsTracker
-//                .getContext(unit.session.analysisContext)
-//                .dartdocDirectiveInfo,
-            new DartdocDirectiveInfo(),
-            unit.unit,
-            offset)
+            server.getDartdocDirectiveInfoFor(unit), unit.unit, offset)
         .compute();
     return success(toHover(unit.lineInfo, hover));
   }
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_implementation.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_implementation.dart
new file mode 100644
index 0000000..e131307
--- /dev/null
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_implementation.dart
@@ -0,0 +1,88 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+
+import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
+import 'package:analysis_server/lsp_protocol/protocol_special.dart';
+import 'package:analysis_server/protocol/protocol_generated.dart';
+import 'package:analysis_server/src/lsp/handlers/handlers.dart';
+import 'package:analysis_server/src/lsp/lsp_analysis_server.dart';
+import 'package:analysis_server/src/lsp/mapping.dart';
+import 'package:analysis_server/src/search/type_hierarchy.dart';
+
+class ImplementationHandler
+    extends MessageHandler<TextDocumentPositionParams, List<Location>> {
+  ImplementationHandler(LspAnalysisServer server) : super(server);
+  Method get handlesMessage => Method.textDocument_implementation;
+
+  @override
+  LspJsonHandler<TextDocumentPositionParams> get jsonHandler =>
+      TextDocumentPositionParams.jsonHandler;
+
+  @override
+  Future<ErrorOr<List<Location>>> handle(
+      TextDocumentPositionParams params) async {
+    if (!isDartDocument(params.textDocument)) {
+      return success(const []);
+    }
+
+    final pos = params.position;
+    final path = pathOfDoc(params.textDocument);
+    final unit = await path.mapResult(requireResolvedUnit);
+    final offset = await unit.mapResult((unit) => toOffset(unit.lineInfo, pos));
+    return offset
+        .mapResult((offset) => _getImplementations(path.result, offset));
+  }
+
+  Future<ErrorOr<List<Location>>> _getImplementations(
+      String file, int offset) async {
+    final element = await server.getElementAtOffset(file, offset);
+    final computer = new TypeHierarchyComputer(server.searchEngine, element);
+    final items = await computer.compute();
+
+    if (items == null || items.isEmpty) {
+      return success([]);
+    }
+
+    Iterable<TypeHierarchyItem> getDescendants(TypeHierarchyItem item) => item
+        .subclasses
+        ?.map((i) => items[i])
+        ?.followedBy(item.subclasses.expand((i) => getDescendants(items[i])));
+
+    // [TypeHierarchyComputer] returns the whole tree, but we specifically only
+    // want implementations (sub-classes). Find the referenced element and then
+    // recursively add its children.
+    var currentItem = items.firstWhere(
+      (item) {
+        final location =
+            item.memberElement?.location ?? item.classElement?.location;
+        return location.offset <= offset &&
+            location.offset + location.length >= offset;
+      },
+      // If we didn't find an item spanning our offset, we must've been at a
+      // call site so start everything from the root item.
+      orElse: () => items.first,
+    );
+
+    final isClass = currentItem.memberElement == null;
+
+    final locations = getDescendants(currentItem).where((item) {
+      // Filter based on type, so when searching for members we don't include
+      // any intermediate classes that don't have implementations for the
+      // method.
+      return isClass ? item.classElement != null : item.memberElement != null;
+    }).map((item) {
+      final elementLocation =
+          item.memberElement?.location ?? item.classElement?.location;
+      final lineInfo = server.getLineInfo(elementLocation.file);
+      return Location(
+        Uri.file(elementLocation.file).toString(),
+        toRange(lineInfo, elementLocation.offset, elementLocation.length),
+      );
+    }).toList();
+
+    return success(locations);
+  }
+}
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_initialize.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_initialize.dart
index 88423de..ea1ed19 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_initialize.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_initialize.dart
@@ -31,6 +31,13 @@
             true
         : false;
 
+    // The suggestFromUnimportedLibraries flag allows clients to opt-out of
+    // behaviour of including suggestions that are not imported. Defaults to true,
+    // so must be explicitly passed as false to disable.
+    final suggestFromUnimportedLibraries = params.initializationOptions ==
+            null ||
+        params.initializationOptions['suggestFromUnimportedLibraries'] != false;
+
     if (!onlyAnalyzeProjectsWithOpenFiles) {
       if (params.workspaceFolders != null) {
         params.workspaceFolders.forEach((wf) {
@@ -50,7 +57,11 @@
 
     server.handleClientConnection(params.capabilities);
     server.messageHandler = new InitializingStateMessageHandler(
-        server, openWorkspacePaths, onlyAnalyzeProjectsWithOpenFiles);
+      server,
+      openWorkspacePaths,
+      onlyAnalyzeProjectsWithOpenFiles,
+      suggestFromUnimportedLibraries,
+    );
 
     final codeActionLiteralSupport =
         params.capabilities.textDocument?.codeAction?.codeActionLiteralSupport;
@@ -68,7 +79,7 @@
         )),
         true, // hoverProvider
         new CompletionOptions(
-          false,
+          true, // resolveProvider
           // Set the characters that will cause the editor to automatically
           // trigger completion.
           // TODO(dantup): There are several characters that we want to conditionally
@@ -99,7 +110,7 @@
         ),
         true, // definitionProvider
         null,
-        null,
+        true, // implementationProvider
         true, // referencesProvider
         true, // documentHighlightProvider
         true, // documentSymbolProvider
@@ -120,8 +131,9 @@
             : Either2<bool, RenameOptions>.t1(true),
         null,
         null,
-        Either3<bool, FoldingRangeProviderOptions, dynamic>.t1(true),
+        true, // foldingRangeProvider
         new ExecuteCommandOptions(Commands.serverSupportedCommands),
+        null, // declarationProvider
         new ServerCapabilitiesWorkspace(
             new ServerCapabilitiesWorkspaceFolders(true, true)),
         null);
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_initialized.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_initialized.dart
index 463ac9e..ea74fc5 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_initialized.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_initialized.dart
@@ -10,10 +10,13 @@
 
 class IntializedMessageHandler extends MessageHandler<InitializedParams, void> {
   final List<String> openWorkspacePaths;
-  final bool onlyAnalyzeProjectsWithOpenFiles;
-  IntializedMessageHandler(LspAnalysisServer server, this.openWorkspacePaths,
-      this.onlyAnalyzeProjectsWithOpenFiles)
-      : super(server);
+  final bool onlyAnalyzeProjectsWithOpenFiles, suggestFromUnimportedLibraries;
+  IntializedMessageHandler(
+    LspAnalysisServer server,
+    this.openWorkspacePaths,
+    this.onlyAnalyzeProjectsWithOpenFiles,
+    this.suggestFromUnimportedLibraries,
+  ) : super(server);
   Method get handlesMessage => Method.initialized;
 
   @override
@@ -22,7 +25,10 @@
 
   ErrorOr<void> handle(InitializedParams params) {
     server.messageHandler = new InitializedStateMessageHandler(
-        server, onlyAnalyzeProjectsWithOpenFiles);
+      server,
+      onlyAnalyzeProjectsWithOpenFiles,
+      suggestFromUnimportedLibraries,
+    );
 
     if (!onlyAnalyzeProjectsWithOpenFiles) {
       server.setAnalysisRoots(openWorkspacePaths);
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_references.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_references.dart
index c025819..f410e9f 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_references.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_references.dart
@@ -29,6 +29,10 @@
 
   @override
   Future<ErrorOr<List<Location>>> handle(ReferenceParams params) async {
+    if (!isDartDocument(params.textDocument)) {
+      return success(const []);
+    }
+
     final pos = params.position;
     final path = pathOfDoc(params.textDocument);
     final unit = await path.mapResult(requireResolvedUnit);
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_rename.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_rename.dart
index 86c39e9..d997719 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_rename.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_rename.dart
@@ -137,7 +137,7 @@
             'Document was modified while rename was being computed', null);
       }
 
-      final workspaceEdit = createWorkspaceEdit(server, change);
+      final workspaceEdit = createWorkspaceEdit(server, change.edits);
       return success(workspaceEdit);
     });
   }
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_signature_help.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_signature_help.dart
index 7fa60a7..cde88c9 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_signature_help.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_signature_help.dart
@@ -10,7 +10,6 @@
 import 'package:analysis_server/src/lsp/handlers/handlers.dart';
 import 'package:analysis_server/src/lsp/lsp_analysis_server.dart';
 import 'package:analysis_server/src/lsp/mapping.dart';
-import 'package:analyzer/src/dartdoc/dartdoc_directive_info.dart';
 
 class SignatureHelpHandler
     extends MessageHandler<TextDocumentPositionParams, SignatureHelp> {
@@ -23,6 +22,10 @@
 
   Future<ErrorOr<SignatureHelp>> handle(
       TextDocumentPositionParams params) async {
+    if (!isDartDocument(params.textDocument)) {
+      return success(null);
+    }
+
     final pos = params.position;
     final path = pathOfDoc(params.textDocument);
     final unit = await path.mapResult(requireResolvedUnit);
@@ -30,12 +33,7 @@
 
     return offset.mapResult((offset) {
       final computer = new DartUnitSignatureComputer(
-          // TODO(brianwilkerson) Add declarationsTracker to server in order to
-          //  enable dartdoc processing.
-//          server.declarationsTracker
-//              .getContext(unit.result.session.analysisContext)
-//              .dartdocDirectiveInfo,
-          new DartdocDirectiveInfo(),
+          server.getDartdocDirectiveInfoFor(unit.result),
           unit.result.unit,
           offset);
       if (!computer.offsetIsValid) {
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_states.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_states.dart
index cd79433..60b6f53 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_states.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_states.dart
@@ -10,6 +10,7 @@
 import 'package:analysis_server/src/lsp/handlers/custom/handler_diagnostic_server.dart';
 import 'package:analysis_server/src/lsp/handlers/handler_code_actions.dart';
 import 'package:analysis_server/src/lsp/handlers/handler_completion.dart';
+import 'package:analysis_server/src/lsp/handlers/handler_completion_resolve.dart';
 import 'package:analysis_server/src/lsp/handlers/handler_definition.dart';
 import 'package:analysis_server/src/lsp/handlers/handler_document_highlights.dart';
 import 'package:analysis_server/src/lsp/handlers/handler_document_symbols.dart';
@@ -19,6 +20,7 @@
 import 'package:analysis_server/src/lsp/handlers/handler_format_on_type.dart';
 import 'package:analysis_server/src/lsp/handlers/handler_formatting.dart';
 import 'package:analysis_server/src/lsp/handlers/handler_hover.dart';
+import 'package:analysis_server/src/lsp/handlers/handler_implementation.dart';
 import 'package:analysis_server/src/lsp/handlers/handler_initialize.dart';
 import 'package:analysis_server/src/lsp/handlers/handler_initialized.dart';
 import 'package:analysis_server/src/lsp/handlers/handler_references.dart';
@@ -50,6 +52,7 @@
   InitializedStateMessageHandler(
     LspAnalysisServer server,
     bool onlyAnalyzeProjectsWithOpenFiles,
+    bool suggestFromUnimportedLibraries,
   ) : super(server) {
     reject(Method.initialize, ServerErrorCodes.ServerAlreadyInitialized,
         'Server already initialized');
@@ -65,10 +68,13 @@
       new TextDocumentCloseHandler(server, onlyAnalyzeProjectsWithOpenFiles),
     );
     registerHandler(new HoverHandler(server));
-    registerHandler(new CompletionHandler(server));
+    registerHandler(
+        new CompletionHandler(server, suggestFromUnimportedLibraries));
+    registerHandler(new CompletionResolveHandler(server));
     registerHandler(new SignatureHelpHandler(server));
     registerHandler(new DefinitionHandler(server));
     registerHandler(new ReferencesHandler(server));
+    registerHandler(new ImplementationHandler(server));
     registerHandler(new FormattingHandler(server));
     registerHandler(new FormatOnTypeHandler(server));
     registerHandler(new DocumentHighlightsHandler(server));
@@ -87,15 +93,22 @@
 }
 
 class InitializingStateMessageHandler extends ServerStateMessageHandler {
-  InitializingStateMessageHandler(LspAnalysisServer server,
-      List<String> openWorkspacePaths, bool onlyAnalyzeProjectsWithOpenFiles)
-      : super(server) {
+  InitializingStateMessageHandler(
+    LspAnalysisServer server,
+    List<String> openWorkspacePaths,
+    bool onlyAnalyzeProjectsWithOpenFiles,
+    bool suggestFromUnimportedLibraries,
+  ) : super(server) {
     reject(Method.initialize, ServerErrorCodes.ServerAlreadyInitialized,
         'Server already initialized');
     registerHandler(new ShutdownMessageHandler(server));
     registerHandler(new ExitMessageHandler(server));
     registerHandler(new IntializedMessageHandler(
-        server, openWorkspacePaths, onlyAnalyzeProjectsWithOpenFiles));
+      server,
+      openWorkspacePaths,
+      onlyAnalyzeProjectsWithOpenFiles,
+      suggestFromUnimportedLibraries,
+    ));
   }
 
   @override
@@ -141,7 +154,7 @@
     if (message is! RequestMessage) {
       return success();
     }
-    return failure(ServerErrorCodes.ServerShuttingDown,
+    return failure(ErrorCodes.InvalidRequest,
         'Unable to handle ${message.method} after shutdown request');
   }
 }
diff --git a/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart b/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart
index a1c6cf2..e8f5112 100644
--- a/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart
+++ b/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart
@@ -6,6 +6,7 @@
 import 'dart:collection';
 import 'dart:io' as io;
 
+import 'package:analysis_server/lsp_protocol/protocol_custom_generated.dart';
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
 import 'package:analysis_server/lsp_protocol/protocol_special.dart';
 import 'package:analysis_server/protocol/protocol_generated.dart' as protocol;
@@ -15,6 +16,7 @@
 import 'package:analysis_server/src/context_manager.dart';
 import 'package:analysis_server/src/domain_completion.dart'
     show CompletionDomainHandler;
+import 'package:analysis_server/src/domains/completion/available_suggestions.dart';
 import 'package:analysis_server/src/lsp/channel/lsp_channel.dart';
 import 'package:analysis_server/src/lsp/constants.dart';
 import 'package:analysis_server/src/lsp/handlers/handler_states.dart';
@@ -35,7 +37,6 @@
 import 'package:analyzer/source/line_info.dart';
 import 'package:analyzer/src/context/builder.dart';
 import 'package:analyzer/src/context/context_root.dart';
-import 'package:analyzer/src/dart/analysis/byte_store.dart';
 import 'package:analyzer/src/dart/analysis/driver.dart' as nd;
 import 'package:analyzer/src/dart/analysis/file_state.dart' as nd;
 import 'package:analyzer/src/dart/analysis/performance_logger.dart';
@@ -43,6 +44,7 @@
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/sdk.dart';
 import 'package:analyzer/src/plugin/resolver_provider.dart';
+import 'package:analyzer/src/services/available_declarations.dart';
 import 'package:watcher/watcher.dart';
 
 /**
@@ -114,10 +116,6 @@
 
   PerformanceLog _analysisPerformanceLogger;
 
-  ByteStore byteStore;
-
-  nd.AnalysisDriverScheduler analysisDriverScheduler;
-
   ServerStateMessageHandler messageHandler;
 
   int nextRequestId = 1;
@@ -150,6 +148,8 @@
     ResolverProvider packageResolverProvider: null,
   }) : super(options, diagnosticServer, baseResourceProvider) {
     messageHandler = new UninitializedStateMessageHandler(this);
+    // TODO(dantup): This code is almost identical to AnalysisServer, consider
+    // moving it the base class that already holds many of these fields.
     defaultContextOptions.generateImplicitErrors = false;
     defaultContextOptions.useFastaParser = options.useFastaParser;
 
@@ -169,8 +169,14 @@
     byteStore = createByteStore(resourceProvider);
     analysisDriverScheduler =
         new nd.AnalysisDriverScheduler(_analysisPerformanceLogger);
+    analysisDriverScheduler.status.listen(sendStatusNotification);
     analysisDriverScheduler.start();
 
+    declarationsTracker = DeclarationsTracker(byteStore, resourceProvider);
+    declarationsTrackerData = DeclarationsTrackerData(declarationsTracker);
+    analysisDriverScheduler.outOfBandWorker =
+        CompletionLibrariesWorker(declarationsTracker);
+
     contextManager = new ContextManagerImpl(
         resourceProvider,
         sdkManager,
@@ -343,9 +349,6 @@
     if (message is RequestMessage) {
       channel.sendResponse(
           new ResponseMessage(message.id, null, error, jsonRpcVersion));
-      // Since the LSP client might not show the failed requests to the user,
-      // also ensure the error is logged to the client.
-      logErrorToClient(error.message);
     } else if (message is ResponseMessage) {
       // For bad response messages where we can't respond with an error, send it as
       // show instead of log.
@@ -433,9 +436,21 @@
     ));
   }
 
+  /// Send status notification to the client. The state of analysis is given by
+  /// the [status] information.
+  void sendStatusNotification(nd.AnalysisStatus status) {
+    channel.sendNotification(new NotificationMessage(
+      CustomMethods.AnalyzerStatus,
+      new AnalyzerStatusParams(status.isAnalyzing),
+      jsonRpcVersion,
+    ));
+  }
+
   void setAnalysisRoots(List<String> includedPaths) {
+    declarationsTracker.discardContexts();
     final uniquePaths = HashSet<String>.of(includedPaths ?? const []);
     contextManager.setRoots(uniquePaths.toList(), [], {});
+    addContextsToDeclarationsTracker();
   }
 
   /**
@@ -443,7 +458,11 @@
    * absolute path.
    */
   bool shouldSendErrorsNotificationFor(String file) {
-    return contextManager.isInAnalysisRoot(file);
+    // Errors should not be reported for things that are explicitly skipped
+    // during normal analysis (for example dot folders are skipped over in
+    // _handleWatchEventImpl).
+    return contextManager.isInAnalysisRoot(file) &&
+        !contextManager.isContainedInDotFolder(file);
   }
 
   void showErrorMessageToUser(String message) {
@@ -475,7 +494,7 @@
           ..addAll(addedPaths ?? const [])
           ..removeAll(removedPaths ?? const []);
 
-    contextManager.setRoots(newPaths.toList(), [], {});
+    setAnalysisRoots(newPaths.toList());
   }
 
   void updateOverlay(String path, String contents) {
@@ -486,6 +505,8 @@
       resourceProvider.removeOverlay(path);
     }
     driverMap.values.forEach((driver) => driver.changeFile(path));
+
+    notifyDeclarationsTracker(path);
   }
 
   _updateDriversPriorityFiles() {
@@ -576,7 +597,8 @@
 
   @override
   void broadcastWatchEvent(WatchEvent event) {
-    // TODO: implement broadcastWatchEvent
+    analysisServer.notifyDeclarationsTracker(event.path);
+    // TODO: implement plugin broadcastWatchEvent
   }
 
   @override
diff --git a/pkg/analysis_server/lib/src/lsp/mapping.dart b/pkg/analysis_server/lib/src/lsp/mapping.dart
index 2f9dd65..5963258d 100644
--- a/pkg/analysis_server/lib/src/lsp/mapping.dart
+++ b/pkg/analysis_server/lib/src/lsp/mapping.dart
@@ -1,11 +1,20 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
 import 'dart:collection';
 
+import 'package:analysis_server/lsp_protocol/protocol_custom_generated.dart'
+    as lsp;
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart' as lsp;
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart'
     show ResponseError;
+import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
+import 'package:analysis_server/lsp_protocol/protocol_special.dart';
 import 'package:analysis_server/lsp_protocol/protocol_special.dart' as lsp;
 import 'package:analysis_server/lsp_protocol/protocol_special.dart'
     show ErrorOr, Either2, Either4;
+import 'package:analysis_server/protocol/protocol_generated.dart';
 import 'package:analysis_server/src/lsp/constants.dart' as lsp;
 import 'package:analysis_server/src/lsp/dartdoc.dart';
 import 'package:analysis_server/src/lsp/lsp_analysis_server.dart' as lsp;
@@ -18,6 +27,8 @@
 import 'package:analyzer/src/dart/analysis/search.dart' as server
     show DeclarationKind;
 import 'package:analyzer/src/generated/source.dart' as server;
+import 'package:analyzer/src/services/available_declarations.dart';
+import 'package:analyzer/src/services/available_declarations.dart' as dec;
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart' as server;
 
 const languageSourceName = 'dart';
@@ -38,10 +49,10 @@
 /// it's important to call this immediately after computing edits to ensure
 /// the document is not modified before the version number is read.
 lsp.WorkspaceEdit createWorkspaceEdit(
-    lsp.LspAnalysisServer server, server.SourceChange change) {
+    lsp.LspAnalysisServer server, List<server.SourceFileEdit> edits) {
   return toWorkspaceEdit(
       server.clientCapabilities?.workspace,
-      change.edits
+      edits
           .map((e) => new FileEditInformation(
               server.getVersionedDocumentIdentifier(e.file),
               server.getLineInfo(e.file),
@@ -49,6 +60,42 @@
           .toList());
 }
 
+lsp.CompletionItemKind declarationKindToCompletionItemKind(
+  HashSet<lsp.CompletionItemKind> clientSupportedCompletionKinds,
+  dec.DeclarationKind kind,
+) {
+  bool isSupported(lsp.CompletionItemKind kind) =>
+      clientSupportedCompletionKinds.contains(kind);
+
+  List<lsp.CompletionItemKind> getKindPreferences() {
+    switch (kind) {
+      case dec.DeclarationKind.CLASS:
+      case dec.DeclarationKind.CLASS_TYPE_ALIAS:
+      case dec.DeclarationKind.MIXIN:
+        return const [lsp.CompletionItemKind.Class];
+      case dec.DeclarationKind.CONSTRUCTOR:
+        return const [lsp.CompletionItemKind.Constructor];
+      case dec.DeclarationKind.ENUM:
+      case dec.DeclarationKind.ENUM_CONSTANT:
+        return const [lsp.CompletionItemKind.Enum];
+      case dec.DeclarationKind.FUNCTION:
+        return const [lsp.CompletionItemKind.Function];
+      case dec.DeclarationKind.FUNCTION_TYPE_ALIAS:
+        return const [lsp.CompletionItemKind.Class];
+      case dec.DeclarationKind.GETTER:
+        return const [lsp.CompletionItemKind.Property];
+      case dec.DeclarationKind.SETTER:
+        return const [lsp.CompletionItemKind.Property];
+      case dec.DeclarationKind.VARIABLE:
+        return const [lsp.CompletionItemKind.Variable];
+      default:
+        return const [];
+    }
+  }
+
+  return getKindPreferences().firstWhere(isSupported, orElse: () => null);
+}
+
 lsp.SymbolKind declarationKindToSymbolKind(
   HashSet<lsp.SymbolKind> clientSupportedSymbolKinds,
   server.DeclarationKind kind,
@@ -84,13 +131,76 @@
         return const [lsp.SymbolKind.Variable];
       default:
         assert(false, 'Unexpected declaration kind $kind');
-        return null;
+        return const [];
     }
   }
 
   return getKindPreferences().firstWhere(isSupported, orElse: () => null);
 }
 
+lsp.CompletionItem declarationToCompletionItem(
+  lsp.TextDocumentClientCapabilitiesCompletion completionCapabilities,
+  HashSet<lsp.CompletionItemKind> supportedCompletionItemKinds,
+  String file,
+  int offset,
+  IncludedSuggestionSet includedSuggestionSet,
+  Library library,
+  Map<String, int> tagBoosts,
+  server.LineInfo lineInfo,
+  dec.Declaration declaration,
+  int replacementOffset,
+  int replacementLength,
+) {
+  final label = declaration.name;
+
+  final useDeprecated =
+      completionCapabilities?.completionItem?.deprecatedSupport == true;
+  final formats = completionCapabilities?.completionItem?.documentationFormat;
+
+  final completionKind = declarationKindToCompletionItemKind(
+      supportedCompletionItemKinds, declaration.kind);
+
+  var itemRelevance = includedSuggestionSet.relevance;
+  if (declaration.relevanceTags != null)
+    declaration.relevanceTags
+        .forEach((t) => itemRelevance += (tagBoosts[t] ?? 0));
+
+  return new lsp.CompletionItem(
+    label,
+    completionKind,
+    getDeclarationCompletionDetail(declaration, completionKind, useDeprecated),
+    asStringOrMarkupContent(formats, cleanDartdoc(declaration.docComplete)),
+    useDeprecated ? declaration.isDeprecated : null,
+    false, // preselect
+    // Relevance is a number, highest being best. LSP does text sort so subtract
+    // from a large number so that a text sort will result in the correct order.
+    // 555 -> 999455
+    //  10 -> 999990
+    //   1 -> 999999
+    (1000000 - itemRelevance).toString(),
+    null, // filterText uses label if not set
+    null, // insertText is deprecated, but also uses label if not set
+    // We don't have completions that use snippets, so we always return PlainText.
+    lsp.InsertTextFormat.PlainText,
+    new lsp.TextEdit(
+      // TODO(dantup): If `clientSupportsSnippets == true` then we should map
+      // `selection` in to a snippet (see how Dart Code does this).
+      toRange(lineInfo, replacementOffset, replacementLength),
+      label,
+    ),
+    [], // additionalTextEdits, used for adding imports, etc.
+    [], // commitCharacters
+    null, // command
+    // data, used for completionItem/resolve.
+    new lsp.CompletionItemResolutionInfo(
+      file,
+      offset,
+      includedSuggestionSet.id,
+      includedSuggestionSet.displayUri ?? library.uri?.toString(),
+    ),
+  );
+}
+
 lsp.CompletionItemKind elementKindToCompletionItemKind(
   HashSet<lsp.CompletionItemKind> clientSupportedCompletionKinds,
   server.ElementKind kind,
@@ -131,6 +241,8 @@
         return const [lsp.CompletionItemKind.Variable];
       case server.ElementKind.METHOD:
         return const [lsp.CompletionItemKind.Method];
+      case server.ElementKind.MIXIN:
+        return const [lsp.CompletionItemKind.Class];
       case server.ElementKind.PARAMETER:
       case server.ElementKind.PREFIX:
         return const [lsp.CompletionItemKind.Variable];
@@ -147,7 +259,7 @@
       case server.ElementKind.UNIT_TEST_TEST:
         return const [lsp.CompletionItemKind.Method];
       default:
-        return null;
+        return const [];
     }
   }
 
@@ -214,7 +326,7 @@
         return const [lsp.SymbolKind.Method];
       default:
         assert(false, 'Unexpected element kind $kind');
-        return null;
+        return const [];
     }
   }
 
@@ -267,6 +379,48 @@
   }
 }
 
+String getDeclarationCompletionDetail(
+  dec.Declaration declaration,
+  lsp.CompletionItemKind completionKind,
+  bool clientSupportsDeprecated,
+) {
+  final hasParameters =
+      declaration.parameters != null && declaration.parameters.isNotEmpty;
+  final hasReturnType =
+      declaration.returnType != null && declaration.returnType.isNotEmpty;
+
+  final prefix = clientSupportsDeprecated || !declaration.isDeprecated
+      ? ''
+      : '(Deprecated) ';
+
+  if (completionKind == lsp.CompletionItemKind.Property) {
+    // Setters appear as methods with one arg but they also cause getters to not
+    // appear in the completion list, so displaying them as setters is misleading.
+    // To avoid this, always show only the return type, whether it's a getter
+    // or a setter.
+    return prefix +
+        (declaration.kind == dec.DeclarationKind.GETTER
+            ? declaration.returnType
+            // Don't assume setters always have parameters
+            // See https://github.com/dart-lang/sdk/issues/27747
+            : declaration.parameters != null &&
+                    declaration.parameters.isNotEmpty
+                // Extract the type part from '(MyType value)`
+                ? declaration.parameters
+                    .substring(1, declaration.parameters.lastIndexOf(" "))
+                : '');
+  } else if (hasParameters && hasReturnType) {
+    return '$prefix${declaration.parameters} → ${declaration.returnType}';
+  } else if (hasReturnType) {
+    return '$prefix${declaration.returnType}';
+  } else {
+    return prefix;
+  }
+}
+
+bool isDartDocument(lsp.TextDocumentIdentifier doc) =>
+    doc?.uri?.endsWith('.dart');
+
 lsp.Location navigationTargetToLocation(String targetFilePath,
     server.NavigationTarget target, server.LineInfo lineInfo) {
   if (lineInfo == null) {
@@ -367,7 +521,7 @@
       case server.CompletionSuggestionKind.PARAMETER:
         return const [lsp.CompletionItemKind.Value];
       default:
-        return null;
+        return const [];
     }
   }
 
diff --git a/pkg/analysis_server/lib/src/nullability/constraint_gatherer.dart b/pkg/analysis_server/lib/src/nullability/constraint_gatherer.dart
index c6d9e80..20532c1 100644
--- a/pkg/analysis_server/lib/src/nullability/constraint_gatherer.dart
+++ b/pkg/analysis_server/lib/src/nullability/constraint_gatherer.dart
@@ -6,10 +6,8 @@
 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_graph.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';
 import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/dart/ast/visitor.dart';
@@ -36,9 +34,6 @@
 
   final NullabilityMigrationAssumptions assumptions;
 
-  /// Constraints gathered by the visitor are stored here.
-  final Constraints _constraints;
-
   final NullabilityGraph _graph;
 
   /// The file being analyzed.
@@ -81,22 +76,16 @@
   /// or expression.
   bool _inConditionalControlFlow = false;
 
-  ConstraintGatherer(
-      TypeProvider typeProvider,
-      this._variables,
-      this._constraints,
-      this._graph,
-      this._source,
-      this._permissive,
-      this.assumptions)
-      : _notNullType =
-            DecoratedType(typeProvider.objectType, NullabilityNode.never),
+  ConstraintGatherer(TypeProvider typeProvider, this._variables, this._graph,
+      this._source, this._permissive, this.assumptions)
+      : _notNullType = DecoratedType(
+            typeProvider.objectType, NullabilityNode.never, _graph),
         _nonNullableBoolType =
-            DecoratedType(typeProvider.boolType, NullabilityNode.never),
+            DecoratedType(typeProvider.boolType, NullabilityNode.never, _graph),
         _nonNullableTypeType =
-            DecoratedType(typeProvider.typeType, NullabilityNode.never),
-        _nullType =
-            DecoratedType(typeProvider.nullType, NullabilityNode.always);
+            DecoratedType(typeProvider.typeType, NullabilityNode.never, _graph),
+        _nullType = DecoratedType(
+            typeProvider.nullType, NullabilityNode.always, _graph);
 
   /// Gets the decorated type of [element] from [_variables], performing any
   /// necessary substitutions.
@@ -132,8 +121,7 @@
       } else {
         throw element.runtimeType; // TODO(paulberry)
       }
-      return decoratedBaseType.substitute(
-          _constraints, substitution, elementType);
+      return decoratedBaseType.substitute(_graph, substitution, elementType);
     } else {
       return decoratedBaseType;
     }
@@ -146,7 +134,7 @@
       if (!_inConditionalControlFlow &&
           _conditionInfo.trueDemonstratesNonNullIntent != null) {
         _conditionInfo.trueDemonstratesNonNullIntent
-            ?.recordNonNullIntent(_constraints, _guards);
+            ?.recordNonNullIntent(_guards, _graph);
       }
     }
     node.message?.accept(this);
@@ -196,7 +184,7 @@
 
   @override
   DecoratedType visitBooleanLiteral(BooleanLiteral node) {
-    return DecoratedType(node.staticType, NullabilityNode.never);
+    return DecoratedType(node.staticType, NullabilityNode.never, _graph);
   }
 
   @override
@@ -215,8 +203,8 @@
     assert(_isSimple(elseType)); // TODO(paulberry)
     var overallType = DecoratedType(
         node.staticType,
-        NullabilityNode.forLUB(
-            node, thenType.node, elseType.node, _graph, _joinNullabilities));
+        NullabilityNode.forLUB(node, thenType.node, elseType.node, _graph),
+        _graph);
     _variables.recordDecoratedExpressionType(node, overallType);
     return overallType;
   }
@@ -234,9 +222,7 @@
         NullabilityNode.recordAssignment(
             NullabilityNode.always,
             getOrComputeElementType(node.declaredElement).node,
-            null,
             _guards,
-            _constraints,
             _graph,
             false);
       } else {
@@ -311,7 +297,7 @@
 
   @override
   DecoratedType visitIntegerLiteral(IntegerLiteral node) {
-    return DecoratedType(node.staticType, NullabilityNode.never);
+    return DecoratedType(node.staticType, NullabilityNode.never, _graph);
   }
 
   @override
@@ -359,7 +345,7 @@
     // Any parameters not supplied must be optional.
     for (var entry in calleeType.namedParameters.entries) {
       if (suppliedNamedParameters.contains(entry.key)) continue;
-      entry.value.node.recordNamedParameterNotSupplied(_constraints, _guards);
+      entry.value.node.recordNamedParameterNotSupplied(_guards, _graph);
     }
     return calleeType.returnType;
   }
@@ -412,24 +398,41 @@
 
   @override
   DecoratedType visitStringLiteral(StringLiteral node) {
-    return DecoratedType(node.staticType, NullabilityNode.never);
+    return DecoratedType(node.staticType, NullabilityNode.never, _graph);
   }
 
   @override
   DecoratedType visitThisExpression(ThisExpression node) {
-    return DecoratedType(node.staticType, NullabilityNode.never);
+    return DecoratedType(node.staticType, NullabilityNode.never, _graph);
   }
 
   @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, NullabilityNode.never);
+    return DecoratedType(node.staticType, NullabilityNode.never, _graph);
   }
 
   @override
   DecoratedType visitTypeName(TypeName typeName) {
-    return DecoratedType(typeName.type, NullabilityNode.never);
+    var typeArguments = typeName.typeArguments?.arguments;
+    var element = typeName.name.staticElement;
+    if (typeArguments != null) {
+      for (int i = 0; i < typeArguments.length; i++) {
+        DecoratedType bound;
+        if (element is TypeParameterizedElement) {
+          bound = _variables.decoratedElementType(element.typeParameters[i],
+              create: true);
+        } else {
+          throw new UnimplementedError('TODO(paulberry)');
+        }
+        _checkAssignment(
+            bound,
+            _variables.decoratedTypeAnnotation(_source, typeArguments[i]),
+            null);
+      }
+    }
+    return DecoratedType(typeName.type, NullabilityNode.never, _graph);
   }
 
   /// Creates the necessary constraint(s) for an assignment from [sourceType] to
@@ -438,9 +441,7 @@
   /// where a nullable source is assigned to a non-nullable destination.
   void _checkAssignment(DecoratedType destinationType, DecoratedType sourceType,
       Expression expression) {
-    CheckExpression checkNotNull;
     if (expression != null) {
-      checkNotNull = CheckExpression(expression);
       _variables.recordExpressionChecks(
           _source,
           expression,
@@ -448,7 +449,7 @@
               expression.end, sourceType.node, destinationType.node, _guards));
     }
     NullabilityNode.recordAssignment(sourceType.node, destinationType.node,
-        checkNotNull, _guards, _constraints, _graph, _inConditionalControlFlow);
+        _guards, _graph, _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.
@@ -508,23 +509,6 @@
     if ((type.type as InterfaceType).typeParameters.isNotEmpty) return false;
     return true;
   }
-
-  /// Creates a constraint variable (if necessary) representing the nullability
-  /// of [node], which is the disjunction of the nullabilities [a] and [b].
-  ConstraintVariable _joinNullabilities(
-      Expression node, ConstraintVariable a, ConstraintVariable b) {
-    if (a == null) return b;
-    if (b == null) return a;
-    if (identical(a, ConstraintVariable.always) ||
-        identical(b, ConstraintVariable.always)) {
-      return ConstraintVariable.always;
-    }
-    var result = TypeIsNullable(node.offset);
-    _constraints.record([a], result);
-    _constraints.record([b], result);
-    _constraints.record([result], ConstraintVariable.or(_constraints, a, b));
-    return result;
-  }
 }
 
 /// Information about a binary expression whose boolean value could possibly
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 adbae5e..fbabd5a 100644
--- a/pkg/analysis_server/lib/src/nullability/constraint_variable_gatherer.dart
+++ b/pkg/analysis_server/lib/src/nullability/constraint_variable_gatherer.dart
@@ -12,6 +12,7 @@
 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/generated/resolver.dart';
 import 'package:analyzer/src/generated/source.dart';
 
 /// Visitor that gathers constraint variables for nullability migration from
@@ -40,18 +41,25 @@
 
   final NullabilityMigrationAssumptions assumptions;
 
-  ConstraintVariableGatherer(
-      this._variables, this._source, this._permissive, this.assumptions);
+  final NullabilityGraph _graph;
+
+  final TypeProvider _typeProvider;
+
+  ConstraintVariableGatherer(this._variables, this._source, this._permissive,
+      this.assumptions, this._graph, this._typeProvider);
 
   /// Creates and stores a [DecoratedType] object corresponding to the given
   /// [type] AST, and returns it.
-  DecoratedType decorateType(TypeAnnotation type) {
+  DecoratedType decorateType(TypeAnnotation type, AstNode enclosingNode) {
     return type == null
         // 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, NullabilityNode.forInferredDynamicType())
+            DynamicTypeImpl.instance,
+            NullabilityNode.forInferredDynamicType(
+                _graph, enclosingNode.offset),
+            _graph)
         : type.accept(this);
   }
 
@@ -81,14 +89,14 @@
   @override
   DecoratedType visitFunctionDeclaration(FunctionDeclaration node) {
     _handleExecutableDeclaration(node.declaredElement, node.returnType,
-        node.functionExpression.parameters);
+        node.functionExpression.parameters, node);
     return null;
   }
 
   @override
   DecoratedType visitMethodDeclaration(MethodDeclaration node) {
     _handleExecutableDeclaration(
-        node.declaredElement, node.returnType, node.parameters);
+        node.declaredElement, node.returnType, node.parameters, node);
     return null;
   }
 
@@ -107,9 +115,8 @@
 
   @override
   DecoratedType visitSimpleFormalParameter(SimpleFormalParameter node) {
-    var type = decorateType(node.type);
+    var type = decorateType(node.type, node);
     var declaredElement = node.declaredElement;
-    type.node.trackNonNullIntent(node.offset);
     _variables.recordDecoratedElementType(declaredElement, type);
     if (declaredElement.isNamed) {
       _currentFunctionType.namedParameters[declaredElement.name] = type;
@@ -125,8 +132,8 @@
     assert(node is NamedType); // TODO(paulberry)
     var type = node.type;
     if (type.isVoid) {
-      return DecoratedType(
-          type, NullabilityNode.forTypeAnnotation(node.end, always: true));
+      return DecoratedType(type,
+          NullabilityNode.forTypeAnnotation(node.end, always: true), _graph);
     }
     assert(
         type is InterfaceType || type is TypeParameterType); // TODO(paulberry)
@@ -145,6 +152,7 @@
         NullabilityNode.forTypeAnnotation(node.end,
             always: node.question != null),
         node.end,
+        _graph,
         typeArguments: typeArguments);
     _variables.recordDecoratedTypeAnnotation(_source, node, decoratedType);
     return decoratedType;
@@ -153,15 +161,30 @@
   @override
   DecoratedType visitTypeName(TypeName node) => visitTypeAnnotation(node);
 
+  @override
+  DecoratedType visitTypeParameter(TypeParameter node) {
+    var element = node.declaredElement;
+    var decoratedBound = node.bound?.accept(this) ??
+        DecoratedType(
+            element.bound ?? _typeProvider.objectType,
+            NullabilityNode.forInferredDynamicType(_graph, node.offset),
+            _graph);
+    _variables.recordDecoratedElementType(element, decoratedBound);
+    return null;
+  }
+
   /// Common handling of function and method declarations.
-  void _handleExecutableDeclaration(ExecutableElement declaredElement,
-      TypeAnnotation returnType, FormalParameterList parameters) {
-    var decoratedReturnType = decorateType(returnType);
+  void _handleExecutableDeclaration(
+      ExecutableElement declaredElement,
+      TypeAnnotation returnType,
+      FormalParameterList parameters,
+      AstNode enclosingNode) {
+    var decoratedReturnType = decorateType(returnType, enclosingNode);
     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, NullabilityNode.never,
+        declaredElement.type, NullabilityNode.never, _graph,
         returnType: decoratedReturnType,
         positionalParameters: [],
         namedParameters: {});
@@ -211,6 +234,10 @@
   /// element, one is synthesized using [DecoratedType.forElement].
   DecoratedType decoratedElementType(Element element, {bool create: false});
 
+  /// Gets the [DecoratedType] associated with the given [typeAnnotation].
+  DecoratedType decoratedTypeAnnotation(
+      Source source, TypeAnnotation typeAnnotation);
+
   /// Records conditional discard information for the given AST node (which is
   /// an `if` statement or a conditional (`?:`) expression).
   void recordConditionalDiscard(
diff --git a/pkg/analysis_server/lib/src/nullability/decorated_type.dart b/pkg/analysis_server/lib/src/nullability/decorated_type.dart
index c6b3256..81abe99 100644
--- a/pkg/analysis_server/lib/src/nullability/decorated_type.dart
+++ b/pkg/analysis_server/lib/src/nullability/decorated_type.dart
@@ -4,7 +4,6 @@
 
 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';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/type.dart';
@@ -36,25 +35,29 @@
   /// TODO(paulberry): how should we handle generic typedefs?
   final List<DecoratedType> typeArguments;
 
-  DecoratedType(this.type, this.node,
+  DecoratedType(this.type, this.node, NullabilityGraph graph,
       {this.returnType,
       this.positionalParameters = const [],
       this.namedParameters = 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 || node.isAlwaysNullable);
+    // the type is `dynamic`, verify that the node is directly downstream from
+    // Nullability.always.
+    assert(!type.isDynamic ||
+        graph
+            .getUnconditionalUpstreamNodes(node)
+            .contains(NullabilityNode.always));
   }
 
   /// Creates a [DecoratedType] corresponding to the given [element], which is
   /// presumed to have come from code that is already migrated.
-  factory DecoratedType.forElement(Element element) {
+  factory DecoratedType.forElement(Element element, NullabilityGraph graph) {
     DecoratedType decorate(DartType type) {
       assert((type as TypeImpl).nullabilitySuffix ==
           NullabilitySuffix.star); // TODO(paulberry)
       if (type is FunctionType) {
-        var decoratedType = DecoratedType(type, NullabilityNode.never,
+        var decoratedType = DecoratedType(type, NullabilityNode.never, graph,
             returnType: decorate(type.returnType), positionalParameters: []);
         for (var parameter in type.parameters) {
           assert(parameter.isPositional); // TODO(paulberry)
@@ -63,7 +66,7 @@
         return decoratedType;
       } else if (type is InterfaceType) {
         assert(type.typeParameters.isEmpty); // TODO(paulberry)
-        return DecoratedType(type, NullabilityNode.never);
+        return DecoratedType(type, NullabilityNode.never, graph);
       } else {
         throw type.runtimeType; // TODO(paulberry)
       }
@@ -83,11 +86,11 @@
   /// [undecoratedResult] is the result of the substitution, as determined by
   /// the normal type system.
   DecoratedType substitute(
-      Constraints constraints,
+      NullabilityGraph graph,
       Map<TypeParameterElement, DecoratedType> substitution,
       DartType undecoratedResult) {
     if (substitution.isEmpty) return this;
-    return _substitute(constraints, substitution, undecoratedResult);
+    return _substitute(graph, substitution, undecoratedResult);
   }
 
   @override
@@ -118,7 +121,7 @@
 
   /// Internal implementation of [_substitute], used as a recursion target.
   DecoratedType _substitute(
-      Constraints constraints,
+      NullabilityGraph graph,
       Map<TypeParameterElement, DecoratedType> substitution,
       DartType undecoratedResult) {
     var type = this.type;
@@ -133,16 +136,16 @@
             : undecoratedResult
                 .optionalParameterTypes[i - numRequiredParameters];
         newPositionalParameters.add(positionalParameters[i]
-            ._substitute(constraints, substitution, undecoratedParameterType));
+            ._substitute(graph, substitution, undecoratedParameterType));
       }
-      return DecoratedType(undecoratedResult, node,
+      return DecoratedType(undecoratedResult, node, graph,
           returnType: returnType._substitute(
-              constraints, substitution, undecoratedResult.returnType),
+              graph, substitution, undecoratedResult.returnType),
           positionalParameters: newPositionalParameters);
     } else if (type is TypeParameterType) {
       var inner = substitution[type.element];
       return DecoratedType(undecoratedResult,
-          NullabilityNode.forSubstitution(constraints, inner?.node, node));
+          NullabilityNode.forSubstitution(inner?.node, node), graph);
     } else if (type is VoidType) {
       return this;
     }
@@ -159,37 +162,15 @@
     implements PotentialModification {
   final int _offset;
 
-  DecoratedTypeAnnotation(
-      DartType type, NullabilityNode nullabilityNode, this._offset,
+  DecoratedTypeAnnotation(DartType type, NullabilityNode nullabilityNode,
+      this._offset, NullabilityGraph graph,
       {List<DecoratedType> typeArguments = const []})
-      : super(type, nullabilityNode, typeArguments: typeArguments);
+      : super(type, nullabilityNode, graph, typeArguments: typeArguments);
 
   @override
-  bool get isEmpty => node.isAlwaysNullable || !node.isNullable;
+  bool get isEmpty => !node.isNullable;
 
   @override
   Iterable<SourceEdit> get modifications =>
       isEmpty ? [] : [SourceEdit(_offset, 0, '?')];
 }
-
-/// Type of a [ConstraintVariable] representing the fact that a type is intended
-/// to be non-null.
-class NonNullIntent extends ConstraintVariable {
-  final int _offset;
-
-  NonNullIntent(this._offset);
-
-  @override
-  toString() => 'nonNullIntent($_offset)';
-}
-
-/// Type of a [ConstraintVariable] representing the fact that a type is
-/// nullable.
-class TypeIsNullable extends ConstraintVariable {
-  final int _offset;
-
-  TypeIsNullable(this._offset);
-
-  @override
-  toString() => 'nullable($_offset)';
-}
diff --git a/pkg/analysis_server/lib/src/nullability/nullability_graph.dart b/pkg/analysis_server/lib/src/nullability/nullability_graph.dart
deleted file mode 100644
index bcc2300..0000000
--- a/pkg/analysis_server/lib/src/nullability/nullability_graph.dart
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:analysis_server/src/nullability/nullability_node.dart';
-
-/// Data structure to keep track of the relationship between [NullabilityNode]
-/// objects.
-class NullabilityGraph {
-  /// Map from a nullability node to those nodes that are "downstream" from it
-  /// (meaning that if a key node is nullable, then all the nodes in the
-  /// corresponding value will either have to be nullable, or null checks will
-  /// have to be added).
-  final _downstream = Map<NullabilityNode, List<NullabilityNode>>.identity();
-
-  /// Map from a nullability node to those nodes that are "upstream" from it
-  /// (meaning that if a node in the value is nullable, then the corresponding
-  /// key node will have to be nullable, or null checks will have to be added).
-  final _upstream = Map<NullabilityNode, List<NullabilityNode>>.identity();
-
-  /// Records that [sourceNode] is immediately upstream from [destinationNode].
-  void connect(NullabilityNode sourceNode, NullabilityNode destinationNode) {
-    (_downstream[sourceNode] ??= []).add(destinationNode);
-    (_upstream[destinationNode] ??= []).add(sourceNode);
-  }
-
-  /// Iterates through all nodes that are "downstream" of [node] (i.e. if
-  /// [node] is nullable, then all the iterated nodes will either have to be
-  /// nullable, or null checks will have to be added).
-  ///
-  /// There is no guarantee of uniqueness of the iterated nodes.
-  Iterable<NullabilityNode> getDownstreamNodes(NullabilityNode node) =>
-      _downstream[node] ?? const [];
-
-  /// Iterates through all nodes that are "upstream" of [node] (i.e. if
-  /// any of the iterated nodes are nullable, then [node] will either have to be
-  /// nullable, or null checks will have to be added).
-  //  ///
-  //  /// There is no guarantee of uniqueness of the iterated nodes.
-  Iterable<NullabilityNode> getUpstreamNodes(NullabilityNode node) =>
-      _upstream[node] ?? const [];
-}
diff --git a/pkg/analysis_server/lib/src/nullability/nullability_node.dart b/pkg/analysis_server/lib/src/nullability/nullability_node.dart
index e871c28..ebd221c 100644
--- a/pkg/analysis_server/lib/src/nullability/nullability_node.dart
+++ b/pkg/analysis_server/lib/src/nullability/nullability_node.dart
@@ -2,45 +2,243 @@
 // for details. All 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/nullability_graph.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';
 
+/// Data structure to keep track of the relationship between [NullabilityNode]
+/// objects.
+class NullabilityGraph {
+  /// Set containing all [NullabilityNode]s that have been passed as the
+  /// `sourceNode` argument to [connect].
+  final _allSourceNodes = Set<NullabilityNode>.identity();
+
+  /// List of [_NullabilityEdge] objects that are downstream from
+  /// [NullabilityNode.always].  (They can't be stored in
+  /// [NullabilityNode.always] directly because it is immutable).
+  final _downstreamFromAlways = <_NullabilityEdge>[];
+
+  /// List of [NullabilityNodes] that are "upstream" from
+  /// [NullabilityNode.never] due to unconditional control flow.  (They can't be
+  /// stored in [NullabilityNode.never] directly because it is immutable).
+  final _unconditionalUpstreamFromNever = <NullabilityNode>[];
+
+  /// Records that [sourceNode] is immediately upstream from [destinationNode].
+  void connect(NullabilityNode sourceNode, NullabilityNode destinationNode,
+      {bool unconditional: false, List<NullabilityNode> guards: const []}) {
+    var sources = [sourceNode]..addAll(guards);
+    var edge = _NullabilityEdge(destinationNode, sources);
+    for (var source in sources) {
+      _allSourceNodes.add(source);
+      if (source is NullabilityNodeMutable) {
+        source._downstreamEdges.add(edge);
+      } else if (source == NullabilityNode.always) {
+        _downstreamFromAlways.add(edge);
+      } else {
+        // We don't need to track nodes that are downstream from `never` because
+        // `never` will never be nullable.
+        assert(source == NullabilityNode.never);
+      }
+    }
+    if (unconditional) {
+      if (destinationNode is NullabilityNodeMutable) {
+        destinationNode._unconditionalUpstreamNodes.add(sourceNode);
+      } else if (destinationNode == NullabilityNode.never) {
+        _unconditionalUpstreamFromNever.add(sourceNode);
+      } else {
+        // We don't need to track nodes that are upstream from `always` because
+        // `always` will never have non-null intent.
+        assert(destinationNode == NullabilityNode.always);
+      }
+    }
+  }
+
+  void debugDump() {
+    for (var source in _allSourceNodes) {
+      var edges = _getDownstreamEdges(source);
+      var destinations =
+          edges.where((edge) => edge.primarySource == source).map((edge) {
+        var suffixes = <Object>[];
+        if (getUnconditionalUpstreamNodes(edge.destinationNode)
+            .contains(source)) {
+          suffixes.add('unconditional');
+        }
+        suffixes.addAll(edge.guards);
+        var suffix = suffixes.isNotEmpty ? ' (${suffixes.join(', ')})' : '';
+        return '${edge.destinationNode}$suffix';
+      });
+      var suffixes = <String>[];
+      if (source.isNullable) {
+        suffixes.add('nullable');
+      }
+      if (source.hasNonNullIntent) {
+        suffixes.add('non-null intent');
+      }
+      var suffix = suffixes.isNotEmpty ? ' (${suffixes.join(', ')})' : '';
+      print('$source$suffix -> ${destinations.join(', ')}');
+    }
+  }
+
+  /// Iterates through all nodes that are "downstream" of [node] (i.e. if
+  /// [node] is nullable, then all the iterated nodes will either have to be
+  /// nullable, or null checks will have to be added).
+  ///
+  /// There is no guarantee of uniqueness of the iterated nodes.
+  Iterable<NullabilityNode> getDownstreamNodes(NullabilityNode node) =>
+      _getDownstreamEdges(node)
+          .where((edge) => edge.primarySource == node)
+          .map((edge) => edge.destinationNode);
+
+  /// Iterates through all nodes that are "upstream" of [node] due to
+  /// unconditional control flow.
+  ///
+  /// There is no guarantee of uniqueness of the iterated nodes.
+  Iterable<NullabilityNode> getUnconditionalUpstreamNodes(
+      NullabilityNode node) {
+    if (node is NullabilityNodeMutable) {
+      return node._unconditionalUpstreamNodes;
+    } else if (node == NullabilityNode.never) {
+      return _unconditionalUpstreamFromNever;
+    } else {
+      // No nodes are upstream from `always`.
+      assert(node == NullabilityNode.always);
+      return const [];
+    }
+  }
+
+  /// Iterates through all nodes that are "upstream" of [node] (i.e. if
+  /// any of the iterated nodes are nullable, then [node] will either have to be
+  /// nullable, or null checks will have to be added).
+  ///
+  /// There is no guarantee of uniqueness of the iterated nodes.
+  ///
+  /// This method is inefficent since it has to search the entire graph, so it
+  /// is for testing only.
+  @visibleForTesting
+  Iterable<NullabilityNode> getUpstreamNodesForTesting(
+      NullabilityNode node) sync* {
+    for (var source in _allSourceNodes) {
+      for (var edge in _getDownstreamEdges(source)) {
+        if (edge.destinationNode == node) {
+          yield source;
+        }
+      }
+    }
+  }
+
+  /// Determines the nullability of each node in the graph by propagating
+  /// nullability information from one node to another.
+  void propagate() {
+    _propagateUpstream();
+    _propagateDownstream();
+  }
+
+  Iterable<_NullabilityEdge> _getDownstreamEdges(NullabilityNode node) {
+    if (node is NullabilityNodeMutable) {
+      return node._downstreamEdges;
+    } else if (node == NullabilityNode.always) {
+      return _downstreamFromAlways;
+    } else {
+      // No nodes are downstream from `never`.
+      assert(node == NullabilityNode.never);
+      return const [];
+    }
+  }
+
+  /// Propagates nullability downstream.
+  void _propagateDownstream() {
+    var pendingEdges = <_NullabilityEdge>[]..addAll(_downstreamFromAlways);
+    var pendingSubstitutions = <NullabilityNodeForSubstitution>[];
+    while (true) {
+      nextEdge:
+      while (pendingEdges.isNotEmpty) {
+        var edge = pendingEdges.removeLast();
+        var node = edge.destinationNode;
+        if (node.hasNonNullIntent) {
+          // Non-null intent nodes are never made nullable; a null check will need
+          // to be added instead.
+          continue;
+        }
+        for (var source in edge.sources) {
+          if (!source.isNullable) {
+            // Note all sources are nullable, so this edge doesn't apply yet.
+            continue nextEdge;
+          }
+        }
+        if (node is NullabilityNodeMutable && node._becomeNullable()) {
+          // Was not previously nullable, so we need to propagate.
+          pendingEdges.addAll(node._downstreamEdges);
+          if (node is NullabilityNodeForSubstitution) {
+            pendingSubstitutions.add(node);
+          }
+        }
+      }
+      if (pendingSubstitutions.isEmpty) break;
+      var node = pendingSubstitutions.removeLast();
+      if (node.innerNode.isNullable || node.outerNode.isNullable) {
+        // No further propagation is needed, since some other connection already
+        // propagated nullability to either the inner or outer node.
+        continue;
+      }
+      // Heuristically choose to propagate to the inner node since this seems
+      // to lead to better quality migrations.
+      pendingEdges.add(_NullabilityEdge(node.innerNode, const []));
+    }
+  }
+
+  /// Propagates non-null intent upstream along unconditional control flow
+  /// lines.
+  void _propagateUpstream() {
+    var pendingNodes = <NullabilityNode>[]
+      ..addAll(_unconditionalUpstreamFromNever);
+    while (pendingNodes.isNotEmpty) {
+      var node = pendingNodes.removeLast();
+      if (node == NullabilityNode.always) {
+        // The "always" node cannot have non-null intent.
+        continue;
+      }
+      if (node is NullabilityNodeMutable && node._setNonNullIntent()) {
+        // Was not previously in the set of non-null intent nodes, so we need to
+        // propagate.
+        pendingNodes.addAll(node._unconditionalUpstreamNodes);
+      }
+    }
+  }
+}
+
 /// 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 {
+abstract 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);
+  static final NullabilityNode always =
+      _NullabilityNodeImmutable('always', true);
 
   /// [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);
+  static final NullabilityNode never =
+      _NullabilityNodeImmutable('never', false);
 
-  /// [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;
+  static final _debugNamesInUse = Set<String>();
 
   bool _isPossiblyOptional = false;
 
+  String _debugName;
+
   /// 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);
+  factory NullabilityNode.forInferredDynamicType(
+      NullabilityGraph graph, int offset) {
+    var node = _NullabilityNodeSimple('inferredDynamic($offset)');
+    graph.connect(NullabilityNode.always, node, unconditional: true);
+    return node;
+  }
 
   /// Creates a [NullabilityNode] representing the nullability of an
   /// expression which is nullable iff both [a] and [b] are nullable.
@@ -53,10 +251,7 @@
       Expression conditionalExpression,
       NullabilityNode a,
       NullabilityNode b,
-      NullabilityGraph graph,
-      ConstraintVariable Function(
-              Expression, ConstraintVariable, ConstraintVariable)
-          joinNullabilities) = NullabilityNodeForLUB._;
+      NullabilityGraph graph) = NullabilityNodeForLUB._;
 
   /// Creates a [NullabilityNode] representing the nullability of a type
   /// substitution where [outerNode] is the nullability node for the type
@@ -70,65 +265,65 @@
   /// TODO(paulberry): this should become unnecessary once constraint solving is
   /// performed directly using [NullabilityNode] objects.
   factory NullabilityNode.forSubstitution(
-      Constraints constraints,
-      NullabilityNode innerNode,
-      NullabilityNode outerNode) = NullabilityNodeForSubstitution._;
+          NullabilityNode innerNode, NullabilityNode outerNode) =
+      NullabilityNodeForSubstitution._;
 
   /// 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));
+  factory NullabilityNode.forTypeAnnotation(int endOffset,
+          {@required bool always}) =>
+      _NullabilityNodeSimple('type($endOffset)');
 
-  NullabilityNode._(this.nullable);
+  NullabilityNode._();
 
   /// 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)';
+  String get debugSuffix =>
+      this == always ? '?' : this == never ? '' : '?($this)';
 
-  /// Indicates whether this node is always nullable, by construction.
-  bool get isAlwaysNullable => identical(nullable, ConstraintVariable.always);
+  bool get hasNonNullIntent;
 
-  /// Indicates whether this node is never nullable, by construction.
-  bool get isNeverNullable => nullable == null;
-
-  /// 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 == null ? false : nullable.value;
+  /// After nullability propagation, this getter can be used to query whether
+  /// the type associated with this node should be considered nullable.
+  bool get isNullable;
 
   /// 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;
+  String get _debugPrefix;
 
   /// 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) {
+      List<NullabilityNode> guards, NullabilityGraph graph) {
     if (isPossiblyOptional) {
-      _recordConstraints(constraints, guards, const [], nullable);
+      graph.connect(NullabilityNode.always, this, guards: guards);
     }
   }
 
   void recordNonNullIntent(
-      Constraints constraints, List<NullabilityNode> guards) {
-    _recordConstraints(constraints, guards, const [], nonNullIntent);
+      List<NullabilityNode> guards, NullabilityGraph graph) {
+    graph.connect(this, NullabilityNode.never, unconditional: true);
   }
 
-  /// 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);
+  String toString() {
+    if (_debugName == null) {
+      var prefix = _debugPrefix;
+      if (_debugNamesInUse.add(prefix)) {
+        _debugName = prefix;
+      } else {
+        for (int i = 0;; i++) {
+          var name = '${prefix}_$i';
+          if (_debugNamesInUse.add(name)) {
+            _debugName = name;
+            break;
+          }
+        }
+      }
+    }
+    return _debugName;
   }
 
   /// Tracks the possibility that this node is associated with a named parameter
@@ -151,84 +346,35 @@
   static void recordAssignment(
       NullabilityNode sourceNode,
       NullabilityNode destinationNode,
-      CheckExpression checkNotNull,
       List<NullabilityNode> guards,
-      Constraints constraints,
       NullabilityGraph graph,
       bool inConditionalControlFlow) {
-    var additionalConditions = <ConstraintVariable>[];
-    graph.connect(sourceNode, destinationNode);
-    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);
+    graph.connect(sourceNode, destinationNode,
+        guards: guards, unconditional: !inConditionalControlFlow);
   }
 }
 
 /// Derived class for nullability nodes that arise from the least-upper-bound
 /// implied by a conditional expression.
-class NullabilityNodeForLUB extends NullabilityNode {
+class NullabilityNodeForLUB extends NullabilityNodeMutable {
   final NullabilityNode left;
 
   final NullabilityNode right;
 
   NullabilityNodeForLUB._(
-      Expression expression,
-      this.left,
-      this.right,
-      NullabilityGraph graph,
-      ConstraintVariable Function(
-              ConditionalExpression, ConstraintVariable, ConstraintVariable)
-          joinNullabilities)
-      : super._(joinNullabilities(expression, left.nullable, right.nullable)) {
+      Expression expression, this.left, this.right, NullabilityGraph graph)
+      : super._() {
     graph.connect(left, this);
     graph.connect(right, this);
   }
+
+  @override
+  String get _debugPrefix => 'LUB($left, $right)';
 }
 
 /// Derived class for nullability nodes that arise from type variable
 /// substitution.
-class NullabilityNodeForSubstitution extends NullabilityNode {
+class NullabilityNodeForSubstitution extends NullabilityNodeMutable {
   /// Nullability node representing the inner type of the substitution.
   ///
   /// For example, if this NullabilityNode arose from substituting `int*` for
@@ -243,8 +389,99 @@
   /// `*` in `T*`.
   final NullabilityNode outerNode;
 
-  NullabilityNodeForSubstitution._(
-      Constraints constraints, this.innerNode, this.outerNode)
-      : super._(ConstraintVariable.or(
-            constraints, innerNode?.nullable, outerNode.nullable));
+  NullabilityNodeForSubstitution._(this.innerNode, this.outerNode) : super._();
+
+  @override
+  String get _debugPrefix => 'Substituted($innerNode, $outerNode)';
+}
+
+/// Base class for nullability nodes whose state can be mutated safely.
+///
+/// Nearly all nullability nodes derive from this class; the only exceptions are
+/// the fixed nodes [NullabilityNode.always] and [NullabilityNode.never].
+abstract class NullabilityNodeMutable extends NullabilityNode {
+  bool _isNullable = false;
+
+  bool _hasNonNullIntent = false;
+
+  /// List of [_NullabilityEdge] objects describing this node's relationship to
+  /// other nodes that are "downstream" from it (meaning that if a key node is
+  /// nullable, then all the nodes in the corresponding value will either have
+  /// to be nullable, or null checks will have to be added).
+  final _downstreamEdges = <_NullabilityEdge>[];
+
+  /// List of nodes that are "upstream" from this node via unconditional control
+  /// flow (meaning that if a node in the list is nullable, then there exists
+  /// code that is unguarded by an "if" statement that indicates that this node
+  /// will have to be nullable, or null checks will have to be added).
+  final _unconditionalUpstreamNodes = <NullabilityNode>[];
+
+  NullabilityNodeMutable._() : super._();
+
+  @override
+  bool get hasNonNullIntent => _hasNonNullIntent;
+
+  @override
+  bool get isNullable => _isNullable;
+
+  /// During nullability propagation, this method marks the type as nullable, or
+  /// does nothing if the type was already nullable.
+  ///
+  /// Return value indicates whether a change was made.
+  bool _becomeNullable() {
+    if (_isNullable) return false;
+    _isNullable = true;
+    return true;
+  }
+
+  /// During nullability propagation, this method marks the type as having
+  /// non-null intent, or does nothing if the type was already marked as having
+  /// non-null intent.
+  ///
+  /// Return value indicates whether a change was made.
+  bool _setNonNullIntent() {
+    if (_hasNonNullIntent) return false;
+    _hasNonNullIntent = true;
+    return true;
+  }
+}
+
+/// Data structure to keep track of the relationship from one [NullabilityNode]
+/// object to another [NullabilityNode] that is "downstream" from it (meaning
+/// that if the former node is nullable, then the latter node will either have
+/// to be nullable, or null checks will have to be added).
+class _NullabilityEdge {
+  /// The node that is downstream.
+  final NullabilityNode destinationNode;
+
+  /// A set of source nodes.  By convention, the first node is the primary
+  /// source and the other nodes are "guards".  The destination node will only
+  /// need to be made nullable if all the source nodes are nullable.
+  final List<NullabilityNode> sources;
+
+  _NullabilityEdge(this.destinationNode, this.sources);
+
+  Iterable<NullabilityNode> get guards => sources.skip(1);
+
+  NullabilityNode get primarySource => sources.first;
+}
+
+class _NullabilityNodeImmutable extends NullabilityNode {
+  @override
+  final String _debugPrefix;
+
+  @override
+  final bool isNullable;
+
+  _NullabilityNodeImmutable(this._debugPrefix, this.isNullable) : super._();
+
+  @override
+  bool get hasNonNullIntent => !isNullable;
+}
+
+class _NullabilityNodeSimple extends NullabilityNodeMutable {
+  @override
+  final String _debugPrefix;
+
+  _NullabilityNodeSimple(this._debugPrefix) : super._();
 }
diff --git a/pkg/analysis_server/lib/src/nullability/provisional_api.dart b/pkg/analysis_server/lib/src/nullability/provisional_api.dart
index 99080c9..36b741b 100644
--- a/pkg/analysis_server/lib/src/nullability/provisional_api.dart
+++ b/pkg/analysis_server/lib/src/nullability/provisional_api.dart
@@ -94,7 +94,7 @@
   }
 
   void prepareInput(ResolvedUnitResult result) {
-    _analyzerMigration.prepareInput(result.unit);
+    _analyzerMigration.prepareInput(result.unit, result.typeProvider);
   }
 
   void processInput(ResolvedUnitResult result) {
diff --git a/pkg/analysis_server/lib/src/nullability/transitional_api.dart b/pkg/analysis_server/lib/src/nullability/transitional_api.dart
index ac1d8df..f49c106 100644
--- a/pkg/analysis_server/lib/src/nullability/transitional_api.dart
+++ b/pkg/analysis_server/lib/src/nullability/transitional_api.dart
@@ -7,25 +7,13 @@
 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_graph.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';
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart' show SourceEdit;
 
-/// Type of a [ConstraintVariable] representing the addition of a null check.
-class CheckExpression extends ConstraintVariable {
-  final int offset;
-
-  CheckExpression(Expression expression) : offset = expression.end;
-
-  @override
-  toString() => 'checkNotNull($offset)';
-}
-
 /// Records information about how a conditional expression or statement might
 /// need to be modified.
 class ConditionalModification extends PotentialModification {
@@ -146,11 +134,9 @@
 
   final NullabilityMigrationAssumptions assumptions;
 
-  final _variables = Variables();
+  final Variables _variables;
 
-  final _constraints = Solver();
-
-  final _graph = NullabilityGraph();
+  final NullabilityGraph _graph;
 
   /// Prepares to perform nullability migration.
   ///
@@ -160,22 +146,31 @@
   /// is fully implemented.
   NullabilityMigration(
       {bool permissive: false,
-      this.assumptions: const NullabilityMigrationAssumptions()})
-      : _permissive = permissive;
+      NullabilityMigrationAssumptions assumptions:
+          const NullabilityMigrationAssumptions()})
+      : this._(permissive, assumptions, NullabilityGraph());
+
+  NullabilityMigration._(this._permissive, this.assumptions, this._graph)
+      : _variables = Variables(_graph);
 
   Map<Source, List<PotentialModification>> finish() {
-    _constraints.applyHeuristics();
+    _graph.propagate();
     return _variables.getPotentialModifications();
   }
 
-  void prepareInput(CompilationUnit unit) {
+  void prepareInput(CompilationUnit unit, TypeProvider typeProvider) {
     unit.accept(ConstraintVariableGatherer(
-        _variables, unit.declaredElement.source, _permissive, assumptions));
+        _variables,
+        unit.declaredElement.source,
+        _permissive,
+        assumptions,
+        _graph,
+        typeProvider));
   }
 
   void processInput(CompilationUnit unit, TypeProvider typeProvider) {
-    unit.accept(ConstraintGatherer(typeProvider, _variables, _constraints,
-        _graph, unit.declaredElement.source, _permissive, assumptions));
+    unit.accept(ConstraintGatherer(typeProvider, _variables, _graph,
+        unit.declaredElement.source, _permissive, assumptions));
   }
 }
 
@@ -267,14 +262,28 @@
 class Variables implements VariableRecorder, VariableRepository {
   final _decoratedElementTypes = <Element, DecoratedType>{};
 
+  final _decoratedTypeAnnotations =
+      <Source, Map<int, DecoratedTypeAnnotation>>{};
+
   final _potentialModifications = <Source, List<PotentialModification>>{};
 
+  final NullabilityGraph _graph;
+
+  Variables(this._graph);
+
   @override
   DecoratedType decoratedElementType(Element element, {bool create: false}) =>
       _decoratedElementTypes[element] ??= create
-          ? DecoratedType.forElement(element)
+          ? DecoratedType.forElement(element, _graph)
           : throw StateError('No element found');
 
+  @override
+  DecoratedType decoratedTypeAnnotation(
+      Source source, TypeAnnotation typeAnnotation) {
+    return _decoratedTypeAnnotations[source]
+        [_uniqueOffsetForTypeAnnotation(typeAnnotation)];
+  }
+
   Map<Source, List<PotentialModification>> getPotentialModifications() =>
       _potentialModifications;
 
@@ -294,6 +303,8 @@
   void recordDecoratedTypeAnnotation(
       Source source, TypeAnnotation node, DecoratedTypeAnnotation type) {
     _addPotentialModification(source, type);
+    (_decoratedTypeAnnotations[source] ??=
+        {})[_uniqueOffsetForTypeAnnotation(node)] = type;
   }
 
   @override
@@ -360,6 +371,11 @@
       Source source, PotentialModification potentialModification) {
     (_potentialModifications[source] ??= []).add(potentialModification);
   }
+
+  int _uniqueOffsetForTypeAnnotation(TypeAnnotation typeAnnotation) =>
+      typeAnnotation is GenericFunctionType
+          ? typeAnnotation.functionKeyword.offset
+          : typeAnnotation.offset;
 }
 
 /// Helper object used by [ConditionalModification] to keep track of AST nodes
diff --git a/pkg/analysis_server/lib/src/nullability/unit_propagation.dart b/pkg/analysis_server/lib/src/nullability/unit_propagation.dart
deleted file mode 100644
index b587e33..0000000
--- a/pkg/analysis_server/lib/src/nullability/unit_propagation.dart
+++ /dev/null
@@ -1,187 +0,0 @@
-// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/// Repository of constraints corresponding to the code being migrated.
-///
-/// This data structure carries information from the second pass of migration
-/// ([ConstraintGatherer]) to the third (which creates individual code
-/// modifications from each constraint).
-abstract class Constraints {
-  /// Records a new constraint equation.
-  void record(
-      Iterable<ConstraintVariable> conditions, ConstraintVariable consequence);
-}
-
-/// Representation of a single boolean variable in the constraint solver.
-class ConstraintVariable {
-  /// A special boolean variable whose value is known to be `true`.
-  static final ConstraintVariable always = _Always();
-
-  /// A list of all constraints containing this variable on their left hand side
-  /// that may not have been satisfied yet.
-  final _dependencies = <_Clause>[];
-
-  /// The value assigned to this constraint variable by the solution currently
-  /// being computed.
-  bool _value = false;
-
-  /// If this variable represents a disjunction ("or") of several other
-  /// variables, the variables in the disjunction.  Otherwise a singleton list
-  /// containing `this`.
-  final List<ConstraintVariable> _disjunctionParts;
-
-  ConstraintVariable() : _disjunctionParts = List.filled(1, null) {
-    _disjunctionParts[0] = this;
-  }
-
-  /// Creates a [ConstraintVariable] representing a disjunction ("or") of
-  /// several other variables.
-  ///
-  /// Additional constraints will be recorded in [constraints] to ensure that
-  /// the solution will be consistent.
-  factory ConstraintVariable.or(
-      Constraints constraints, ConstraintVariable a, ConstraintVariable b) {
-    if (a == null) return b;
-    if (b == null) return a;
-    var parts = a.disjunctionParts.toList();
-    parts.addAll(b.disjunctionParts);
-    assert(parts.length > 1);
-    var result = ConstraintVariable._(parts);
-    constraints.record([a], result);
-    constraints.record([b], result);
-    return result;
-  }
-
-  ConstraintVariable._(this._disjunctionParts);
-
-  /// If this variable represents a disjunction ("or") of several other
-  /// variables, the variables in the disjunction.  Otherwise a singleton list
-  /// containing `this`.
-  Iterable<ConstraintVariable> get disjunctionParts => _disjunctionParts;
-
-  /// Indicates whether this variable represents a disjunction ("or") of several
-  /// other variables.
-  bool get isDisjunction => _disjunctionParts.length > 1;
-
-  /// The value assigned to this constraint variable by the solution currently
-  /// being computed.
-  bool get value => _value;
-
-  @override
-  String toString() =>
-      isDisjunction ? '(${_disjunctionParts.join(' | ')})' : super.toString();
-}
-
-/// The core of the migration tool's constraint solver.  This class implements
-/// unit propagation (see https://en.wikipedia.org/wiki/Unit_propagation),
-/// extended to support disjunctions.
-///
-/// The extension works approximately as follows: first we perform ordinary unit
-/// propagation, accumulating a list of any disjunction variables that need to
-/// be assigned a value of `true`.  Once this finishes, we heuristically choose
-/// one of these disjunction variables and ensure that it is assigned a value of
-/// `true` by setting one of its constituent variables to `true` and propagating
-/// again.  Once all disjunctions have been resolved, we have a final solution.
-class Solver extends Constraints {
-  /// Clauses that should be evaluated as part of ordinary unit propagation.
-  final _pending = <_Clause>[];
-
-  /// Disjunction variables that have been determined by unit propagation to be
-  /// `true`, but for which we have not yet propagated the `true` value to one
-  /// of the constituent variables.
-  final _pendingDisjunctions = <ConstraintVariable>[];
-
-  /// Heuristically resolves any pending disjunctions.
-  void applyHeuristics() {
-    while (_pendingDisjunctions.isNotEmpty) {
-      var disjunction = _pendingDisjunctions.removeLast();
-      if (disjunction.disjunctionParts.any((v) => v.value)) continue;
-      // TODO(paulberry): smarter heuristics
-      var choice = disjunction.disjunctionParts.first;
-      record([], choice);
-    }
-  }
-
-  @override
-  void record(Iterable<ConstraintVariable> conditions,
-      covariant ConstraintVariable consequence) {
-    var _conditions = List<ConstraintVariable>.from(conditions);
-    var clause = _Clause(_conditions, consequence);
-    int i = 0;
-    while (i < _conditions.length) {
-      ConstraintVariable variable = _conditions[i];
-      if (variable._value) {
-        int j = _conditions.length - 1;
-        _conditions[i] = _conditions[j];
-        _conditions.removeLast();
-        continue;
-      }
-      variable._dependencies.add(clause);
-      i++;
-    }
-    if (i == 0) {
-      if (!consequence._value) {
-        consequence._value = true;
-        if (consequence.isDisjunction) {
-          _pendingDisjunctions.add(consequence);
-        }
-        _pending.addAll(consequence._dependencies);
-        _propagate();
-      }
-    } else {
-      consequence._dependencies.add(clause);
-    }
-  }
-
-  /// Performs ordinary unit propagation, recording any disjunctions encountered
-  /// in [_pendingDisjunctions].
-  void _propagate() {
-    while (_pending.isNotEmpty) {
-      var clause = _pending.removeLast();
-      var conditions = clause.conditions;
-      int i = 0;
-      while (i < conditions.length) {
-        ConstraintVariable variable = conditions[i];
-        if (variable._value) {
-          int j = conditions.length - 1;
-          conditions[i] = conditions[j];
-          conditions.removeLast();
-          continue;
-        }
-        i++;
-      }
-      if (i == 0) {
-        var consequence = clause.consequence;
-        if (!consequence._value) {
-          consequence._value = true;
-          if (consequence.isDisjunction) {
-            _pendingDisjunctions.add(consequence);
-          }
-          _pending.addAll(consequence._dependencies);
-        }
-      }
-    }
-  }
-}
-
-/// The special singleton [ConstraintVariable] whose value is always `true`.
-class _Always extends ConstraintVariable {
-  _Always() {
-    _value = true;
-  }
-
-  @override
-  String toString() => 'always';
-}
-
-/// A single equation in a system of constraints.
-class _Clause {
-  /// The conditions on the left hand side of the equation.
-  final List<ConstraintVariable> conditions;
-
-  /// The single variable on the right hand side of the equation.
-  final ConstraintVariable consequence;
-
-  _Clause(this.conditions, this.consequence);
-}
diff --git a/pkg/analysis_server/lib/src/server/driver.dart b/pkg/analysis_server/lib/src/server/driver.dart
index 70f98dc..2937dee 100644
--- a/pkg/analysis_server/lib/src/server/driver.dart
+++ b/pkg/analysis_server/lib/src/server/driver.dart
@@ -532,6 +532,8 @@
   ) {
     final serve_http = diagnosticServerPort != null;
 
+    linter.registerLintRules();
+
     _DiagnosticServerImpl diagnosticServer = new _DiagnosticServerImpl();
 
     final socketServer = new LspSocketServer(
diff --git a/pkg/analysis_server/lib/src/services/correction/assist.dart b/pkg/analysis_server/lib/src/services/correction/assist.dart
index 50ac2ac..d24108b 100644
--- a/pkg/analysis_server/lib/src/services/correction/assist.dart
+++ b/pkg/analysis_server/lib/src/services/correction/assist.dart
@@ -60,11 +60,6 @@
   static const CONVERT_INTO_FINAL_FIELD = const AssistKind(
       'dart.assist.convert.getterToFinalField', 30, "Convert to final field",
       associatedErrorCodes: <String>['prefer_final_fields']);
-  static const CONVERT_INTO_ABSOLUTE_IMPORT = const AssistKind(
-      'dart.assist.convert.relativeToAbsoluteImport',
-      30,
-      "Convert to absolute import",
-      associatedErrorCodes: <String>['avoid_relative_lib_imports']);
   static const CONVERT_INTO_FOR_INDEX = const AssistKind(
       'dart.assist.convert.forEachToForIndex', 30, "Convert to for-index loop");
   static const CONVERT_INTO_GENERIC_FUNCTION_SYNTAX = const AssistKind(
@@ -120,6 +115,11 @@
   static const CONVERT_TO_NULL_AWARE = const AssistKind(
       'dart.assist.convert.toNullAware', 30, "Convert to use '?.'",
       associatedErrorCodes: <String>['prefer_null_aware_operators']);
+  static const CONVERT_TO_PACKAGE_IMPORT = const AssistKind(
+      'dart.assist.convert.relativeToPackageImport',
+      30,
+      "Convert to 'package:' import",
+      associatedErrorCodes: <String>['avoid_relative_lib_imports']);
   static const CONVERT_TO_SET_LITERAL = const AssistKind(
       'dart.assist.convert.toSetLiteral', 30, "Convert to set literal",
       // todo (brianwilkerson): unify w/ fix
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 6539550..b420fd0 100644
--- a/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
@@ -104,7 +104,6 @@
     await _addProposal_convertMapConstructorToMapLiteral();
     await _addProposal_convertPartOfToUri();
     await _addProposal_convertSetConstructorToSetLiteral();
-    await _addProposal_convertToAbsoluteImport();
     await _addProposal_convertToAsyncFunctionBody();
     await _addProposal_convertToBlockFunctionBody();
     await _addProposal_convertToDoubleQuotedString();
@@ -119,6 +118,7 @@
     await _addProposal_convertToMultilineString();
     await _addProposal_convertToNormalParameter();
     await _addProposal_convertToNullAware();
+    await _addProposal_convertToPackageImport();
     await _addProposal_convertToSingleQuotedString();
     await _addProposal_encapsulateField();
     await _addProposal_exchangeOperands();
@@ -1229,29 +1229,6 @@
     _addAssistFromBuilder(changeBuilder, DartAssistKind.CONVERT_TO_SET_LITERAL);
   }
 
-  Future<void> _addProposal_convertToAbsoluteImport() async {
-    var node = this.node;
-    if (node is StringLiteral) {
-      node = node.parent;
-    }
-    if (node is ImportDirective) {
-      var importDirective = node;
-      var importUri = node.uriSource?.uri;
-      if (importUri?.scheme != 'package') {
-        return;
-      }
-      var changeBuilder = _newDartChangeBuilder();
-      await changeBuilder.addFileEdit(file, (builder) {
-        builder.addSimpleReplacement(
-            range.node(importDirective.uri), "'$importUri'");
-      });
-      _addAssistFromBuilder(
-        changeBuilder,
-        DartAssistKind.CONVERT_INTO_ABSOLUTE_IMPORT,
-      );
-    }
-  }
-
   Future<void> _addProposal_convertToAsyncFunctionBody() async {
     FunctionBody body = getEnclosingFunctionBody();
     if (body == null ||
@@ -1945,6 +1922,48 @@
     }
   }
 
+  Future<void> _addProposal_convertToPackageImport() async {
+    var node = this.node;
+    if (node is StringLiteral) {
+      node = node.parent;
+    }
+    if (node is ImportDirective) {
+      ImportDirective importDirective = node;
+      var uriSource = importDirective.uriSource;
+
+      // Ignore if invalid URI.
+      if (uriSource == null) {
+        return;
+      }
+
+      var importUri = uriSource.uri;
+      if (importUri.scheme != 'package') {
+        return;
+      }
+
+      // Don't offer to convert a 'package:' URI to itself.
+      try {
+        if (Uri.parse(importDirective.uriContent).scheme == 'package') {
+          return;
+        }
+      } on FormatException {
+        return;
+      }
+
+      var changeBuilder = _newDartChangeBuilder();
+      await changeBuilder.addFileEdit(file, (builder) {
+        builder.addSimpleReplacement(
+          range.node(importDirective.uri),
+          "'$importUri'",
+        );
+      });
+      _addAssistFromBuilder(
+        changeBuilder,
+        DartAssistKind.CONVERT_TO_PACKAGE_IMPORT,
+      );
+    }
+  }
+
   Future<void> _addProposal_convertToSingleQuotedString() async {
     // TODO(brianwilkerson) Determine whether this await is necessary.
     await null;
diff --git a/pkg/analysis_server/lib/src/status/diagnostics.dart b/pkg/analysis_server/lib/src/status/diagnostics.dart
index 2723c18..a03964c 100644
--- a/pkg/analysis_server/lib/src/status/diagnostics.dart
+++ b/pkg/analysis_server/lib/src/status/diagnostics.dart
@@ -551,9 +551,9 @@
     }
 
     h3('Dartdoc template info');
-    DartdocDirectiveInfo info = (server as AnalysisServer).declarationsTracker
-        ?.getContext(driver.analysisContext)
-        ?.dartdocDirectiveInfo ??
+    DartdocDirectiveInfo info = server.declarationsTracker
+            ?.getContext(driver.analysisContext)
+            ?.dartdocDirectiveInfo ??
         new DartdocDirectiveInfo();
     writeMap(info.templateMap);
   }
diff --git a/pkg/analysis_server/test/analysis/notification_errors_test.dart b/pkg/analysis_server/test/analysis/notification_errors_test.dart
index ffec72b..d344bc9 100644
--- a/pkg/analysis_server/test/analysis/notification_errors_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_errors_test.dart
@@ -29,6 +29,12 @@
     if (notification.event == ANALYSIS_NOTIFICATION_ERRORS) {
       var decoded = new AnalysisErrorsParams.fromNotification(notification);
       filesErrors[decoded.file] = decoded.errors;
+    } else if (notification.event == ANALYSIS_NOTIFICATION_FLUSH_RESULTS) {
+      var decoded =
+          new AnalysisFlushResultsParams.fromNotification(notification);
+      for (var file in decoded.files) {
+        filesErrors[file] = null;
+      }
     }
   }
 
@@ -125,6 +131,55 @@
     expect(errors, isNull);
   }
 
+  test_dotFolder_priority() async {
+    // Files inside dotFolders should not generate error notifications even
+    // if they are added to priority (priority affects only priority, not what
+    // is analyzed).
+    createProject();
+    addTestFile('');
+    String brokenFile =
+        newFile(join(projectPath, '.dart_tool/broken.dart'), content: 'err')
+            .path;
+
+    await waitForTasksFinished();
+    await pumpEventQueue(times: 5000);
+    expect(filesErrors[brokenFile], isNull);
+
+    // Add to priority files and give chance for the file to be analyzed (if
+    // it would).
+    await setPriorityFiles([brokenFile]);
+    await waitForTasksFinished();
+    await pumpEventQueue(times: 5000);
+
+    // There should still be no errors.
+    expect(filesErrors[brokenFile], isNull);
+  }
+
+  test_dotFolder_unopenedFile() async {
+    // Files inside dotFolders are not analyzed. Sending requests that cause
+    // them to be opened (such as hovers) should not result in error notifications
+    // because there is no event that would flush them and they'd remain in the
+    // editor forever.
+    createProject();
+    addTestFile('');
+    String brokenFile =
+        newFile(join(projectPath, '.dart_tool/broken.dart'), content: 'err')
+            .path;
+
+    await waitForTasksFinished();
+    await pumpEventQueue(times: 5000);
+    expect(filesErrors[brokenFile], isNull);
+
+    // Send a getHover request for the file that will cause it to be read from disk.
+    await waitResponse(
+        new AnalysisGetHoverParams(brokenFile, 0).toRequest('0'));
+    await waitForTasksFinished();
+    await pumpEventQueue(times: 5000);
+
+    // There should be no errors because the file is not being analyzed.
+    expect(filesErrors[brokenFile], isNull);
+  }
+
   test_importError() async {
     createProject();
 
@@ -191,6 +246,108 @@
     expect(filesErrors[otherFile], isNull);
   }
 
+  test_overlay_dotFolder() async {
+    // Files inside dotFolders should not generate error notifications even
+    // if they have overlays added.
+    createProject();
+    addTestFile('');
+    String brokenFile =
+        newFile(join(projectPath, '.dart_tool/broken.dart'), content: 'err')
+            .path;
+
+    await waitForTasksFinished();
+    await pumpEventQueue(times: 5000);
+    expect(filesErrors[brokenFile], isNull);
+
+    // Add and overlay and give chance for the file to be analyzed (if
+    // it would).
+    await waitResponse(
+      new AnalysisUpdateContentParams({
+        brokenFile: new AddContentOverlay('err'),
+      }).toRequest('1'),
+    );
+    await waitForTasksFinished();
+    await pumpEventQueue(times: 5000);
+
+    // There should still be no errors.
+    expect(filesErrors[brokenFile], isNull);
+  }
+
+  test_overlay_newFile() async {
+    // Overlays added for files that don't exist on disk should still generate
+    // error notifications. Removing the overlay if the file is not on disk
+    // should clear the errors.
+    createProject();
+    addTestFile('');
+    String brokenFile = convertPath(join(projectPath, 'broken.dart'));
+
+    // Add and overlay and give chance for the file to be analyzed.
+    await waitResponse(
+      new AnalysisUpdateContentParams({
+        brokenFile: new AddContentOverlay('err'),
+      }).toRequest('0'),
+    );
+    await waitForTasksFinished();
+    await pumpEventQueue(times: 5000);
+
+    // There should now be errors.
+    expect(filesErrors[brokenFile], hasLength(greaterThan(0)));
+
+    // Remove the overlay (this file no longer exists anywhere).
+    await waitResponse(
+      new AnalysisUpdateContentParams({
+        brokenFile: new RemoveContentOverlay(),
+      }).toRequest('1'),
+    );
+    await waitForTasksFinished();
+    await pumpEventQueue(times: 5000);
+
+    // Unlike other tests here, removing an overlay for a file that doesn't exist
+    // on disk doesn't flush errors, but re-analyzes the missing file, which results
+    // in an error notification of 0 errors rather than a flush.
+    expect(filesErrors[brokenFile], isEmpty);
+  }
+
+  test_overlay_newFileSavedBeforeRemoving() async {
+    // Overlays added for files that don't exist on disk should still generate
+    // error notifications. If the file is subsequently saved to disk before the
+    // overlay is removed, the errors should not be flushed when the overlay is
+    // removed.
+    createProject();
+    addTestFile('');
+    String brokenFile = convertPath(join(projectPath, 'broken.dart'));
+
+    // Add and overlay and give chance for the file to be analyzed.
+    await waitResponse(
+      new AnalysisUpdateContentParams({
+        brokenFile: new AddContentOverlay('err'),
+      }).toRequest('0'),
+    );
+    await waitForTasksFinished();
+    await pumpEventQueue(times: 5000);
+
+    // There should now be errors.
+    expect(filesErrors[brokenFile], hasLength(greaterThan(0)));
+
+    // Write the file to disk.
+    newFile(brokenFile, content: 'err');
+    await waitForTasksFinished();
+    await pumpEventQueue(times: 5000);
+
+    // Remove the overlay.
+    await waitResponse(
+      new AnalysisUpdateContentParams({
+        brokenFile: new RemoveContentOverlay(),
+      }).toRequest('1'),
+    );
+    await waitForTasksFinished();
+    await pumpEventQueue(times: 5000);
+
+    // Errors should not have been flushed since the file still exists without
+    // the overlay.
+    expect(filesErrors[brokenFile], hasLength(greaterThan(0)));
+  }
+
   test_ParserError() async {
     createProject();
     addTestFile('library lib');
diff --git a/pkg/analysis_server/test/context_manager_test.dart b/pkg/analysis_server/test/context_manager_test.dart
index 88938f1..f30a1c3 100644
--- a/pkg/analysis_server/test/context_manager_test.dart
+++ b/pkg/analysis_server/test/context_manager_test.dart
@@ -18,6 +18,7 @@
 import 'package:analyzer/src/dart/analysis/file_state.dart';
 import 'package:analyzer/src/dart/analysis/performance_logger.dart';
 import 'package:analyzer/src/dart/analysis/restricted_analysis_context.dart';
+import 'package:analyzer/src/dart/analysis/session.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer/src/generated/engine.dart' hide AnalysisResult;
 import 'package:analyzer/src/generated/sdk.dart';
@@ -1978,8 +1979,9 @@
     String sdkExtPath = '$projPath/sdk_ext';
     newFile('$projPath/test', content: 'test.dart');
     newFile('$sdkExtPath/entry.dart');
+    var synchronousSession = SynchronousSession(analysisOptions, null);
     List<int> bytes = new SummaryBuilder(
-            [], RestrictedAnalysisContext(analysisOptions, null, null))
+            [], RestrictedAnalysisContext(synchronousSession, null))
         .build();
     newFileWithBytes('$projPath/sdk.ds', bytes);
     // Setup _embedder.yaml.
diff --git a/pkg/analysis_server/test/integration/lsp_server/analyzer_status_test.dart b/pkg/analysis_server/test/integration/lsp_server/analyzer_status_test.dart
new file mode 100644
index 0000000..bff7062
--- /dev/null
+++ b/pkg/analysis_server/test/integration/lsp_server/analyzer_status_test.dart
@@ -0,0 +1,59 @@
+// 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/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'integration_tests.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(AnalyzerStatusTest);
+  });
+}
+
+@reflectiveTest
+class AnalyzerStatusTest extends AbstractLspAnalysisServerIntegrationTest {
+  test_afterInitialize() async {
+    const initialContents = 'int a = 1;';
+    newFile(mainFilePath, content: initialContents);
+
+    // To avoid races, set up listeners for the notifications before we initialise
+    // and track which event came first to ensure they arrived in the expected
+    // order.
+    bool firstNotificationWasAnalyzing = null;
+    final startNotification = waitForAnalysisStart()
+        .then((_) => firstNotificationWasAnalyzing ??= true);
+    final completeNotification = waitForAnalysisComplete()
+        .then((_) => firstNotificationWasAnalyzing ??= false);
+
+    await initialize();
+    await startNotification;
+    await completeNotification;
+
+    expect(firstNotificationWasAnalyzing, isTrue);
+  }
+
+  test_afterDocumentEdits() async {
+    const initialContents = 'int a = 1;';
+    newFile(mainFilePath, content: initialContents);
+
+    final initialAnalysis = waitForAnalysisComplete();
+
+    await initialize();
+    await initialAnalysis;
+
+    // Set up futures to wait for the new events.
+    final startNotification = waitForAnalysisStart();
+    final completeNotification = waitForAnalysisComplete();
+
+    // Send a modification
+    await openFile(mainFileUri, initialContents);
+    await replaceFile(222, mainFileUri, 'String a = 1;');
+
+    // Ensure the notifications come through again.
+    await startNotification;
+    await completeNotification;
+  }
+}
diff --git a/pkg/analysis_server/test/integration/lsp_server/diagnostic_test.dart b/pkg/analysis_server/test/integration/lsp_server/diagnostic_test.dart
new file mode 100644
index 0000000..40e2ff6
--- /dev/null
+++ b/pkg/analysis_server/test/integration/lsp_server/diagnostic_test.dart
@@ -0,0 +1,52 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'integration_tests.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(DiagnosticTest);
+  });
+}
+
+@reflectiveTest
+class DiagnosticTest extends AbstractLspAnalysisServerIntegrationTest {
+  test_initialAnalysis() async {
+    newFile(mainFilePath, content: 'String a = 1;');
+
+    final diagnosticsUpdate = waitForDiagnostics(mainFileUri);
+    await initialize();
+    final diagnostics = await diagnosticsUpdate;
+    expect(diagnostics, hasLength(1));
+    final diagnostic = diagnostics.first;
+    expect(diagnostic.code, equals('invalid_assignment'));
+    expect(diagnostic.range.start.line, equals(0));
+    expect(diagnostic.range.start.character, equals(11));
+    expect(diagnostic.range.end.line, equals(0));
+    expect(diagnostic.range.end.character, equals(12));
+  }
+
+  test_lints() async {
+    newFile(mainFilePath, content: '''main() async => await 1;''');
+    newFile(analysisOptionsPath, content: '''
+linter:
+  rules:
+    - await_only_futures
+    ''');
+
+    final diagnosticsUpdate = waitForDiagnostics(mainFileUri);
+    await initialize();
+    final diagnostics = await diagnosticsUpdate;
+    expect(diagnostics, hasLength(1));
+    final diagnostic = diagnostics.first;
+    expect(diagnostic.code, equals('await_only_futures'));
+    expect(diagnostic.range.start.line, equals(0));
+    expect(diagnostic.range.start.character, equals(16));
+    expect(diagnostic.range.end.line, equals(0));
+    expect(diagnostic.range.end.character, equals(21));
+  }
+}
diff --git a/pkg/analysis_server/test/integration/lsp_server/integration_tests.dart b/pkg/analysis_server/test/integration/lsp_server/integration_tests.dart
index f8a1713..aac6231 100644
--- a/pkg/analysis_server/test/integration/lsp_server/integration_tests.dart
+++ b/pkg/analysis_server/test/integration/lsp_server/integration_tests.dart
@@ -9,16 +9,12 @@
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
 import 'package:analysis_server/src/lsp/channel/lsp_byte_stream_channel.dart';
 import 'package:analyzer/instrumentation/instrumentation.dart';
-import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
 import 'package:path/path.dart';
 
 import '../../lsp/server_abstract.dart';
 
 class AbstractLspAnalysisServerIntegrationTest
-    with
-        ResourceProviderMixin,
-        ClientCapabilitiesHelperMixin,
-        LspAnalysisServerTestMixin {
+    with ClientCapabilitiesHelperMixin, LspAnalysisServerTestMixin {
   LspServerClient client;
 
   final Map<int, Completer<ResponseMessage>> _completers = {};
@@ -49,6 +45,11 @@
     }
   }
 
+  newFile(String path, {String content}) =>
+      File(path).writeAsStringSync(content ?? '');
+
+  newFolder(String path) => Directory(path).createSync(recursive: true);
+
   @override
   void sendNotificationToServer(NotificationMessage notification) =>
       client.channel.sendNotification(notification);
@@ -74,7 +75,13 @@
     projectFolderPath = Directory.systemTemp
         .createTempSync('analysisServer')
         .resolveSymbolicLinksSync();
+    newFolder(projectFolderPath);
+    newFolder(join(projectFolderPath, 'lib'));
     projectFolderUri = Uri.file(projectFolderPath);
+    mainFilePath = join(projectFolderPath, 'lib', 'main.dart');
+    mainFileUri = Uri.file(mainFilePath);
+    analysisOptionsPath = join(projectFolderPath, 'analysis_options.yaml');
+    analysisOptionsUri = Uri.file(analysisOptionsPath);
 
     client = new LspServerClient();
     await client.start();
diff --git a/pkg/analysis_server/test/integration/lsp_server/test_all.dart b/pkg/analysis_server/test/integration/lsp_server/test_all.dart
index 7f67613..b171d0a 100644
--- a/pkg/analysis_server/test/integration/lsp_server/test_all.dart
+++ b/pkg/analysis_server/test/integration/lsp_server/test_all.dart
@@ -4,11 +4,15 @@
 
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
+import 'analyzer_status_test.dart' as analyzer_status;
+import 'diagnostic_test.dart' as diagnostic_test;
 import 'initialization_test.dart' as initialization_test;
 import 'server_test.dart' as server_test;
 
 main() {
   defineReflectiveSuite(() {
+    analyzer_status.main();
+    diagnostic_test.main();
     initialization_test.main();
     server_test.main();
   }, name: 'lsp integration');
diff --git a/pkg/analysis_server/test/lsp/analyzer_status_test.dart b/pkg/analysis_server/test/lsp/analyzer_status_test.dart
new file mode 100644
index 0000000..1f5859c
--- /dev/null
+++ b/pkg/analysis_server/test/lsp/analyzer_status_test.dart
@@ -0,0 +1,59 @@
+// 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/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'server_abstract.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(AnalyzerStatusTest);
+  });
+}
+
+@reflectiveTest
+class AnalyzerStatusTest extends AbstractLspAnalysisServerTest {
+  test_afterInitialize() async {
+    const initialContents = 'int a = 1;';
+    newFile(mainFilePath, content: initialContents);
+
+    // To avoid races, set up listeners for the notifications before we initialise
+    // and track which event came first to ensure they arrived in the expected
+    // order.
+    bool firstNotificationWasAnalyzing = null;
+    final startNotification = waitForAnalysisStart()
+        .then((_) => firstNotificationWasAnalyzing ??= true);
+    final completeNotification = waitForAnalysisComplete()
+        .then((_) => firstNotificationWasAnalyzing ??= false);
+
+    await initialize();
+    await startNotification;
+    await completeNotification;
+
+    expect(firstNotificationWasAnalyzing, isTrue);
+  }
+
+  test_afterDocumentEdits() async {
+    const initialContents = 'int a = 1;';
+    newFile(mainFilePath, content: initialContents);
+
+    final initialAnalysis = waitForAnalysisComplete();
+
+    await initialize();
+    await initialAnalysis;
+
+    // Set up futures to wait for the new events.
+    final startNotification = waitForAnalysisStart();
+    final completeNotification = waitForAnalysisComplete();
+
+    // Send a modification
+    await openFile(mainFileUri, initialContents);
+    await replaceFile(222, mainFileUri, 'String a = 1;');
+
+    // Ensure the notifications come through again.
+    await startNotification;
+    await completeNotification;
+  }
+}
diff --git a/pkg/analysis_server/test/lsp/code_actions_assists_test.dart b/pkg/analysis_server/test/lsp/code_actions_assists_test.dart
index a42d083..7c37bec 100644
--- a/pkg/analysis_server/test/lsp/code_actions_assists_test.dart
+++ b/pkg/analysis_server/test/lsp/code_actions_assists_test.dart
@@ -91,4 +91,16 @@
     applyChanges(contents, assistAction.edit.changes);
     expect(contents[mainFilePath], equals(expectedContent));
   }
+
+  test_nonDartFile() async {
+    await newFile(pubspecFilePath, content: simplePubspecContent);
+    await initialize(
+      textDocumentCapabilities: withCodeActionKinds(
+          emptyTextDocumentClientCapabilities, [CodeActionKind.Refactor]),
+    );
+
+    final codeActions =
+        await getCodeActions(pubspecFileUri.toString(), range: startOfDocRange);
+    expect(codeActions, isEmpty);
+  }
 }
diff --git a/pkg/analysis_server/test/lsp/code_actions_fixes_test.dart b/pkg/analysis_server/test/lsp/code_actions_fixes_test.dart
index 4d692a1..daadf31 100644
--- a/pkg/analysis_server/test/lsp/code_actions_fixes_test.dart
+++ b/pkg/analysis_server/test/lsp/code_actions_fixes_test.dart
@@ -93,4 +93,16 @@
     applyChanges(contents, fixAction.edit.changes);
     expect(contents[mainFilePath], equals(expectedContent));
   }
+
+  test_nonDartFile() async {
+    await newFile(pubspecFilePath, content: simplePubspecContent);
+    await initialize(
+      textDocumentCapabilities: withCodeActionKinds(
+          emptyTextDocumentClientCapabilities, [CodeActionKind.QuickFix]),
+    );
+
+    final codeActions =
+        await getCodeActions(pubspecFileUri.toString(), range: startOfDocRange);
+    expect(codeActions, isEmpty);
+  }
 }
diff --git a/pkg/analysis_server/test/lsp/code_actions_source_test.dart b/pkg/analysis_server/test/lsp/code_actions_source_test.dart
index 3ea0d20..22c11ab 100644
--- a/pkg/analysis_server/test/lsp/code_actions_source_test.dart
+++ b/pkg/analysis_server/test/lsp/code_actions_source_test.dart
@@ -59,7 +59,7 @@
         // When the server sends the edit back, just keep a copy and say we
         // applied successfully (it'll be verified below).
         editParams = edit;
-        return new ApplyWorkspaceEditResponse(true);
+        return new ApplyWorkspaceEditResponse(true, null);
       },
     );
     // Successful edits return an empty success() response.
@@ -116,7 +116,7 @@
         // When the server sends the edit back, just keep a copy and say we
         // applied successfully (it'll be verified below).
         editParams = edit;
-        return new ApplyWorkspaceEditResponse(true);
+        return new ApplyWorkspaceEditResponse(true, null);
       },
     );
     // Successful edits return an empty success() response.
@@ -257,7 +257,7 @@
         // When the server sends the edit back, just keep a copy and say we
         // applied successfully (it'll be verified below).
         editParams = edit;
-        return new ApplyWorkspaceEditResponse(true);
+        return new ApplyWorkspaceEditResponse(true, null);
       },
     );
     // Successful edits return an empty success() response.
@@ -307,7 +307,7 @@
         // When the server sends the edit back, just keep a copy and say we
         // applied successfully (it'll be verified below).
         editParams = edit;
-        return new ApplyWorkspaceEditResponse(true);
+        return new ApplyWorkspaceEditResponse(true, null);
       },
     );
     // Successful edits return an empty success() response.
@@ -377,7 +377,8 @@
       // Claim that we failed tpo apply the edits. This is what the client
       // would do if the edits provided were for an old version of the
       // document.
-      handler: (edit) => new ApplyWorkspaceEditResponse(false),
+      handler: (edit) =>
+          new ApplyWorkspaceEditResponse(false, 'Document changed'),
     );
 
     // Ensure the request returned an error (error repsonses are thrown by
@@ -406,6 +407,18 @@
         throwsA(isResponseError(ServerErrorCodes.FileHasErrors)));
   }
 
+  test_nonDartFile() async {
+    await newFile(pubspecFilePath, content: simplePubspecContent);
+    await initialize(
+      textDocumentCapabilities: withCodeActionKinds(
+          emptyTextDocumentClientCapabilities, [CodeActionKind.Source]),
+    );
+
+    final codeActions =
+        await getCodeActions(pubspecFileUri.toString(), range: startOfDocRange);
+    expect(codeActions, isEmpty);
+  }
+
   test_unavailableWhenNotRequested() async {
     await newFile(mainFilePath);
     await initialize(
diff --git a/pkg/analysis_server/test/lsp/completion_test.dart b/pkg/analysis_server/test/lsp/completion_test.dart
index b3554c1..8a378f4 100644
--- a/pkg/analysis_server/test/lsp/completion_test.dart
+++ b/pkg/analysis_server/test/lsp/completion_test.dart
@@ -192,6 +192,14 @@
     expect(item.detail, isNot(contains('deprecated')));
   }
 
+  test_nonDartFile() async {
+    newFile(pubspecFilePath, content: simplePubspecContent);
+    await initialize();
+
+    final res = await getCompletion(pubspecFileUri, startOfDocPos);
+    expect(res, isEmpty);
+  }
+
   test_plainText() async {
     final content = '''
     class MyClass {
@@ -216,6 +224,210 @@
     expect(updated, contains('a.abcdefghij'));
   }
 
+  test_suggestionSets() async {
+    newFile(
+      join(projectFolderPath, 'other_file.dart'),
+      content: 'class InOtherFile {}',
+    );
+
+    final content = '''
+main() {
+  InOtherF^
+}
+    ''';
+
+    final initialAnalysis = waitForAnalysisComplete();
+    await initialize(
+        workspaceCapabilities:
+            withApplyEditSupport(emptyWorkspaceClientCapabilities));
+    await openFile(mainFileUri, withoutMarkers(content));
+    await initialAnalysis;
+    final res = await getCompletion(mainFileUri, positionFromMarker(content));
+
+    // Find the completion for the class in the other file.
+    final completion = res.singleWhere((c) => c.label == 'InOtherFile');
+    expect(completion, isNotNull);
+
+    // Resolve the completion item (via server) to get its edits. This is the
+    // LSP's equiv of getSuggestionDetails() and is invoked by LSP clients to
+    // populate additional info (in our case, the additional edits for inserting
+    // the import).
+    final resolved = await resolveCompletion(completion);
+    expect(resolved, isNotNull);
+
+    // Ensure the detail field was update to show this will auto-import.
+    expect(
+        resolved.detail, startsWith("Auto import from '../other_file.dart'"));
+
+    // There should be no command for this item because it doesn't need imports
+    // in other files. Same-file completions are in additionalEdits.
+    expect(resolved.command, isNull);
+
+    // Apply both the main completion edit and the additionalTextEdits atomically.
+    final newContent = applyTextEdits(
+      withoutMarkers(content),
+      [resolved.textEdit].followedBy(resolved.additionalTextEdits).toList(),
+    );
+
+    // Ensure both edits were made - the completion, and the inserted import.
+    expect(newContent, equals('''
+import '../other_file.dart';
+
+main() {
+  InOtherFile
+}
+    '''));
+  }
+
+  test_suggestionSets_insertsIntoPartFiles() async {
+    // File we'll be adding an import for.
+    newFile(
+      join(projectFolderPath, 'other_file.dart'),
+      content: 'class InOtherFile {}',
+    );
+
+    // File that will have the import added.
+    final parentContent = '''part 'main.dart';''';
+    final parentFilePath = newFile(
+      join(projectFolderPath, 'lib', 'parent.dart'),
+      content: parentContent,
+    ).path;
+
+    // File that we're invoking completion in.
+    final content = '''
+part of 'parent.dart';
+main() {
+  InOtherF^
+}
+    ''';
+
+    final initialAnalysis = waitForAnalysisComplete();
+    await initialize(
+        workspaceCapabilities:
+            withApplyEditSupport(emptyWorkspaceClientCapabilities));
+    await openFile(mainFileUri, withoutMarkers(content));
+    await initialAnalysis;
+    final res = await getCompletion(mainFileUri, positionFromMarker(content));
+
+    final completion = res.singleWhere((c) => c.label == 'InOtherFile');
+    expect(completion, isNotNull);
+
+    // Resolve the completion item to get its edits.
+    final resolved = await resolveCompletion(completion);
+    expect(resolved, isNotNull);
+    // Ensure it has a command, since it will need to make edits in other files
+    // and that's done by telling the server to send a workspace/applyEdit. LSP
+    // doesn't currently support these other-file edits in the completion.
+    // See https://github.com/microsoft/language-server-protocol/issues/749
+    expect(resolved.command, isNotNull);
+
+    // Apply all current-document edits.
+    final newContent = applyTextEdits(
+      withoutMarkers(content),
+      [resolved.textEdit].followedBy(resolved.additionalTextEdits).toList(),
+    );
+    expect(newContent, equals('''
+part of 'parent.dart';
+main() {
+  InOtherFile
+}
+    '''));
+
+    // Execute the associated command (which will handle edits in other files).
+    ApplyWorkspaceEditParams editParams;
+    final commandResponse = await handleExpectedRequest<Object,
+        ApplyWorkspaceEditParams, ApplyWorkspaceEditResponse>(
+      Method.workspace_applyEdit,
+      () => executeCommand(resolved.command),
+      handler: (edit) {
+        // When the server sends the edit back, just keep a copy and say we
+        // applied successfully (it'll be verified below).
+        editParams = edit;
+        return new ApplyWorkspaceEditResponse(true, null);
+      },
+    );
+    // Successful edits return an empty success() response.
+    expect(commandResponse, isNull);
+
+    // Ensure the edit came back.
+    expect(editParams, isNotNull);
+    expect(editParams.edit.changes, isNotNull);
+
+    // Ensure applying the changes will give us the expected content.
+    final contents = {
+      parentFilePath: withoutMarkers(parentContent),
+    };
+    applyChanges(contents, editParams.edit.changes);
+
+    // Check the parent file was modified to include the import by the edits
+    // that came from the server.
+    expect(contents[parentFilePath], equals('''
+import '../other_file.dart';
+
+part 'main.dart';'''));
+  }
+
+  test_suggestionSets_unavailableIfDisabled() async {
+    newFile(
+      join(projectFolderPath, 'other_file.dart'),
+      content: 'class InOtherFile {}',
+    );
+
+    final content = '''
+main() {
+  InOtherF^
+}
+    ''';
+
+    final initialAnalysis = waitForAnalysisComplete();
+    // Support applyEdit, but explicitly disable the suggestions.
+    await initialize(
+      initializationOptions: {'suggestFromUnimportedLibraries': false},
+      workspaceCapabilities:
+          withApplyEditSupport(emptyWorkspaceClientCapabilities),
+    );
+    await openFile(mainFileUri, withoutMarkers(content));
+    await initialAnalysis;
+    final res = await getCompletion(mainFileUri, positionFromMarker(content));
+
+    // Ensure the item doesn't appear in the results (because we might not
+    // be able to execute the import edits if they're in another file).
+    final completion = res.singleWhere(
+      (c) => c.label == 'InOtherFile',
+      orElse: () => null,
+    );
+    expect(completion, isNull);
+  }
+
+  test_suggestionSets_unavailableWithoutApplyEdit() async {
+    // If client doesn't advertise support for workspace/applyEdit, we won't
+    // include suggestion sets.
+    newFile(
+      join(projectFolderPath, 'other_file.dart'),
+      content: 'class InOtherFile {}',
+    );
+
+    final content = '''
+main() {
+  InOtherF^
+}
+    ''';
+
+    final initialAnalysis = waitForAnalysisComplete();
+    await initialize();
+    await openFile(mainFileUri, withoutMarkers(content));
+    await initialAnalysis;
+    final res = await getCompletion(mainFileUri, positionFromMarker(content));
+
+    // Ensure the item doesn't appear in the results (because we might not
+    // be able to execute the import edits if they're in another file).
+    final completion = res.singleWhere(
+      (c) => c.label == 'InOtherFile',
+      orElse: () => null,
+    );
+    expect(completion, isNull);
+  }
+
   test_unopenFile() async {
     final content = '''
     class MyClass {
diff --git a/pkg/analysis_server/test/lsp/definition_test.dart b/pkg/analysis_server/test/lsp/definition_test.dart
index 4e99a7f..a7df3fe 100644
--- a/pkg/analysis_server/test/lsp/definition_test.dart
+++ b/pkg/analysis_server/test/lsp/definition_test.dart
@@ -53,6 +53,14 @@
     expect(loc.uri, equals(referencedFileUri.toString()));
   }
 
+  test_nonDartFile() async {
+    newFile(pubspecFilePath, content: simplePubspecContent);
+    await initialize();
+
+    final res = await getDefinition(pubspecFileUri, startOfDocPos);
+    expect(res, isEmpty);
+  }
+
   test_singleFile() async {
     final contents = '''
     [[foo]]() {
diff --git a/pkg/analysis_server/test/lsp/diagnostic_test.dart b/pkg/analysis_server/test/lsp/diagnostic_test.dart
index 802d3be..06ba649 100644
--- a/pkg/analysis_server/test/lsp/diagnostic_test.dart
+++ b/pkg/analysis_server/test/lsp/diagnostic_test.dart
@@ -2,6 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -61,4 +62,23 @@
     expect(diagnostic.range.end.line, equals(0));
     expect(diagnostic.range.end.character, equals(12));
   }
+
+  test_dotFilesExcluded() async {
+    var dotFolderFilePath =
+        join(projectFolderPath, '.dart_tool', 'tool_file.dart');
+    var dotFolderFileUri = Uri.file(dotFolderFilePath);
+
+    newFile(dotFolderFilePath, content: 'String a = 1;');
+
+    List<Diagnostic> diagnostics = null;
+    waitForDiagnostics(dotFolderFileUri).then((d) => diagnostics = d);
+
+    // Send a request for a hover.
+    await initialize();
+    await getHover(dotFolderFileUri, Position(0, 0));
+
+    // Ensure that as part of responding to getHover, diagnostics were not
+    // transmitted.
+    expect(diagnostics, isNull);
+  }
 }
diff --git a/pkg/analysis_server/test/lsp/document_highlights_test.dart b/pkg/analysis_server/test/lsp/document_highlights_test.dart
index 7f002b4..374dd1d 100644
--- a/pkg/analysis_server/test/lsp/document_highlights_test.dart
+++ b/pkg/analysis_server/test/lsp/document_highlights_test.dart
@@ -29,6 +29,17 @@
     }
     ''');
 
+  test_nonDartFile() async {
+    await initialize();
+    await openFile(pubspecFileUri, simplePubspecContent);
+
+    final highlights =
+        await getDocumentHighlights(pubspecFileUri, startOfDocPos);
+
+    // Non-Dart files should return empty results, not errors.
+    expect(highlights, isEmpty);
+  }
+
   test_noResult() => _testMarkedContent('''
     main() {
       // This one is in a ^ comment!
diff --git a/pkg/analysis_server/test/lsp/document_symbols_test.dart b/pkg/analysis_server/test/lsp/document_symbols_test.dart
index b29ec7e..6d56201 100644
--- a/pkg/analysis_server/test/lsp/document_symbols_test.dart
+++ b/pkg/analysis_server/test/lsp/document_symbols_test.dart
@@ -104,4 +104,16 @@
     expect(method.kind, equals(SymbolKind.Method));
     expect(method.containerName, equals(myClass.name));
   }
+
+  test_nonDartFile() async {
+    newFile(pubspecFilePath, content: simplePubspecContent);
+    await initialize();
+
+    final result = await getDocumentSymbols(pubspecFileUri.toString());
+    final symbols = result.map(
+      (docsymbols) => throw 'Expected SymbolInformations, got DocumentSymbols',
+      (symbolInfos) => symbolInfos,
+    );
+    expect(symbols, isEmpty);
+  }
 }
diff --git a/pkg/analysis_server/test/lsp/folding_test.dart b/pkg/analysis_server/test/lsp/folding_test.dart
index 0b41612..098010c 100644
--- a/pkg/analysis_server/test/lsp/folding_test.dart
+++ b/pkg/analysis_server/test/lsp/folding_test.dart
@@ -66,6 +66,14 @@
     expect(regions, unorderedEquals(expectedRegions));
   }
 
+  test_nonDartFile() async {
+    await initialize();
+    await openFile(pubspecFileUri, simplePubspecContent);
+
+    final regions = await getFoldingRegions(pubspecFileUri);
+    expect(regions, isEmpty);
+  }
+
   test_headersImportsComments() async {
     // TODO(dantup): Review why the file header and the method comment ranges
     // are different... one spans only the range to collapse, but the other
diff --git a/pkg/analysis_server/test/lsp/format_test.dart b/pkg/analysis_server/test/lsp/format_test.dart
index 17a34b0..52d944e 100644
--- a/pkg/analysis_server/test/lsp/format_test.dart
+++ b/pkg/analysis_server/test/lsp/format_test.dart
@@ -63,6 +63,15 @@
     expect(formatEdits, isNull);
   }
 
+  test_nonDartFile() async {
+    await initialize();
+    await openFile(pubspecFileUri, simplePubspecContent);
+
+    final formatEdits =
+        await formatOnType(pubspecFileUri.toString(), startOfDocPos, '}');
+    expect(formatEdits, isNull);
+  }
+
   test_path_doesNotExist() async {
     await initialize();
 
diff --git a/pkg/analysis_server/test/lsp/hover_test.dart b/pkg/analysis_server/test/lsp/hover_test.dart
index f1312e2..6b9be51 100644
--- a/pkg/analysis_server/test/lsp/hover_test.dart
+++ b/pkg/analysis_server/test/lsp/hover_test.dart
@@ -18,6 +18,27 @@
 
 @reflectiveTest
 class HoverTest extends AbstractLspAnalysisServerTest {
+  test_dartDoc_macros() async {
+    final content = '''
+    /// {@template template_name}
+    /// This is shared content.
+    /// {@endtemplate}
+    const String foo = null;
+
+    /// {@macro template_name}
+    const String [[f^oo2]] = null;
+    ''';
+
+    final initialAnalysis = waitForAnalysisComplete();
+    await initialize();
+    await openFile(mainFileUri, withoutMarkers(content));
+    await initialAnalysis;
+    var hover = await getHover(mainFileUri, positionFromMarker(content));
+    expect(hover, isNotNull);
+    expect(hover.range, equals(rangeFromMarkers(content)));
+    expect(_getStringContents(hover), endsWith('This is shared content.'));
+  }
+
   test_hover_bad_position() async {
     await initialize();
     await openFile(mainFileUri, '');
@@ -107,6 +128,13 @@
     expect(hover, isNull);
   }
 
+  test_nonDartFile() async {
+    await initialize();
+    await openFile(pubspecFileUri, simplePubspecContent);
+    final hover = await getHover(pubspecFileUri, startOfDocPos);
+    expect(hover, isNull);
+  }
+
   test_plainText_simple() async {
     final content = '''
     /// This is a string.
diff --git a/pkg/analysis_server/test/lsp/implementation_test.dart b/pkg/analysis_server/test/lsp/implementation_test.dart
new file mode 100644
index 0000000..bde558e
--- /dev/null
+++ b/pkg/analysis_server/test/lsp/implementation_test.dart
@@ -0,0 +1,183 @@
+// 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/lsp_protocol/protocol_generated.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'server_abstract.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(ImplementationTest);
+  });
+}
+
+@reflectiveTest
+class ImplementationTest extends AbstractLspAnalysisServerTest {
+  test_class_excludesSelf() => _testMarkedContent('''
+      abstract class ^[[A]] {}
+      class B extends A {}
+      class C extends A {}
+    ''', shouldMatch: false);
+
+  test_class_excludesSuper() => _testMarkedContent('''
+      abstract class [[A]] {}
+      class ^B extends A {}
+      class C extends A {}
+    ''', shouldMatch: false);
+
+  test_class_sub() => _testMarkedContent('''
+      abstract class ^A {}
+      class [[B]] extends A {}
+      class [[C]] extends A {}
+    ''');
+
+  test_class_subSub() => _testMarkedContent('''
+      abstract class ^A {}
+      class [[B]] extends A {}
+      class [[C]] extends A {}
+      class [[D]] extends B {}
+      class [[E]] extends B {}
+      class [[F]] extends E {}
+    ''');
+
+  test_emptyResults() async {
+    final content = '';
+
+    await initialize();
+    await openFile(mainFileUri, content);
+    final res = await getImplementations(
+      mainFileUri,
+      startOfDocPos,
+    );
+
+    expect(res, isEmpty);
+  }
+
+  test_method_excludesClassesWithoutImplementations() => _testMarkedContent('''
+      abstract class A {
+        void ^b();
+      }
+
+      class B extends A {}
+
+      class [[E]] extends B {}
+    ''', shouldMatch: false);
+
+  test_method_excludesSelf() => _testMarkedContent('''
+      abstract class A {
+        void ^[[b]]();
+      }
+
+      class B extends A {
+        void b() {}
+      }
+    ''', shouldMatch: false);
+
+  test_method_excludesSuper() => _testMarkedContent('''
+      abstract class A {
+        void [[b]]();
+      }
+
+      class B extends A {
+        void ^b() {}
+      }
+    ''', shouldMatch: false);
+
+  test_method_fromCallSite() => _testMarkedContent('''
+      abstract class A {
+        void b();
+      }
+
+      class B extends A {
+        void [[b]]() {}
+      }
+
+      class C extends A {
+        void [[b]]() {}
+      }
+
+      class D extends B {
+        void [[b]]() {}
+      }
+
+      class E extends B {}
+
+      class F extends E {
+        void [[b]]() {}
+      }
+
+      void fromCallSite() {
+        A e = new E();
+        e.^b();
+      }
+    ''');
+
+  test_method_sub() => _testMarkedContent('''
+      abstract class A {
+        void ^b();
+      }
+
+      class B extends A {
+        void [[b]]() {}
+      }
+
+      class C extends A {
+        void [[b]]() {}
+      }
+    ''');
+
+  test_method_subSub() => _testMarkedContent('''
+      abstract class A {
+        void ^b();
+      }
+
+      class B extends A {
+        void [[b]]() {}
+      }
+
+      class D extends B {
+        void [[b]]() {}
+      }
+
+      class E extends B {}
+
+      class F extends E {
+        void [[b]]() {}
+      }
+    ''');
+
+  test_nonDartFile() async {
+    newFile(pubspecFilePath, content: simplePubspecContent);
+    await initialize();
+
+    final res = await getImplementations(pubspecFileUri, startOfDocPos);
+    expect(res, isEmpty);
+  }
+
+  /// Takes an input string that contains ^ at the location to invoke the
+  /// textDocument/implementations command and has ranges marked with
+  /// `[[brackets]]` that are expected to be included (or not, if [shouldMatch]
+  /// is set to `false`) in the results.
+  Future<void> _testMarkedContent(String content,
+      {bool shouldMatch = true}) async {
+    await initialize();
+    await openFile(mainFileUri, withoutMarkers(content));
+
+    final res = await getImplementations(
+      mainFileUri,
+      positionFromMarker(content),
+    );
+
+    final expectedLocations = rangesFromMarkers(content)
+        .map((r) => Location(mainFileUri.toString(), r));
+
+    if (shouldMatch) {
+      expect(res, equals(expectedLocations));
+    } else {
+      expectedLocations.forEach((l) => expect(res, isNot(contains(res))));
+    }
+  }
+}
diff --git a/pkg/analysis_server/test/lsp/initialization_test.dart b/pkg/analysis_server/test/lsp/initialization_test.dart
index 26b7028..aa19b1d 100644
--- a/pkg/analysis_server/test/lsp/initialization_test.dart
+++ b/pkg/analysis_server/test/lsp/initialization_test.dart
@@ -179,13 +179,10 @@
 
   test_uninitialized_rejectsRequests() async {
     final request = makeRequest(new Method.fromJson('randomRequest'), null);
-    final logParams = await expectErrorNotification<LogMessageParams>(() async {
-      final response = await channel.sendRequestToServer(request);
-      expect(response.id, equals(request.id));
-      expect(response.result, isNull);
-      expect(response.error, isNotNull);
-      expect(response.error.code, ErrorCodes.ServerNotInitialized);
-    });
-    expect(logParams.type, equals(MessageType.Error));
+    final response = await channel.sendRequestToServer(request);
+    expect(response.id, equals(request.id));
+    expect(response.result, isNull);
+    expect(response.error, isNotNull);
+    expect(response.error.code, ErrorCodes.ServerNotInitialized);
   }
 }
diff --git a/pkg/analysis_server/test/lsp/mapping_test.dart b/pkg/analysis_server/test/lsp/mapping_test.dart
new file mode 100644
index 0000000..d0d25b8
--- /dev/null
+++ b/pkg/analysis_server/test/lsp/mapping_test.dart
@@ -0,0 +1,76 @@
+// 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:collection';
+
+import 'package:analysis_server/lsp_protocol/protocol_generated.dart' as lsp;
+import 'package:analysis_server/src/lsp/mapping.dart' as lsp;
+import 'package:analysis_server/src/protocol_server.dart' as server;
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'server_abstract.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(MappingTest);
+  });
+}
+
+@reflectiveTest
+class MappingTest extends AbstractLspAnalysisServerTest {
+  test_completionItemKind_firstNotSupported() async {
+    // TYPE_PARAMETER maps to TypeParameter first, but since originally LSP
+    // did not support it, it'll map to Variable if the client doesn't support
+    // that.
+    var supportedKinds = new HashSet.of([
+      lsp.CompletionItemKind.TypeParameter,
+      lsp.CompletionItemKind.Variable,
+    ]);
+    var result = lsp.elementKindToCompletionItemKind(
+      supportedKinds,
+      server.ElementKind.TYPE_PARAMETER,
+    );
+    expect(result, equals(lsp.CompletionItemKind.TypeParameter));
+  }
+
+  test_completionItemKind_firstSupported() async {
+    // TYPE_PARAMETER maps to TypeParameter first, but since originally LSP
+    // did not support it, it'll map to Variable if the client doesn't support
+    // that.
+    var supportedKinds = new HashSet.of([lsp.CompletionItemKind.Variable]);
+    var result = lsp.elementKindToCompletionItemKind(
+      supportedKinds,
+      server.ElementKind.TYPE_PARAMETER,
+    );
+    expect(result, equals(lsp.CompletionItemKind.Variable));
+  }
+
+  test_completionItemKind_knownMapping() async {
+    final supportedKinds = new HashSet.of([lsp.CompletionItemKind.Class]);
+    final result = lsp.elementKindToCompletionItemKind(
+      supportedKinds,
+      server.ElementKind.CLASS,
+    );
+    expect(result, equals(lsp.CompletionItemKind.Class));
+  }
+
+  test_completionItemKind_notMapped() async {
+    var supportedKinds = new HashSet<lsp.CompletionItemKind>();
+    var result = lsp.elementKindToCompletionItemKind(
+      supportedKinds,
+      server.ElementKind.UNKNOWN, // Unknown is not mapped.
+    );
+    expect(result, isNull);
+  }
+
+  test_completionItemKind_notSupported() async {
+    var supportedKinds = new HashSet<lsp.CompletionItemKind>();
+    var result = lsp.elementKindToCompletionItemKind(
+      supportedKinds,
+      server.ElementKind.CLASS,
+    );
+    expect(result, isNull);
+  }
+}
diff --git a/pkg/analysis_server/test/lsp/references_test.dart b/pkg/analysis_server/test/lsp/references_test.dart
index bd36c11..0c69bca 100644
--- a/pkg/analysis_server/test/lsp/references_test.dart
+++ b/pkg/analysis_server/test/lsp/references_test.dart
@@ -99,6 +99,14 @@
     expect(loc.uri, equals(mainFileUri.toString()));
   }
 
+  test_nonDartFile() async {
+    newFile(pubspecFilePath, content: simplePubspecContent);
+    await initialize();
+
+    final res = await getReferences(pubspecFileUri, startOfDocPos);
+    expect(res, isEmpty);
+  }
+
   test_singleFile_withoutDeclaration() async {
     final contents = '''
     f^oo() {
diff --git a/pkg/analysis_server/test/lsp/server_abstract.dart b/pkg/analysis_server/test/lsp/server_abstract.dart
index 108a850..9c15da4 100644
--- a/pkg/analysis_server/test/lsp/server_abstract.dart
+++ b/pkg/analysis_server/test/lsp/server_abstract.dart
@@ -30,8 +30,7 @@
 
 final beginningOfDocument = new Range(new Position(0, 0), new Position(0, 0));
 
-mixin LspAnalysisServerTestMixin
-    implements ResourceProviderMixin, ClientCapabilitiesHelperMixin {
+mixin LspAnalysisServerTestMixin implements ClientCapabilitiesHelperMixin {
   static const positionMarker = '^';
   static const rangeMarkerStart = '[[';
   static const rangeMarkerEnd = ']]';
@@ -40,8 +39,11 @@
       new RegExp(allMarkers.map(RegExp.escape).join('|'));
 
   int _id = 0;
-  String projectFolderPath, mainFilePath;
-  Uri projectFolderUri, mainFileUri;
+  String projectFolderPath, mainFilePath, pubspecFilePath, analysisOptionsPath;
+  Uri projectFolderUri, mainFileUri, pubspecFileUri, analysisOptionsUri;
+  final String simplePubspecContent = 'name: my_project';
+  final startOfDocPos = new Position(0, 0);
+  final startOfDocRange = new Range(new Position(0, 0), new Position(0, 0));
 
   Stream<Message> get serverToClient;
 
@@ -367,6 +369,14 @@
     return expectSuccessfulResponseTo<List<CompletionItem>>(request);
   }
 
+  Future<CompletionItem> resolveCompletion(CompletionItem item) {
+    final request = makeRequest(
+      Method.completionItem_resolve,
+      item,
+    );
+    return expectSuccessfulResponseTo<CompletionItem>(request);
+  }
+
   Future<List<Location>> getDefinition(Uri uri, Position pos) {
     final request = makeRequest(
       Method.textDocument_definition,
@@ -433,6 +443,21 @@
     return expectSuccessfulResponseTo<Hover>(request);
   }
 
+  Future<List<Location>> getImplementations(
+    Uri uri,
+    Position pos, {
+    includeDeclarations = false,
+  }) {
+    final request = makeRequest(
+      Method.textDocument_implementation,
+      new TextDocumentPositionParams(
+        new TextDocumentIdentifier(uri.toString()),
+        pos,
+      ),
+    );
+    return expectSuccessfulResponseTo<List<Location>>(request);
+  }
+
   Future<List<Location>> getReferences(
     Uri uri,
     Position pos, {
@@ -713,7 +738,13 @@
     await serverToClient.firstWhere((message) {
       if (message is NotificationMessage &&
           message.method == Method.textDocument_publishDiagnostics) {
-        diagnosticParams = message.params;
+        // This helper method is used both in in-process tests where we'll get
+        // the real type back, and out-of-process integration tests where
+        // params is `Map<String, dynamic>` so for convenience just
+        // handle either here.
+        diagnosticParams = message.params is PublishDiagnosticsParams
+            ? message.params
+            : PublishDiagnosticsParams.fromJson(message.params);
 
         return diagnosticParams.uri == uri.toString();
       }
@@ -722,6 +753,31 @@
     return diagnosticParams.diagnostics;
   }
 
+  Future<AnalyzerStatusParams> waitForAnalysisStart() =>
+      waitForAnalysisStatus(true);
+
+  Future<AnalyzerStatusParams> waitForAnalysisComplete() =>
+      waitForAnalysisStatus(false);
+
+  Future<AnalyzerStatusParams> waitForAnalysisStatus(bool analyzing) async {
+    AnalyzerStatusParams params;
+    await serverToClient.firstWhere((message) {
+      if (message is NotificationMessage &&
+          message.method == CustomMethods.AnalyzerStatus) {
+        // This helper method is used both in in-process tests where we'll get
+        // the real type back, and out-of-process integration tests where
+        // params is `Map<String, dynamic>` so for convenience just
+        // handle either here.
+        params = message.params is AnalyzerStatusParams
+            ? message.params
+            : AnalyzerStatusParams.fromJson(message.params);
+        return params.isAnalyzing == analyzing;
+      }
+      return false;
+    });
+    return params;
+  }
+
   /// Removes markers like `[[` and `]]` and `^` that are used for marking
   /// positions/ranges in strings to avoid hard-coding positions in tests.
   String withoutMarkers(String contents) =>
@@ -786,6 +842,10 @@
     newFile(join(projectFolderPath, 'lib', 'file.dart'));
     mainFilePath = join(projectFolderPath, 'lib', 'main.dart');
     mainFileUri = Uri.file(mainFilePath);
+    pubspecFilePath = join(projectFolderPath, 'pubspec.yaml');
+    pubspecFileUri = Uri.file(pubspecFilePath);
+    analysisOptionsPath = join(projectFolderPath, 'analysis_options.yaml');
+    analysisOptionsUri = Uri.file(analysisOptionsPath);
   }
 
   Future tearDown() async {
@@ -931,4 +991,10 @@
       'workspaceEdit': {'documentChanges': true}
     });
   }
+
+  WorkspaceClientCapabilities withApplyEditSupport(
+    WorkspaceClientCapabilities source,
+  ) {
+    return extendWorkspaceCapabilities(source, {'applyEdit': true});
+  }
 }
diff --git a/pkg/analysis_server/test/lsp/signature_help_test.dart b/pkg/analysis_server/test/lsp/signature_help_test.dart
index e22eec0..b791ddd 100644
--- a/pkg/analysis_server/test/lsp/signature_help_test.dart
+++ b/pkg/analysis_server/test/lsp/signature_help_test.dart
@@ -122,6 +122,15 @@
     );
   }
 
+  test_nonDartFile() async {
+    await initialize(
+        textDocumentCapabilities: withSignatureHelpContentFormat(
+            emptyTextDocumentClientCapabilities, [MarkupKind.PlainText]));
+    await openFile(pubspecFileUri, simplePubspecContent);
+    final res = await getSignatureHelp(pubspecFileUri, startOfDocPos);
+    expect(res, isNull);
+  }
+
   test_params_multipleNamed() async {
     final content = '''
     /// Does foo.
@@ -253,6 +262,37 @@
     );
   }
 
+  test_dartDocMacro() async {
+    final content = '''
+    /// {@template template_name}
+    /// This is shared content.
+    /// {@endtemplate}
+    const String bar = null;
+
+    /// {@macro template_name}
+    foo(String s, int i) {
+      foo(^);
+    }
+    ''';
+    final expectedLabel = 'foo(String s, int i)';
+    final expectedDoc = 'This is shared content.';
+
+    final initialAnalysis = waitForAnalysisComplete();
+    await initialize();
+    await openFile(mainFileUri, withoutMarkers(content));
+    await initialAnalysis;
+    await testSignature(
+      content,
+      expectedLabel,
+      expectedDoc,
+      [
+        new ParameterInformation('String s', null),
+        new ParameterInformation('int i', null),
+      ],
+      expectedFormat: null,
+    );
+  }
+
   test_unopenFile() async {
     final content = '''
     /// Does foo.
diff --git a/pkg/analysis_server/test/lsp/test_all.dart b/pkg/analysis_server/test/lsp/test_all.dart
index 7c6ab34..54c5d7d 100644
--- a/pkg/analysis_server/test/lsp/test_all.dart
+++ b/pkg/analysis_server/test/lsp/test_all.dart
@@ -5,6 +5,7 @@
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import '../src/lsp/lsp_packet_transformer_test.dart' as lsp_packet_transformer;
+import 'analyzer_status_test.dart' as analyzer_status;
 import 'change_workspace_folders_test.dart' as change_workspace_folders;
 import 'code_actions_assists_test.dart' as code_actions_assists;
 import 'code_actions_fixes_test.dart' as code_actions_fixes;
@@ -18,7 +19,9 @@
 import 'folding_test.dart' as folding;
 import 'format_test.dart' as format;
 import 'hover_test.dart' as hover;
+import 'implementation_test.dart' as implementation;
 import 'initialization_test.dart' as initialization;
+import 'mapping_test.dart' as mapping;
 import 'priority_files_test.dart' as priority_files;
 import 'references_test.dart' as references;
 import 'rename_test.dart' as rename;
@@ -28,6 +31,7 @@
 
 main() {
   defineReflectiveSuite(() {
+    analyzer_status.main();
     change_workspace_folders.main();
     code_actions_assists.main();
     code_actions_fixes.main();
@@ -40,9 +44,11 @@
     file_modification.main();
     folding.main();
     format.main();
-    lsp_packet_transformer.main();
     hover.main();
+    implementation.main();
     initialization.main();
+    lsp_packet_transformer.main();
+    mapping.main();
     priority_files.main();
     references.main();
     rename.main();
diff --git a/pkg/analysis_server/test/protocol_server_test.dart b/pkg/analysis_server/test/protocol_server_test.dart
index b83902c..7bc7663 100644
--- a/pkg/analysis_server/test/protocol_server_test.dart
+++ b/pkg/analysis_server/test/protocol_server_test.dart
@@ -183,6 +183,7 @@
       engine.ElementKind.GENERIC_FUNCTION_TYPE: ElementKind.FUNCTION_TYPE_ALIAS,
       engine.ElementKind.IMPORT: ElementKind.UNKNOWN,
       engine.ElementKind.NAME: ElementKind.UNKNOWN,
+      engine.ElementKind.NEVER: ElementKind.UNKNOWN,
       engine.ElementKind.UNIVERSE: ElementKind.UNKNOWN
     });
   }
diff --git a/pkg/analysis_server/test/services/completion/dart/variable_name_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/variable_name_contributor_test.dart
index 2d776e06..ed57fbe 100644
--- a/pkg/analysis_server/test/services/completion/dart/variable_name_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/variable_name_contributor_test.dart
@@ -42,7 +42,28 @@
     assertNotSuggested('a');
   }
 
-  test_ExpressionStatement_long() async {
+  test_ExpressionStatement_inConstructorBody() async {
+    addTestSource('''
+    class A { A() { AbstractCrazyNonsenseClassName ^ } }
+    ''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestName('abstractCrazyNonsenseClassName');
+    assertSuggestName('crazyNonsenseClassName');
+    assertSuggestName('nonsenseClassName');
+    assertSuggestName('className');
+    assertSuggestName('name');
+    // private versions aren't provided as this completion is in a constructor
+    // body
+    assertNotSuggested('_abstractCrazyNonsenseClassName');
+    assertNotSuggested('_crazyNonsenseClassName');
+    assertNotSuggested('_nonsenseClassName');
+    assertNotSuggested('_className');
+    assertNotSuggested('_name');
+  }
+
+  test_ExpressionStatement_inFunctionBody() async {
     addTestSource('''
     f() { AbstractCrazyNonsenseClassName ^ }
     ''');
@@ -54,7 +75,27 @@
     assertSuggestName('nonsenseClassName');
     assertSuggestName('className');
     assertSuggestName('name');
-    // private versions
+    // private versions aren't provided as this completion is in a function body
+    assertNotSuggested('_abstractCrazyNonsenseClassName');
+    assertNotSuggested('_crazyNonsenseClassName');
+    assertNotSuggested('_nonsenseClassName');
+    assertNotSuggested('_className');
+    assertNotSuggested('_name');
+  }
+
+  test_ExpressionStatement_inMethodBody() async {
+    addTestSource('''
+    class A { f() { AbstractCrazyNonsenseClassName ^ } }
+    ''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestName('abstractCrazyNonsenseClassName');
+    assertSuggestName('crazyNonsenseClassName');
+    assertSuggestName('nonsenseClassName');
+    assertSuggestName('className');
+    assertSuggestName('name');
+    // private versions aren't provided as this completion is in a method body
     assertNotSuggested('_abstractCrazyNonsenseClassName');
     assertNotSuggested('_crazyNonsenseClassName');
     assertNotSuggested('_nonsenseClassName');
@@ -146,6 +187,88 @@
     assertNotSuggested('_a');
   }
 
+  @failingTest
+  test_ForStatement() async {
+    addTestSource('''
+    f() { for(AbstractCrazyNonsenseClassName ^) {} }
+    ''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestName('abstractCrazyNonsenseClassName');
+    assertSuggestName('crazyNonsenseClassName');
+    assertSuggestName('nonsenseClassName');
+    assertSuggestName('className');
+    assertSuggestName('name');
+    // private versions
+    assertNotSuggested('_abstractCrazyNonsenseClassName');
+    assertNotSuggested('_crazyNonsenseClassName');
+    assertNotSuggested('_nonsenseClassName');
+    assertNotSuggested('_className');
+    assertNotSuggested('_name');
+  }
+
+  test_ForStatement_partial() async {
+    addTestSource('''
+    f() { for(AbstractCrazyNonsenseClassName a^) {} }
+    ''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertSuggestName('abstractCrazyNonsenseClassName');
+    assertSuggestName('crazyNonsenseClassName');
+    assertSuggestName('nonsenseClassName');
+    assertSuggestName('className');
+    assertSuggestName('name');
+    // private versions
+    assertNotSuggested('_abstractCrazyNonsenseClassName');
+    assertNotSuggested('_crazyNonsenseClassName');
+    assertNotSuggested('_nonsenseClassName');
+    assertNotSuggested('_className');
+    assertNotSuggested('_name');
+  }
+
+  @failingTest
+  test_ForStatement_prefixed() async {
+    addTestSource('''
+    f() { for(prefix.AbstractCrazyNonsenseClassName ^) {} }
+    ''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertSuggestName('abstractCrazyNonsenseClassName');
+    assertSuggestName('crazyNonsenseClassName');
+    assertSuggestName('nonsenseClassName');
+    assertSuggestName('className');
+    assertSuggestName('name');
+    // private versions
+    assertNotSuggested('_abstractCrazyNonsenseClassName');
+    assertNotSuggested('_crazyNonsenseClassName');
+    assertNotSuggested('_nonsenseClassName');
+    assertNotSuggested('_className');
+    assertNotSuggested('_name');
+  }
+
+  test_ForStatement_prefixed_partial() async {
+    addTestSource('''
+    f() { for(prefix.AbstractCrazyNonsenseClassName a^) {} }
+    ''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertSuggestName('abstractCrazyNonsenseClassName');
+    assertSuggestName('crazyNonsenseClassName');
+    assertSuggestName('nonsenseClassName');
+    assertSuggestName('className');
+    assertSuggestName('name');
+    // private versions
+    assertNotSuggested('_abstractCrazyNonsenseClassName');
+    assertNotSuggested('_crazyNonsenseClassName');
+    assertNotSuggested('_nonsenseClassName');
+    assertNotSuggested('_className');
+    assertNotSuggested('_name');
+  }
+
   test_TopLevelVariableDeclaration_dont_suggest_type() async {
     addTestSource('''
     a ^
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 61c133d..b143f73 100644
--- a/pkg/analysis_server/test/src/nullability/migration_visitor_test.dart
+++ b/pkg/analysis_server/test/src/nullability/migration_visitor_test.dart
@@ -7,10 +7,8 @@
 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_graph.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';
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/source.dart';
@@ -29,62 +27,38 @@
 
 @reflectiveTest
 class ConstraintGathererTest extends ConstraintsTestBase {
-  @override
-  final _Constraints constraints = _Constraints();
-
-  @override
-  final graph = NullabilityGraph();
-
   void assertConditional(
       NullabilityNode node, NullabilityNode left, NullabilityNode right) {
     var conditionalNode = node as NullabilityNodeForLUB;
     expect(conditionalNode.left, same(left));
     expect(conditionalNode.right, same(right));
-    if (left.isNeverNullable) {
-      if (right.isNeverNullable) {
-        expect(conditionalNode.isNeverNullable, true);
-      } else {
-        expect(conditionalNode.nullable, same(right.nullable));
-      }
-    } else {
-      if (right.isNeverNullable) {
-        expect(conditionalNode.nullable, same(left.nullable));
-      } else {
-        assertConstraint([left.nullable], conditionalNode.nullable);
-        assertConstraint([right.nullable], conditionalNode.nullable);
-      }
-    }
   }
 
-  /// Checks that a constraint was recorded with a left hand side of
-  /// [conditions] and a right hand side of [consequence].
-  void assertConstraint(
-      Iterable<ConstraintVariable> conditions, ConstraintVariable consequence) {
-    expect(constraints._clauses,
-        contains(_Clause(conditions.toSet(), consequence)));
-  }
-
-  /// Checks that no constraint was recorded with a right hand side of
-  /// [consequence].
-  void assertNoConstraints(ConstraintVariable consequence) {
-    expect(
-        constraints._clauses,
-        isNot(contains(
-            predicate((_Clause clause) => clause.consequence == consequence))));
+  /// Checks that there is a connection from [sourceNode] to [destinationNode].
+  void assertConnection(
+      NullabilityNode sourceNode, NullabilityNode destinationNode) {
+    expect(graph.getDownstreamNodes(sourceNode).toList(),
+        contains(destinationNode));
   }
 
   void assertNonNullIntent(NullabilityNode node, bool expected) {
     if (expected) {
-      assertConstraint([], node.nonNullIntent);
+      expect(graph.getUnconditionalUpstreamNodes(NullabilityNode.never),
+          contains(node));
     } else {
-      assertNoConstraints(node.nonNullIntent);
+      expect(graph.getUnconditionalUpstreamNodes(NullabilityNode.never),
+          isNot(contains(node)));
     }
   }
 
   /// Checks that there are no nullability nodes upstream from [node] that could
   /// cause it to become nullable.
   void assertNoUpstreamNullability(NullabilityNode node) {
-    for (var upstreamNode in graph.getUpstreamNodes(node)) {
+    // NullabilityNode.never can never become nullable, even if it has nodes
+    // upstream from it.
+    if (node == NullabilityNode.never) return;
+
+    for (var upstreamNode in graph.getUpstreamNodesForTesting(node)) {
       expect(upstreamNode, NullabilityNode.never);
     }
   }
@@ -128,10 +102,7 @@
   test_always() async {
     await analyze('');
 
-    // No clause is needed for `always`; it is assigned the value `true` before
-    // solving begins.
-    assertNoConstraints(ConstraintVariable.always);
-    assert(ConstraintVariable.always.value, isTrue);
+    expect(NullabilityNode.always.isNullable, isTrue);
   }
 
   test_assert_demonstrates_non_null_intent() async {
@@ -264,7 +235,7 @@
     var nullable_conditional =
         decoratedExpressionType('(b ?').node as NullabilityNodeForLUB;
     var nullable_throw = nullable_conditional.left;
-    expect(nullable_throw.isNeverNullable, true);
+    assertNoUpstreamNullability(nullable_throw);
     assertConditional(nullable_conditional, nullable_throw, nullable_i);
   }
 
@@ -275,8 +246,9 @@
 }
 ''');
 
+    var nullable_i = decoratedTypeAnnotation('int i').node;
     var nullable_conditional = decoratedExpressionType('(b ?').node;
-    expect(nullable_conditional.isAlwaysNullable, true);
+    assertConditional(nullable_conditional, NullabilityNode.always, nullable_i);
   }
 
   test_conditionalExpression_right_non_null() async {
@@ -290,7 +262,7 @@
     var nullable_conditional =
         decoratedExpressionType('(b ?').node as NullabilityNodeForLUB;
     var nullable_throw = nullable_conditional.right;
-    expect(nullable_throw.isNeverNullable, true);
+    assertNoUpstreamNullability(nullable_throw);
     assertConditional(nullable_conditional, nullable_i, nullable_throw);
   }
 
@@ -301,8 +273,9 @@
 }
 ''');
 
+    var nullable_i = decoratedTypeAnnotation('int i').node;
     var nullable_conditional = decoratedExpressionType('(b ?').node;
-    expect(nullable_conditional.isAlwaysNullable, true);
+    assertConditional(nullable_conditional, nullable_i, NullabilityNode.always);
   }
 
   test_functionDeclaration_expression_body() async {
@@ -328,8 +301,8 @@
 void f({int i = null}) {}
 ''');
 
-    assertConstraint([ConstraintVariable.always],
-        decoratedTypeAnnotation('int').node.nullable);
+    assertConnection(
+        NullabilityNode.always, decoratedTypeAnnotation('int').node);
   }
 
   test_functionDeclaration_parameter_named_no_default_assume_nullable() async {
@@ -340,8 +313,8 @@
             namedNoDefaultParameterHeuristic:
                 NamedNoDefaultParameterHeuristic.assumeNullable));
 
-    assertConstraint([ConstraintVariable.always],
-        decoratedTypeAnnotation('int').node.nullable);
+    assertConnection(
+        NullabilityNode.always, decoratedTypeAnnotation('int').node);
   }
 
   test_functionDeclaration_parameter_named_no_default_assume_required() async {
@@ -394,8 +367,8 @@
 void f([int i = null]) {}
 ''');
 
-    assertConstraint([ConstraintVariable.always],
-        decoratedTypeAnnotation('int').node.nullable);
+    assertConnection(
+        NullabilityNode.always, decoratedTypeAnnotation('int').node);
   }
 
   test_functionDeclaration_parameter_positionalOptional_no_default() async {
@@ -403,8 +376,8 @@
 void f([int i]) {}
 ''');
 
-    assertConstraint([ConstraintVariable.always],
-        decoratedTypeAnnotation('int').node.nullable);
+    assertConnection(
+        NullabilityNode.always, decoratedTypeAnnotation('int').node);
   }
 
   test_functionDeclaration_parameter_positionalOptional_no_default_assume_required() async {
@@ -417,8 +390,8 @@
             namedNoDefaultParameterHeuristic:
                 NamedNoDefaultParameterHeuristic.assumeRequired));
 
-    assertConstraint([ConstraintVariable.always],
-        decoratedTypeAnnotation('int').node.nullable);
+    assertConnection(
+        NullabilityNode.always, decoratedTypeAnnotation('int').node);
   }
 
   test_functionDeclaration_resets_unconditional_control_flow() async {
@@ -449,7 +422,8 @@
     var int_2 = decoratedTypeAnnotation('int/*2*/');
     var i_3 = checkExpression('i/*3*/');
     assertNullCheck(i_3, int_2.node, contextNode: int_1.node);
-    assertConstraint([int_1.node.nonNullIntent], int_2.node.nonNullIntent);
+    expect(
+        graph.getUnconditionalUpstreamNodes(int_1.node), contains(int_2.node));
   }
 
   test_functionInvocation_parameter_named() async {
@@ -473,7 +447,7 @@
 }
 ''');
     var optional_i = possiblyOptionalParameter('int i');
-    assertConstraint([], optional_i.nullable);
+    assertConnection(NullabilityNode.always, optional_i);
   }
 
   test_functionInvocation_parameter_named_missing_required() async {
@@ -675,8 +649,8 @@
 }
 ''');
 
-    assertConstraint([decoratedTypeAnnotation('int/*3*/').node.nullable],
-        decoratedTypeAnnotation('int/*1*/').node.nullable);
+    assertConnection(decoratedTypeAnnotation('int/*3*/').node,
+        decoratedTypeAnnotation('int/*1*/').node);
     assertNullCheck(checkExpression('c/*check*/'),
         decoratedTypeAnnotation('C<int/*3*/>/*4*/').node,
         contextNode: decoratedTypeAnnotation('C<int/*1*/>/*2*/').node);
@@ -724,6 +698,12 @@
     assertNonNullIntent(decoratedTypeAnnotation('C c').node, true);
   }
 
+  test_never() async {
+    await analyze('');
+
+    expect(NullabilityNode.never.isNullable, isFalse);
+  }
+
   test_parenthesizedExpression() async {
     await analyze('''
 int f() {
@@ -743,8 +723,8 @@
 }
 ''');
 
-    assertConstraint([ConstraintVariable.always],
-        decoratedTypeAnnotation('int').node.nullable);
+    assertConnection(
+        NullabilityNode.always, decoratedTypeAnnotation('int').node);
   }
 
   test_return_null() async {
@@ -787,6 +767,15 @@
     assertNoUpstreamNullability(decoratedTypeAnnotation('int').node);
   }
 
+  test_type_argument_explicit_bound() async {
+    await analyze('''
+class C<T extends Object> {}
+void f(C<int> c) {}
+''');
+    assertConnection(decoratedTypeAnnotation('int>').node,
+        decoratedTypeAnnotation('Object>').node);
+  }
+
   test_typeName() async {
     await analyze('''
 Type f() {
@@ -798,10 +787,6 @@
 }
 
 abstract class ConstraintsTestBase extends MigrationVisitorTestBase {
-  Constraints get constraints;
-
-  NullabilityGraph get graph;
-
   /// Analyzes the given source code, producing constraint variables and
   /// constraints for it.
   @override
@@ -809,8 +794,8 @@
       {NullabilityMigrationAssumptions assumptions:
           const NullabilityMigrationAssumptions()}) async {
     var unit = await super.analyze(code);
-    unit.accept(ConstraintGatherer(typeProvider, _variables, constraints, graph,
-        testSource, false, assumptions));
+    unit.accept(ConstraintGatherer(
+        typeProvider, _variables, graph, testSource, false, assumptions));
     return unit;
   }
 }
@@ -823,18 +808,8 @@
       _variables.decoratedElementType(
           findNode.functionDeclaration(search).declaredElement);
 
-  @failingTest
-  test_interfaceType_nullable() async {
-    // The tests are now being run without enabling nnbd, which causes the '?'
-    // to be reported as an error.
-    await analyze('''
-void f(int? x) {}
-''');
-    var decoratedType = decoratedTypeAnnotation('int?');
-    expect(decoratedFunctionType('f').positionalParameters[0],
-        same(decoratedType));
-    expect(decoratedType.node.nullable, same(ConstraintVariable.always));
-  }
+  DecoratedType decoratedTypeParameterBound(String search) => _variables
+      .decoratedElementType(findNode.typeParameter(search).declaredElement);
 
   test_interfaceType_typeParameter() async {
     await analyze('''
@@ -843,10 +818,12 @@
     var decoratedListType = decoratedTypeAnnotation('List<int>');
     expect(decoratedFunctionType('f').positionalParameters[0],
         same(decoratedListType));
-    expect(decoratedListType.node.nullable, isNotNull);
+    expect(decoratedListType.node, isNotNull);
+    expect(decoratedListType.node, isNot(NullabilityNode.never));
     var decoratedIntType = decoratedTypeAnnotation('int');
     expect(decoratedListType.typeArguments[0], same(decoratedIntType));
-    expect(decoratedIntType.node.nullable, isNotNull);
+    expect(decoratedIntType.node, isNotNull);
+    expect(decoratedIntType.node, isNot(NullabilityNode.never));
   }
 
   test_topLevelFunction_parameterType_implicit_dynamic() async {
@@ -858,7 +835,8 @@
     expect(decoratedFunctionType('f').positionalParameters[0],
         same(decoratedType));
     expect(decoratedType.type.isDynamic, isTrue);
-    expect(decoratedType.node.nullable, same(ConstraintVariable.always));
+    expect(graph.getUpstreamNodesForTesting(decoratedType.node),
+        contains(NullabilityNode.always));
   }
 
   test_topLevelFunction_parameterType_named_no_default() async {
@@ -868,8 +846,9 @@
     var decoratedType = decoratedTypeAnnotation('String');
     var functionType = decoratedFunctionType('f');
     expect(functionType.namedParameters['s'], same(decoratedType));
-    expect(decoratedType.node.nullable, isNotNull);
-    expect(decoratedType.node.nullable, isNot(same(ConstraintVariable.always)));
+    expect(decoratedType.node, isNotNull);
+    expect(decoratedType.node, isNot(NullabilityNode.never));
+    expect(decoratedType.node, isNot(NullabilityNode.always));
     expect(functionType.namedParameters['s'].node.isPossiblyOptional, true);
   }
 
@@ -882,8 +861,9 @@
     var decoratedType = decoratedTypeAnnotation('String');
     var functionType = decoratedFunctionType('f');
     expect(functionType.namedParameters['s'], same(decoratedType));
-    expect(decoratedType.node.nullable, isNotNull);
-    expect(decoratedType.node.nullable, isNot(same(ConstraintVariable.always)));
+    expect(decoratedType.node, isNotNull);
+    expect(decoratedType.node, isNot(NullabilityNode.never));
+    expect(decoratedType.node, isNot(NullabilityNode.always));
     expect(functionType.namedParameters['s'].node.isPossiblyOptional, false);
   }
 
@@ -894,7 +874,8 @@
     var decoratedType = decoratedTypeAnnotation('String');
     var functionType = decoratedFunctionType('f');
     expect(functionType.namedParameters['s'], same(decoratedType));
-    expect(decoratedType.node.nullable, isNotNull);
+    expect(decoratedType.node, isNotNull);
+    expect(decoratedType.node, isNot(NullabilityNode.never));
     expect(functionType.namedParameters['s'].node.isPossiblyOptional, false);
   }
 
@@ -905,7 +886,8 @@
     var decoratedType = decoratedTypeAnnotation('int');
     expect(decoratedFunctionType('f').positionalParameters[0],
         same(decoratedType));
-    expect(decoratedType.node.nullable, isNotNull);
+    expect(decoratedType.node, isNotNull);
+    expect(decoratedType.node, isNot(NullabilityNode.never));
   }
 
   test_topLevelFunction_parameterType_simple() async {
@@ -915,8 +897,8 @@
     var decoratedType = decoratedTypeAnnotation('int');
     expect(decoratedFunctionType('f').positionalParameters[0],
         same(decoratedType));
-    expect(decoratedType.node.nullable, isNotNull);
-    expect(decoratedType.node.nonNullIntent, isNotNull);
+    expect(decoratedType.node, isNotNull);
+    expect(decoratedType.node, isNot(NullabilityNode.never));
   }
 
   test_topLevelFunction_returnType_implicit_dynamic() async {
@@ -925,7 +907,8 @@
 ''');
     var decoratedType = decoratedFunctionType('f').returnType;
     expect(decoratedType.type.isDynamic, isTrue);
-    expect(decoratedType.node.nullable, same(ConstraintVariable.always));
+    expect(graph.getUpstreamNodesForTesting(decoratedType.node),
+        contains(NullabilityNode.always));
   }
 
   test_topLevelFunction_returnType_simple() async {
@@ -934,23 +917,53 @@
 ''');
     var decoratedType = decoratedTypeAnnotation('int');
     expect(decoratedFunctionType('f').returnType, same(decoratedType));
-    expect(decoratedType.node.nullable, isNotNull);
+    expect(decoratedType.node, isNotNull);
+    expect(decoratedType.node, isNot(NullabilityNode.never));
+  }
+
+  test_type_parameter_explicit_bound() async {
+    await analyze('''
+class C<T extends Object> {}
+''');
+    var bound = decoratedTypeParameterBound('T');
+    expect(decoratedTypeAnnotation('Object'), same(bound));
+    expect(bound.node, isNot(NullabilityNode.always));
+    expect(bound.type, typeProvider.objectType);
+  }
+
+  test_type_parameter_implicit_bound() async {
+    // The implicit bound of `T` is automatically `Object?`.  TODO(paulberry):
+    // consider making it possible for type inference to infer an explicit bound
+    // of `Object`.
+    await analyze('''
+class C<T> {}
+''');
+    var bound = decoratedTypeParameterBound('T');
+    expect(graph.getUnconditionalUpstreamNodes(bound.node),
+        contains(NullabilityNode.always));
+    expect(bound.type, same(typeProvider.objectType));
   }
 }
 
 class MigrationVisitorTestBase extends AbstractSingleUnitTest {
-  final _variables = _Variables();
+  final _Variables _variables;
 
   FindNode findNode;
 
+  final NullabilityGraph graph;
+
+  MigrationVisitorTestBase() : this._(NullabilityGraph());
+
+  MigrationVisitorTestBase._(this.graph) : _variables = _Variables(graph);
+
   TypeProvider get typeProvider => testAnalysisResult.typeProvider;
 
   Future<CompilationUnit> analyze(String code,
       {NullabilityMigrationAssumptions assumptions:
           const NullabilityMigrationAssumptions()}) async {
     await resolveTestUnit(code);
-    testUnit.accept(
-        ConstraintVariableGatherer(_variables, testSource, false, assumptions));
+    testUnit.accept(ConstraintVariableGatherer(
+        _variables, testSource, false, assumptions, graph, typeProvider));
     findNode = FindNode(code, testUnit);
     return testUnit;
   }
@@ -958,7 +971,8 @@
   /// Gets the [DecoratedType] associated with the type annotation whose text
   /// is [text].
   DecoratedType decoratedTypeAnnotation(String text) {
-    return _variables.decoratedTypeAnnotation(findNode.typeAnnotation(text));
+    return _variables.decoratedTypeAnnotation(
+        testSource, findNode.typeAnnotation(text));
   }
 
   NullabilityNode possiblyOptionalParameter(String text) {
@@ -973,64 +987,18 @@
   }
 }
 
-/// Mock representation of a constraint equation that is not connected to a
-/// constraint solver.  We use this to confirm that analysis produces the
-/// correct constraint equations.
-///
-/// [hashCode] and equality are implemented using [toString] for simplicity.
-class _Clause {
-  final Set<ConstraintVariable> conditions;
-  final ConstraintVariable consequence;
-
-  _Clause(this.conditions, this.consequence);
-
-  @override
-  int get hashCode => toString().hashCode;
-
-  @override
-  bool operator ==(Object other) =>
-      other is _Clause && toString() == other.toString();
-
-  @override
-  String toString() {
-    String lhs;
-    if (conditions.isNotEmpty) {
-      var sortedConditionStrings = conditions.map((v) => v.toString()).toList()
-        ..sort();
-      lhs = sortedConditionStrings.join(' & ') + ' => ';
-    } else {
-      lhs = '';
-    }
-    String rhs = consequence.toString();
-    return lhs + rhs;
-  }
-}
-
-/// Mock representation of a constraint solver that does not actually do any
-/// solving.  We use this to confirm that analysis produced the correct
-/// constraint equations.
-class _Constraints extends Constraints {
-  final _clauses = <_Clause>[];
-
-  @override
-  void record(
-      Iterable<ConstraintVariable> conditions, ConstraintVariable consequence) {
-    _clauses.add(_Clause(conditions.toSet(), consequence));
-  }
-}
-
 /// Mock representation of constraint variables.
 class _Variables extends Variables {
   final _conditionalDiscard = <AstNode, ConditionalDiscard>{};
 
   final _decoratedExpressionTypes = <Expression, DecoratedType>{};
 
-  final _decoratedTypeAnnotations = <TypeAnnotation, DecoratedType>{};
-
   final _expressionChecks = <Expression, ExpressionChecks>{};
 
   final _possiblyOptional = <DefaultFormalParameter, NullabilityNode>{};
 
+  _Variables(NullabilityGraph graph) : super(graph);
+
   /// Gets the [ExpressionChecks] associated with the given [expression].
   ExpressionChecks checkExpression(Expression expression) =>
       _expressionChecks[_normalizeExpression(expression)];
@@ -1043,10 +1011,6 @@
   DecoratedType decoratedExpressionType(Expression expression) =>
       _decoratedExpressionTypes[_normalizeExpression(expression)];
 
-  /// Gets the [DecoratedType] associated with the given [typeAnnotation].
-  DecoratedType decoratedTypeAnnotation(TypeAnnotation typeAnnotation) =>
-      _decoratedTypeAnnotations[typeAnnotation];
-
   /// Gets the [NullabilityNode] associated with the possibility that
   /// [parameter] may be optional.
   NullabilityNode possiblyOptionalParameter(DefaultFormalParameter parameter) =>
@@ -1064,12 +1028,6 @@
     _decoratedExpressionTypes[_normalizeExpression(node)] = type;
   }
 
-  void recordDecoratedTypeAnnotation(
-      Source source, TypeAnnotation node, DecoratedType type) {
-    super.recordDecoratedTypeAnnotation(source, node, type);
-    _decoratedTypeAnnotations[node] = type;
-  }
-
   @override
   void recordExpressionChecks(
       Source source, Expression expression, ExpressionChecks checks) {
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 d96f84d..8a4bb19 100644
--- a/pkg/analysis_server/test/src/nullability/provisional_api_test.dart
+++ b/pkg/analysis_server/test/src/nullability/provisional_api_test.dart
@@ -231,37 +231,6 @@
     await _checkSingleFileChanges(content, expected);
   }
 
-  test_data_flow_generic_inward_hint() async {
-    var content = '''
-class C<T> {
-  void f(T? t) {}
-}
-void g(C<int> c, int i) {
-  c.f(i);
-}
-void test(C<int> c) {
-  g(c, null);
-}
-''';
-
-    // The user may override the behavior shown in test_data_flow_generic_inward
-    // by explicitly marking f's use of T as nullable.  Since this makes g's
-    // call to f valid regardless of the type of c, c's type will remain
-    // C<int>.
-    var expected = '''
-class C<T> {
-  void f(T? t) {}
-}
-void g(C<int> c, int? i) {
-  c.f(i);
-}
-void test(C<int> c) {
-  g(c, null);
-}
-''';
-    await _checkSingleFileChanges(content, expected);
-  }
-
   test_data_flow_inward() async {
     var content = '''
 int f(int i) => 0;
@@ -793,6 +762,34 @@
         {path1: file1, path2: file2}, {path1: expected1, path2: expected2});
   }
 
+  test_type_argument_flows_to_bound() async {
+    // The inference of C<int?> forces class C to be declared as
+    // C<T extends Object?>.
+    var content = '''
+class C<T extends Object> {
+  void m(T t);
+}
+class D<T extends Object> {
+  void m(T t);
+}
+f(C<int> c, D<int> d) {
+  c.m(null);
+}
+''';
+    var expected = '''
+class C<T extends Object?> {
+  void m(T t);
+}
+class D<T extends Object> {
+  void m(T t);
+}
+f(C<int?> c, D<int> d) {
+  c.m(null);
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
   test_unconditional_assert_statement_implies_non_null_intent() async {
     var content = '''
 void f(int i) {
diff --git a/pkg/analysis_server/test/src/nullability/test_all.dart b/pkg/analysis_server/test/src/nullability/test_all.dart
index 77b5187..c43a34f 100644
--- a/pkg/analysis_server/test/src/nullability/test_all.dart
+++ b/pkg/analysis_server/test/src/nullability/test_all.dart
@@ -6,12 +6,10 @@
 
 import 'migration_visitor_test.dart' as migration_visitor_test;
 import 'provisional_api_test.dart' as provisional_api_test;
-import 'unit_propagation_test.dart' as unit_propagation_test;
 
 main() {
   defineReflectiveSuite(() {
     migration_visitor_test.main();
     provisional_api_test.main();
-    unit_propagation_test.main();
   });
 }
diff --git a/pkg/analysis_server/test/src/nullability/unit_propagation_test.dart b/pkg/analysis_server/test/src/nullability/unit_propagation_test.dart
deleted file mode 100644
index d2fcf89..0000000
--- a/pkg/analysis_server/test/src/nullability/unit_propagation_test.dart
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:analysis_server/src/nullability/unit_propagation.dart';
-import 'package:test/test.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-main() {
-  defineReflectiveSuite(() {
-    defineReflectiveTests(UnitPropagationTest);
-  });
-}
-
-/// TODO(paulberry): write more tests
-@reflectiveTest
-class UnitPropagationTest {
-  var solver = Solver();
-
-  ConstraintVariable newVar(String name) => _NamedConstraintVariable(name);
-
-  test_record_copies_conditions() {
-    var a = newVar('a');
-    var b = newVar('b');
-    var conditions = [a];
-    solver.record(conditions, b);
-    conditions.removeLast();
-    expect(a.value, false);
-    expect(b.value, false);
-    solver.record([], a);
-    expect(a.value, true);
-    expect(b.value, true);
-  }
-
-  test_record_propagates_true_variables_immediately() {
-    var a = newVar('a');
-    expect(a.value, false);
-    solver.record([], a);
-    expect(a.value, true);
-    var b = newVar('b');
-    expect(b.value, false);
-    solver.record([a], b);
-    expect(b.value, true);
-  }
-}
-
-/// Representation of a constraint variable with a specified name.
-///
-/// This makes test failures easier to comprehend.
-class _NamedConstraintVariable extends ConstraintVariable {
-  final String _name;
-
-  _NamedConstraintVariable(this._name);
-
-  @override
-  String toString() => _name;
-}
diff --git a/pkg/analysis_server/test/src/services/correction/assist/convert_into_absolute_import_test.dart b/pkg/analysis_server/test/src/services/correction/assist/convert_to_package_import_test.dart
similarity index 72%
rename from pkg/analysis_server/test/src/services/correction/assist/convert_into_absolute_import_test.dart
rename to pkg/analysis_server/test/src/services/correction/assist/convert_to_package_import_test.dart
index 36e3fab..84df167 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/convert_into_absolute_import_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/convert_to_package_import_test.dart
@@ -10,25 +10,14 @@
 
 main() {
   defineReflectiveSuite(() {
-    defineReflectiveTests(ConvertIntoAbsoluteImportTest);
+    defineReflectiveTests(ConvertToPackageImportTest);
   });
 }
 
 @reflectiveTest
-class ConvertIntoAbsoluteImportTest extends AssistProcessorTest {
+class ConvertToPackageImportTest extends AssistProcessorTest {
   @override
-  AssistKind get kind => DartAssistKind.CONVERT_INTO_ABSOLUTE_IMPORT;
-
-  test_fileName_onUri() async {
-    addSource('/home/test/lib/foo.dart', '');
-
-    await resolveTestUnit('''
-import 'foo.dart';
-''');
-    await assertHasAssistAt('foo.dart', '''
-import 'package:test/foo.dart';
-''');
-  }
+  AssistKind get kind => DartAssistKind.CONVERT_TO_PACKAGE_IMPORT;
 
   test_fileName_onImport() async {
     addSource('/home/test/lib/foo.dart', '');
@@ -42,6 +31,25 @@
 ''');
   }
 
+  test_fileName_onUri() async {
+    addSource('/home/test/lib/foo.dart', '');
+
+    await resolveTestUnit('''
+import 'foo.dart';
+''');
+    await assertHasAssistAt('foo.dart', '''
+import 'package:test/foo.dart';
+''');
+  }
+
+  test_invalidUri() async {
+    verifyNoTestUnitErrors = false;
+    await resolveTestUnit('''
+import ':[invalidUri]';
+''');
+    await assertNoAssistAt('invalid');
+  }
+
   test_nonPackage_Uri() async {
     addSource('/home/test/lib/foo.dart', '');
 
@@ -53,6 +61,16 @@
     await assertNoAssistAt('import');
   }
 
+  test_packageUri() async {
+    addSource('/home/test/lib/foo.dart', '');
+
+    await resolveTestUnit('''
+import 'package:test/foo.dart';
+''');
+    await assertNoAssistAt('foo.dart');
+    await assertNoAssistAt('import');
+  }
+
   test_path() async {
     addSource('/home/test/lib/foo/bar.dart', '');
 
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 bc906ab..d76f97b 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
@@ -11,7 +11,6 @@
     as convert_documentation_into_block;
 import 'convert_documentation_into_line_test.dart'
     as convert_documentation_into_line;
-import 'convert_into_absolute_import_test.dart' as convert_into_absolute_import;
 import 'convert_into_async_body_test.dart' as convert_into_async_body;
 import 'convert_into_block_body_test.dart' as convert_into_block_body;
 import 'convert_into_expression_body_test.dart' as convert_into_expression_body;
@@ -34,6 +33,7 @@
 import 'convert_to_multiline_string_test.dart' as convert_to_multiline_string;
 import 'convert_to_normal_parameter_test.dart' as convert_to_normal_parameter;
 import 'convert_to_null_aware_test.dart' as convert_to_null_aware;
+import 'convert_to_package_import_test.dart' as convert_to_package_import;
 import 'convert_to_set_literal_test.dart' as convert_to_set_literal;
 import 'convert_to_single_quoted_string_test.dart'
     as convert_to_single_quoted_string;
@@ -85,7 +85,6 @@
     convert_class_to_mixin.main();
     convert_documentation_into_block.main();
     convert_documentation_into_line.main();
-    convert_into_absolute_import.main();
     convert_into_async_body.main();
     convert_into_block_body.main();
     convert_into_expression_body.main();
@@ -106,6 +105,7 @@
     convert_to_multiline_string.main();
     convert_to_normal_parameter.main();
     convert_to_null_aware.main();
+    convert_to_package_import.main();
     convert_to_set_literal.main();
     convert_to_single_quoted_string.main();
     convert_to_spread.main();
diff --git a/pkg/analysis_server/test/tool/lsp_spec/typescript_test.dart b/pkg/analysis_server/test/tool/lsp_spec/typescript_test.dart
index f100429..e3e874e 100644
--- a/pkg/analysis_server/test/tool/lsp_spec/typescript_test.dart
+++ b/pkg/analysis_server/test/tool/lsp_spec/typescript_test.dart
@@ -125,7 +125,7 @@
 	/**
 	 * The method's params.
 	 */
-	params?: Array<any> | object;
+	params?: Array<any> | string;
 }
     ''';
       final List<AstNode> output = parseString(input);
@@ -143,7 +143,7 @@
       UnionType union = field.type;
       expect(union.types, hasLength(2));
       expect(union.types[0], isArrayOf(isSimpleType('any')));
-      expect(union.types[1], isSimpleType('object'));
+      expect(union.types[1], isSimpleType('string'));
     });
 
     test('parses an interface with a map into a MapType', () {
@@ -304,5 +304,22 @@
       expect(union.types[0], isSimpleType('string'));
       expect(union.types[1], isArrayOf(isSimpleType('number')));
     });
+
+    test('parses an union including Object into a single type', () {
+      final String input = '''
+interface SomeInformation {
+	label: string | object;
+}
+    ''';
+      final List<AstNode> output = parseString(input);
+      expect(output, hasLength(1));
+      expect(output[0], const TypeMatcher<Interface>());
+      final Interface interface = output[0];
+      expect(interface.members, hasLength(1));
+      final Field field = interface.members.first;
+      expect(field, const TypeMatcher<Field>());
+      expect(field.name, equals('label'));
+      expect(field.type, isSimpleType('object'));
+    });
   });
 }
diff --git a/pkg/analysis_server/tool/lsp_spec/README.md b/pkg/analysis_server/tool/lsp_spec/README.md
index f5420ac..5cfc02b 100644
--- a/pkg/analysis_server/tool/lsp_spec/README.md
+++ b/pkg/analysis_server/tool/lsp_spec/README.md
@@ -16,7 +16,12 @@
 
 Note: In LSP the client makes the first request so there is no obvious confirmation that the server is working correctly until the client sends an `initialize` request. Unlike standard JSON RPC, [LSP requires that headers are sent](https://microsoft.github.io/language-server-protocol/specification).
 
-## Message Status
+## Initialization Options
+
+- `onlyAnalyzeProjectsWithOpenFiles`: When set to `true`, analysis will only be performed for projects that have open files rather than the root workspace folder. Defaults to `false`.
+- `suggestFromUnimportedLibraries`: When set to `false`, completion will not include synbols that are not already imported into the current file. Defaults to `true`, though the client must additionally support `workspace/applyEdit` for these completions to be included.
+
+## Method Status
 
 Below is a list of LSP methods and their implementation status.
 
@@ -59,7 +64,7 @@
 | textDocument/declaration | | | | |
 | textDocument/definition | ✅ | ✅ | ✅ | ✅ |
 | textDocument/typeDefinition | | | | |
-| textDocument/implementation | | | | |
+| textDocument/implementation | ✅ | ✅ | ✅ | ✅ |
 | textDocument/references | ✅ | ✅ | ✅ | ✅ |
 | textDocument/documentHighlight | ✅ | ✅ | ✅ | ✅ |
 | textDocument/documentSymbol | ✅ | ✅ | ✅ | ✅ |
@@ -81,4 +86,21 @@
 | textDocument/prepareRename | | | | |
 | textDocument/foldingRange | ✅ | ✅ | ✅ | ✅ |
 
+## Custom Methods
 
+The following custom methods are also provided by the Dart LSP server:
+
+### dart/diagnosticServer Method
+
+Direction: Client -> Server
+Params: None
+Returns: `{ port: number }`
+
+Starts the analzyer diagnostics server (if not already running) and returns the port number it's listening on.
+
+### $/analyzerStatus Notification
+
+Direction: Server -> Client
+Params: `{ isAnalyzing: boolean }`
+
+Notifies the client when analysis starts/completes.
diff --git a/pkg/analysis_server/tool/lsp_spec/generate_all.dart b/pkg/analysis_server/tool/lsp_spec/generate_all.dart
index 23fb23f..00cd091 100644
--- a/pkg/analysis_server/tool/lsp_spec/generate_all.dart
+++ b/pkg/analysis_server/tool/lsp_spec/generate_all.dart
@@ -40,8 +40,8 @@
   final String outFolder = path.join(packageFolder, 'lib', 'lsp_protocol');
   new Directory(outFolder).createSync();
 
-  await writeSpecClasses(args, outFolder);
   await writeCustomClasses(args, outFolder);
+  await writeSpecClasses(args, outFolder);
 }
 
 Future writeSpecClasses(ArgResults args, String outFolder) async {
@@ -66,8 +66,8 @@
 
   final String output = generateDartForTypes(types);
 
-  new File(path.join(outFolder, 'protocol_generated.dart'))
-      .writeAsStringSync(generatedFileHeader(2018) + output);
+  new File(path.join(outFolder, 'protocol_generated.dart')).writeAsStringSync(
+      generatedFileHeader(2018, importCustom: true) + output);
 }
 
 /// Writes classes used by Dart's custom LSP methods.
@@ -83,6 +83,16 @@
 
   final List<AstNode> customTypes = [
     interface('DartDiagnosticServer', [field('port', type: 'number')]),
+    interface('AnalyzerStatusParams', [field('isAnalyzing', type: 'boolean')]),
+    interface(
+      'CompletionItemResolutionInfo',
+      [
+        field('file', type: 'string'),
+        field('offset', type: 'number'),
+        field('libraryId', type: 'number'),
+        field('autoImportDisplayUri', type: 'string')
+      ],
+    ),
   ];
 
   final String output = generateDartForTypes(customTypes);
@@ -117,7 +127,7 @@
       comment, new Token.identifier('Method'), methodConstants);
 }
 
-String generatedFileHeader(int year) => '''
+String generatedFileHeader(int year, {bool importCustom = false}) => '''
 // Copyright (c) $year, the Dart project authors. Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
@@ -134,6 +144,7 @@
 import 'dart:core' hide deprecated;
 import 'dart:core' as core show deprecated;
 import 'dart:convert' show JsonEncoder;
+${importCustom ? "import 'package:analysis_server/lsp_protocol/protocol_custom_generated.dart';" : ''}
 import 'package:analysis_server/lsp_protocol/protocol_special.dart';
 import 'package:analysis_server/src/protocol/protocol_internal.dart'
     show listEqual, mapEqual;
diff --git a/pkg/analysis_server/tool/lsp_spec/lsp_specification.md b/pkg/analysis_server/tool/lsp_spec/lsp_specification.md
index 2bb235d..38c8f2e 100644
--- a/pkg/analysis_server/tool/lsp_spec/lsp_specification.md
+++ b/pkg/analysis_server/tool/lsp_spec/lsp_specification.md
@@ -7,7 +7,6 @@
 download the latest version of the specification before regenerating the
 code, run the same script with an argument of "--download".
 
-
 ---
 
 Copyright (c) Microsoft Corporation.
@@ -129,10 +128,10 @@
 	id: number | string | null;
 
 	/**
-	 * The result of a request. This can be omitted in
-	 * the case of an error.
+	 * The result of a request. This member is REQUIRED on success.
+	 * This member MUST NOT exist if there was an error invoking the method.
 	 */
-	result?: any;
+	result?: string | number | boolean | object | null;
 
 	/**
 	 * The error object in case a request fails.
@@ -260,7 +259,7 @@
 
 #### Position
 
-Position in a text document expressed as zero-based line and zero-based character offset. A position is between two characters like an 'insert' cursor in a editor.
+Position in a text document expressed as zero-based line and zero-based character offset. A position is between two characters like an 'insert' cursor in a editor. Special values like for example `-1` to denote the end of a line are not supported.
 
 ```typescript
 interface Position {
@@ -608,7 +607,7 @@
 
 #### WorkspaceEdit
 
-A workspace edit represents changes to many resources managed in the workspace. The edit should either provide `changes` or `documentChanges`. If the client can handle versioned document edits and if `documentChange`s are present, the latter are preferred over `changes`.
+A workspace edit represents changes to many resources managed in the workspace. The edit should either provide `changes` or `documentChanges`. If the client can handle versioned document edits and if `documentChanges` are present, the latter are preferred over `changes`.
 
 ```typescript
 export interface WorkspaceEdit {
@@ -678,6 +677,7 @@
 
 Language | Identifier
 -------- | ----------
+ABAP | `abap`
 Windows Bat | `bat`
 BibTeX | `bibtex`
 Clojure | `clojure`
@@ -698,6 +698,7 @@
 Ini | `ini`
 Java | `java`
 JavaScript | `javascript`
+JavaScript React | `javascriptreact`
 JSON | `json`
 LaTeX | `latex`
 Less | `less`
@@ -706,7 +707,8 @@
 Markdown | `markdown`
 Objective-C | `objective-c`
 Objective-C++ | `objective-cpp`
-Perl | `perl` and `perl6`
+Perl | `perl`
+Perl 6 | `perl6`
 PHP | `php`
 Powershell | `powershell`
 Pug | `jade`
@@ -715,13 +717,14 @@
 Razor (cshtml) | `razor`
 Ruby | `ruby`
 Rust | `rust`
-Sass | `scss` (syntax using curly brackets), `sass` (indented syntax)
+SCSS | `scss` (syntax using curly brackets), `sass` (indented syntax)
 Scala | `scala`
 ShaderLab | `shaderlab`
 Shell Script (Bash) | `shellscript`
 SQL | `sql`
 Swift | `swift`
 TypeScript | `typescript`
+TypeScript React| `typescriptreact`
 TeX | `tex`
 Visual Basic | `vb`
 XML | `xml`
@@ -1760,7 +1763,8 @@
 
 export interface TextDocumentSyncOptions {
 	/**
-	 * Open and close notifications are sent to the server.
+	 * Open and close notifications are sent to the server. If omitted open close notification should not
+	 * be sent.
 	 */
 	openClose?: boolean;
 	/**
@@ -1769,15 +1773,18 @@
 	 */
 	change?: number;
 	/**
-	 * Will save notifications are sent to the server.
+	 * If present will save notifications are sent to the server. If omitted the notification should not be
+	 * sent.
 	 */
 	willSave?: boolean;
 	/**
-	 * Will save wait until requests are sent to the server.
+	 * If present will save wait until requests are sent to the server. If omitted the request should not be
+	 * sent.
 	 */
 	willSaveWaitUntil?: boolean;
 	/**
-	 * Save notifications are sent to the server.
+	 * If present save notifications are sent to the server. If omitted the notification should not be
+	 * sent.
 	 */
 	save?: SaveOptions;
 }
@@ -1888,6 +1895,12 @@
 	 */
 	foldingRangeProvider?: boolean | FoldingRangeProviderOptions | (FoldingRangeProviderOptions & TextDocumentRegistrationOptions & StaticRegistrationOptions);
 	/**
+	 * The server provides go to declaration support.
+	 *
+	 * Since 3.14.0
+	 */
+	declarationProvider?: boolean | (TextDocumentRegistrationOptions & StaticRegistrationOptions);
+	/**
 	 * The server provides execute command support.
 	 */
 	executeCommandProvider?: ExecuteCommandOptions;
@@ -1939,7 +1952,7 @@
 
 #### <a href="#shutdown" name="shutdown" class="anchor">Shutdown Request (:leftwards_arrow_with_hook:)</a>
 
-The shutdown request is sent from the client to the server. It asks the server to shut down, but to not exit (otherwise the response might not be delivered correctly to the client). There is a separate exit notification that asks the server to exit.
+The shutdown request is sent from the client to the server. It asks the server to shut down, but to not exit (otherwise the response might not be delivered correctly to the client). There is a separate exit notification that asks the server to exit. Clients must not sent any notifications other than `exit` or requests to a server to which they have sent a shutdown requests. If a server receives requests after a shutdown request those requests should be errored with `InvalidRequest`.
 
 _Request_:
 * method: 'shutdown'
@@ -2229,8 +2242,8 @@
 	uri: string;
 
 	/**
-	 * The name of the workspace folder. Defaults to the
-	 * uri's basename.
+	 * The name of the workspace folder. Used to refer to this
+	 * workspace folder in the user interface.
 	 */
 	name: string;
 }
@@ -2395,7 +2408,7 @@
 
 ```typescript
 /**
- * Describe options to be used when registering for text document change events.
+ * Describe options to be used when registering for file system change events.
  */
 export interface DidChangeWatchedFilesRegistrationOptions {
 	/**
@@ -2549,6 +2562,14 @@
 	 * Indicates whether the edit was applied or not.
 	 */
 	applied: boolean;
+
+	/**
+	 * An optional textual description for why the edit was not applied.
+	 * This may be used may be used by the server for diagnostic
+	 * logging or to provide a suitable error for a request that
+	 * triggered the edit.
+	 */
+	failureReason?: string;
 }
 ```
 * error: code and message set in case an exception happens during the request.
@@ -2898,7 +2919,8 @@
 
 	/**
 	 * The kind of this completion item. Based of the kind
-	 * an icon is chosen by the editor.
+	 * an icon is chosen by the editor. The standardized set
+	 * of available values is defined in `CompletionItemKind`.
 	 */
 	kind?: number;
 
@@ -2995,7 +3017,7 @@
 	command?: Command;
 
 	/**
-	 * An data entry field that is preserved on a completion item between
+	 * A data entry field that is preserved on a completion item between
 	 * a completion and a completion resolve request.
 	 */
 	data?: any
@@ -3051,6 +3073,15 @@
 	triggerCharacters?: string[];
 
 	/**
+	 * The list of all possible characters that commit a completion. This field can be used
+	 * if clients don't support individual commmit characters per completion item. See
+	 * `ClientCapabilities.textDocument.completion.completionItem.commitCharactersSupport`
+	 *
+   * Since 3.2.0
+	 */
+	allCommitCharacters?: string[];
+
+	/**
 	 * The server provides support to resolve additional
 	 * information for a completion item.
 	 */
diff --git a/pkg/analysis_server/tool/lsp_spec/typescript.dart b/pkg/analysis_server/tool/lsp_spec/typescript.dart
index afa5b76..130cbe2 100644
--- a/pkg/analysis_server/tool/lsp_spec/typescript.dart
+++ b/pkg/analysis_server/tool/lsp_spec/typescript.dart
@@ -55,6 +55,7 @@
     },
     "CompletionItem": {
       "kind": "CompletionItemKind",
+      "data": "CompletionItemResolutionInfo",
     },
     "DocumentHighlight": {
       "kind": "DocumentHighlightKind",
diff --git a/pkg/analysis_server/tool/lsp_spec/typescript_parser.dart b/pkg/analysis_server/tool/lsp_spec/typescript_parser.dart
index 2412309..3b06fd1 100644
--- a/pkg/analysis_server/tool/lsp_spec/typescript_parser.dart
+++ b/pkg/analysis_server/tool/lsp_spec/typescript_parser.dart
@@ -12,7 +12,8 @@
 
 final _validIdentifierCharacters = RegExp('[a-zA-Z0-9_]');
 
-bool isAnyType(TypeBase t) => t is Type && t.name == 'any';
+bool isAnyType(TypeBase t) =>
+    t is Type && (t.name == 'any' || t.name == 'object');
 
 bool isNullType(TypeBase t) => t is Type && t.name == 'null';
 
@@ -596,6 +597,15 @@
     final uniqueTypes = new Map.fromEntries(
       types.map((t) => new MapEntry(t.dartTypeWithTypeArgs, t)),
     ).values.toList();
+
+    // If our list includes something that maps to dynamic as well as other
+    // types, we should just treat the whole thing as dynamic as we get no value
+    // typing Either4<bool, String, num, dynamic> but it becomes much more
+    // difficult to use.
+    if (uniqueTypes.any(isAnyType)) {
+      return [uniqueTypes.firstWhere(isAnyType)];
+    }
+
     return uniqueTypes;
   }
 
diff --git a/pkg/analysis_server/tool/spec/spec_input.html b/pkg/analysis_server/tool/spec/spec_input.html
index 56f1243..362a389 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.26.0</version>
+  <version>1.26.1</version>
 </h1>
 <p>
   This document contains a specification of the API provided by the
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 35174b9..af958c9 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.26.0';
+const String PROTOCOL_VERSION = '1.26.1';
 
 const String ANALYSIS_NOTIFICATION_ANALYZED_FILES = 'analysis.analyzedFiles';
 const String ANALYSIS_NOTIFICATION_ANALYZED_FILES_DIRECTORIES = 'directories';
diff --git a/pkg/analyzer/CHANGELOG.md b/pkg/analyzer/CHANGELOG.md
index 19b5b21..e305a68 100644
--- a/pkg/analyzer/CHANGELOG.md
+++ b/pkg/analyzer/CHANGELOG.md
@@ -1,3 +1,10 @@
+## 0.36.4-dev (not yet published)
+* Deprecated the `isNonNullableUnit` parameter of the `TypeResolverVisitor`
+  constructor.  TypeResolverVisitor should now be configured using the
+  `featureSet` parameter.
+* Refined the return type of the getter `TypeParameter.declaredElement`.  It is
+  always guaranteed to return a `TypeParameterElement`.
+
 ## 0.36.3
 * Deprecated `AstFactory.compilationUnit`.  In a future analyzer release, this
   method will be changed so that all its parameters are named parameters.
diff --git a/pkg/analyzer/lib/dart/analysis/features.dart b/pkg/analyzer/lib/dart/analysis/features.dart
index 6841054..575c7de 100644
--- a/pkg/analyzer/lib/dart/analysis/features.dart
+++ b/pkg/analyzer/lib/dart/analysis/features.dart
@@ -20,6 +20,9 @@
   static const control_flow_collections =
       ExperimentalFeatures.control_flow_collections;
 
+  /// Feature information for extension methods.
+  static const extension_methods = ExperimentalFeatures.extension_methods;
+
   /// Feature information for spread collections.
   static const spread_collections = ExperimentalFeatures.spread_collections;
 
diff --git a/pkg/analyzer/lib/dart/ast/ast.dart b/pkg/analyzer/lib/dart/ast/ast.dart
index 8747ace..008e727 100644
--- a/pkg/analyzer/lib/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/dart/ast/ast.dart
@@ -5143,6 +5143,9 @@
   /// Set the upper bound for legal arguments to the given [type].
   void set bound(TypeAnnotation type);
 
+  @override
+  TypeParameterElement get declaredElement;
+
   /// Return the token representing the 'extends' keyword, or `null` if there is
   /// no explicit upper bound.
   Token get extendsKeyword;
diff --git a/pkg/analyzer/lib/dart/element/element.dart b/pkg/analyzer/lib/dart/element/element.dart
index fb66964..61cc2fc 100644
--- a/pkg/analyzer/lib/dart/element/element.dart
+++ b/pkg/analyzer/lib/dart/element/element.dart
@@ -843,25 +843,27 @@
 
   static const ElementKind NAME = const ElementKind('NAME', 15, "<name>");
 
+  static const ElementKind NEVER = const ElementKind('NEVER', 16, "<never>");
+
   static const ElementKind PARAMETER =
-      const ElementKind('PARAMETER', 16, "parameter");
+      const ElementKind('PARAMETER', 17, "parameter");
 
   static const ElementKind PREFIX =
-      const ElementKind('PREFIX', 17, "import prefix");
+      const ElementKind('PREFIX', 18, "import prefix");
 
-  static const ElementKind SETTER = const ElementKind('SETTER', 18, "setter");
+  static const ElementKind SETTER = const ElementKind('SETTER', 19, "setter");
 
   static const ElementKind TOP_LEVEL_VARIABLE =
-      const ElementKind('TOP_LEVEL_VARIABLE', 19, "top level variable");
+      const ElementKind('TOP_LEVEL_VARIABLE', 20, "top level variable");
 
   static const ElementKind FUNCTION_TYPE_ALIAS =
-      const ElementKind('FUNCTION_TYPE_ALIAS', 20, "function type alias");
+      const ElementKind('FUNCTION_TYPE_ALIAS', 21, "function type alias");
 
   static const ElementKind TYPE_PARAMETER =
-      const ElementKind('TYPE_PARAMETER', 21, "type parameter");
+      const ElementKind('TYPE_PARAMETER', 22, "type parameter");
 
   static const ElementKind UNIVERSE =
-      const ElementKind('UNIVERSE', 22, "<universe>");
+      const ElementKind('UNIVERSE', 23, "<universe>");
 
   static const List<ElementKind> values = const [
     CLASS,
@@ -880,6 +882,7 @@
     LOCAL_VARIABLE,
     METHOD,
     NAME,
+    NEVER,
     PARAMETER,
     PREFIX,
     SETTER,
@@ -1296,6 +1299,8 @@
   /// included using the `part` directive.
   List<CompilationUnitElement> get units;
 
+  bool get isNonNullableByDefault;
+
   /// Return a list containing all of the imports that share the given [prefix],
   /// or an empty array if there are no such imports.
   List<ImportElement> getImportsWithPrefix(PrefixElement prefix);
diff --git a/pkg/analyzer/lib/error/error.dart b/pkg/analyzer/lib/error/error.dart
index 8cadd5f..8902935 100644
--- a/pkg/analyzer/lib/error/error.dart
+++ b/pkg/analyzer/lib/error/error.dart
@@ -350,6 +350,7 @@
   HintCode.SDK_VERSION_EQ_EQ_OPERATOR_IN_CONST_CONTEXT,
   HintCode.SDK_VERSION_GT_GT_GT_OPERATOR,
   HintCode.SDK_VERSION_IS_EXPRESSION_IN_CONST_CONTEXT,
+  HintCode.SDK_VERSION_NEVER,
   HintCode.SDK_VERSION_SET_LITERAL,
   HintCode.SDK_VERSION_UI_AS_CODE,
   HintCode.STRICT_RAW_TYPE,
diff --git a/pkg/analyzer/lib/src/dart/analysis/dependency/reference_collector.dart b/pkg/analyzer/lib/src/dart/analysis/dependency/reference_collector.dart
index 5f16104..01b5ac3 100644
--- a/pkg/analyzer/lib/src/dart/analysis/dependency/reference_collector.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/dependency/reference_collector.dart
@@ -631,7 +631,10 @@
     if (node.isSynthetic) return;
 
     var name = node.name;
-    if (_localScopes.contains(name) || name == 'void' || name == 'dynamic') {
+    if (_localScopes.contains(name) ||
+        name == 'void' ||
+        name == 'dynamic' ||
+        name == 'Never') {
       return;
     }
 
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index 2098c3f..f92f743 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -1622,7 +1622,7 @@
       }
     }
 
-    if (_libraryContext == null || useSummary2) {
+    if (_libraryContext == null) {
       _libraryContext = new LibraryContext(
         session: currentSession,
         logger: _logger,
@@ -1635,6 +1635,8 @@
         targetLibrary: library,
         useSummary2: useSummary2,
       );
+    } else if (useSummary2) {
+      _libraryContext.load2(library);
     } else {
       _libraryContext.load(library);
     }
diff --git a/pkg/analyzer/lib/src/dart/analysis/experiments.dart b/pkg/analyzer/lib/src/dart/analysis/experiments.dart
index 2cfdf21..c26eb6f 100644
--- a/pkg/analyzer/lib/src/dart/analysis/experiments.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/experiments.dart
@@ -33,6 +33,9 @@
   /// String to enable the experiment "control-flow-collections"
   static const String control_flow_collections = 'control-flow-collections';
 
+  /// String to enable the experiment "extension-methods"
+  static const String extension_methods = 'extension-methods';
+
   /// String to enable the experiment "non-nullable"
   static const String non_nullable = 'non-nullable';
 
@@ -98,15 +101,22 @@
       IsExpired.triple_shift,
       'Triple-shift operator');
 
-  static const bogus_disabled = const ExperimentalFeature(
+  static const extension_methods = const ExperimentalFeature(
       6,
+      EnableString.extension_methods,
+      IsEnabledByDefault.extension_methods,
+      IsExpired.extension_methods,
+      'Extension Methods');
+
+  static const bogus_disabled = const ExperimentalFeature(
+      7,
       EnableString.bogus_disabled,
       IsEnabledByDefault.bogus_disabled,
       IsExpired.bogus_disabled,
       null);
 
   static const bogus_enabled = const ExperimentalFeature(
-      7,
+      8,
       EnableString.bogus_enabled,
       IsEnabledByDefault.bogus_enabled,
       IsExpired.bogus_enabled,
@@ -121,11 +131,12 @@
   static const knownFeatures = <String, ExperimentalFeature>{
     EnableString.constant_update_2018:
         ExperimentalFeatures.constant_update_2018,
-    EnableString.non_nullable: ExperimentalFeatures.non_nullable,
     EnableString.control_flow_collections:
         ExperimentalFeatures.control_flow_collections,
-    EnableString.spread_collections: ExperimentalFeatures.spread_collections,
+    EnableString.extension_methods: ExperimentalFeatures.extension_methods,
+    EnableString.non_nullable: ExperimentalFeatures.non_nullable,
     EnableString.set_literals: ExperimentalFeatures.set_literals,
+    EnableString.spread_collections: ExperimentalFeatures.spread_collections,
     EnableString.triple_shift: ExperimentalFeatures.triple_shift,
     EnableString.bogus_disabled: ExperimentalFeatures.bogus_disabled,
     EnableString.bogus_enabled: ExperimentalFeatures.bogus_enabled,
@@ -138,6 +149,7 @@
   ExperimentStatus(
       {bool constant_update_2018,
       bool control_flow_collections,
+      bool extension_methods,
       bool non_nullable,
       bool set_literals,
       bool spread_collections,
@@ -149,6 +161,7 @@
           true, // spread-collections
           true, // set-literals
           triple_shift ?? IsEnabledByDefault.triple_shift,
+          extension_methods ?? IsEnabledByDefault.extension_methods,
           false, // bogus-disabled
           true, // bogus-enabled
         ];
@@ -188,6 +201,10 @@
   bool get control_flow_collections =>
       isEnabled(ExperimentalFeatures.control_flow_collections);
 
+  /// Current state for the flag "extension_methods"
+  bool get extension_methods =>
+      isEnabled(ExperimentalFeatures.extension_methods);
+
   @override
   int get hashCode {
     int hash = 0;
@@ -248,6 +265,9 @@
   /// Default state of the experiment "control-flow-collections"
   static const bool control_flow_collections = true;
 
+  /// Default state of the experiment "extension-methods"
+  static const bool extension_methods = false;
+
   /// Default state of the experiment "non-nullable"
   static const bool non_nullable = false;
 
@@ -277,6 +297,9 @@
   /// Expiration status of the experiment "control-flow-collections"
   static const bool control_flow_collections = true;
 
+  /// Expiration status of the experiment "extension-methods"
+  static const bool extension_methods = false;
+
   /// Expiration status of the experiment "non-nullable"
   static const bool non_nullable = false;
 
diff --git a/pkg/analyzer/lib/src/dart/analysis/file_state.dart b/pkg/analyzer/lib/src/dart/analysis/file_state.dart
index 7c8377e..1df560f 100644
--- a/pkg/analyzer/lib/src/dart/analysis/file_state.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/file_state.dart
@@ -35,6 +35,10 @@
 import 'package:front_end/src/fasta/scanner/token.dart';
 import 'package:meta/meta.dart';
 
+var counterFileStateRefresh = 0;
+var counterUnlinkedLinkedBytes = 0;
+var timerFileStateRefresh = Stopwatch();
+
 /**
  * [FileContentOverlay] is used to temporary override content of files.
  */
@@ -118,9 +122,11 @@
   String _unlinkedKey;
   AnalysisDriverUnlinkedUnit _driverUnlinkedUnit;
   UnlinkedUnit _unlinked;
-  UnlinkedUnit2 _unlinked2;
   List<int> _apiSignature;
 
+  UnlinkedUnit2 _unlinked2;
+  CompilationUnit _unitForLinking;
+
   List<FileState> _importedFiles;
   List<FileState> _exportedFiles;
   List<FileState> _partedFiles;
@@ -454,8 +460,15 @@
    * Return `true` if the API signature changed since the last refresh.
    */
   bool refresh({bool allowCached: false}) {
+    counterFileStateRefresh++;
+
     if (_fsState.useSummary2) {
-      return _refresh2();
+      return _refresh2(allowCached: allowCached);
+    }
+
+    var timerWasRunning = timerFileStateRefresh.isRunning;
+    if (!timerWasRunning) {
+      timerFileStateRefresh.start();
     }
 
     _invalidateCurrentUnresolvedData();
@@ -494,6 +507,7 @@
                   referencedNames: referencedNames,
                   subtypedNames: subtypedNames)
               .toBuffer();
+          counterUnlinkedLinkedBytes += bytes.length;
           _fsState._byteStore.put(_unlinkedKey, bytes);
         });
       }
@@ -582,10 +596,26 @@
       files.add(this);
     }
 
+    if (!timerWasRunning) {
+      timerFileStateRefresh.stop();
+    }
+
     // Return whether the API signature changed.
     return apiSignatureChanged;
   }
 
+  /// If the file has a parsed unit from computing unlinked data, return it.
+  /// Otherwise, parse it afresh now.
+  CompilationUnit takeUnitForLinking() {
+    if (_unitForLinking != null) {
+      var result = _unitForLinking;
+      _unitForLinking = null;
+      return result;
+    } else {
+      return parse();
+    }
+  }
+
   @override
   String toString() => path ?? '<unresolved>';
 
@@ -708,7 +738,7 @@
     Scanner scanner = new Scanner(source, reader, errorListener)
       ..configureFeatures(featureSet);
     Token token = PerformanceStatistics.scan.makeCurrentWhile(() {
-      return scanner.tokenize();
+      return scanner.tokenize(reportScannerErrors: false);
     });
     LineInfo lineInfo = new LineInfo(scanner.lineStarts);
 
@@ -729,11 +759,16 @@
     return unit;
   }
 
-  bool _refresh2() {
+  bool _refresh2({bool allowCached: false}) {
+    var timerWasRunning = timerFileStateRefresh.isRunning;
+    if (!timerWasRunning) {
+      timerFileStateRefresh.start();
+    }
+
     _invalidateCurrentUnresolvedData();
 
     {
-      var rawFileState = _fsState._fileContentCache.get(path, false);
+      var rawFileState = _fsState._fileContentCache.get(path, allowCached);
       _content = rawFileState.content;
       _exists = rawFileState.exists;
       _contentHash = rawFileState.contentHash;
@@ -756,6 +791,7 @@
       bytes = _fsState._byteStore.get(_unlinkedKey);
       if (bytes == null || bytes.isEmpty) {
         CompilationUnit unit = parse();
+        _unitForLinking = unit;
         _fsState._logger.run('Create unlinked for $path', () {
           var unlinkedUnit = serializeAstUnlinked2(contentSignature, unit);
           var definedNames = computeDefinedNames(unit);
@@ -853,6 +889,10 @@
       files.add(this);
     }
 
+    if (!timerWasRunning) {
+      timerFileStateRefresh.stop();
+    }
+
     // Return whether the API signature changed.
     return apiSignatureChanged;
   }
diff --git a/pkg/analyzer/lib/src/dart/analysis/index.dart b/pkg/analyzer/lib/src/dart/analysis/index.dart
index 61b116e..1c23029 100644
--- a/pkg/analyzer/lib/src/dart/analysis/index.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/index.dart
@@ -487,6 +487,14 @@
             element.enclosingElement.isSynthetic)) {
       return;
     }
+    // Elements for generic function types are enclosed by the compilation
+    // units, but don't have names. So, we cannot index references to their
+    // named parameters. Ignore them.
+    if (elementKind == ElementKind.PARAMETER &&
+        element is ParameterElement &&
+        element.enclosingElement is GenericFunctionTypeElement) {
+      return;
+    }
     // Add the relation.
     assembler.addElementRelation(element, kind, offset, length, isQualified);
   }
diff --git a/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart b/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
index 33e6df3..699c335 100644
--- a/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
@@ -32,11 +32,17 @@
 import 'package:analyzer/src/lint/linter.dart';
 import 'package:analyzer/src/lint/linter_visitor.dart';
 import 'package:analyzer/src/services/lint.dart';
-import 'package:analyzer/src/summary2/declaration_splicer.dart';
 import 'package:analyzer/src/summary2/linked_element_factory.dart';
 import 'package:analyzer/src/task/strong/checker.dart';
 import 'package:pub_semver/pub_semver.dart';
 
+var timerLibraryAnalyzer = Stopwatch();
+var timerLibraryAnalyzerConst = Stopwatch();
+var timerLibraryAnalyzerFreshUnit = Stopwatch();
+var timerLibraryAnalyzerResolve = Stopwatch();
+var timerLibraryAnalyzerSplicer = Stopwatch();
+var timerLibraryAnalyzerVerify = Stopwatch();
+
 /**
  * Analyzer of a single library.
  */
@@ -59,7 +65,6 @@
   final TypeProvider _typeProvider;
 
   final TypeSystem _typeSystem;
-  bool isNonNullableLibrary = false;
   LibraryElement _libraryElement;
 
   LibraryScope _libraryScope;
@@ -108,15 +113,15 @@
    * Compute analysis results for all units of the library.
    */
   Map<FileState, UnitAnalysisResult> analyzeSync() {
+    timerLibraryAnalyzer.start();
     Map<FileState, CompilationUnit> units = {};
 
     // Parse all files.
+    timerLibraryAnalyzerFreshUnit.start();
     for (FileState file in _library.libraryFiles) {
       units[file] = _parse(file);
     }
-    // TODO(danrubel): Verify that all units are either nullable or non-nullable
-    isNonNullableLibrary =
-        (units.values.first as CompilationUnitImpl).isNonNullable;
+    timerLibraryAnalyzerFreshUnit.stop();
 
     // Resolve URIs in directives to corresponding sources.
     units.forEach((file, unit) {
@@ -131,17 +136,22 @@
     }
     _libraryScope = new LibraryScope(_libraryElement);
 
+    timerLibraryAnalyzerResolve.start();
     _resolveDirectives(units);
 
     units.forEach((file, unit) {
       _resolveFile(file, unit);
       _computePendingMissingRequiredParameters(file, unit);
     });
+    timerLibraryAnalyzerResolve.stop();
 
+    timerLibraryAnalyzerConst.start();
     units.values.forEach(_findConstants);
     _clearConstantEvaluationResults();
     _computeConstants();
+    timerLibraryAnalyzerConst.stop();
 
+    timerLibraryAnalyzerVerify.start();
     PerformanceStatistics.errors.makeCurrentWhile(() {
       units.forEach((file, unit) {
         _computeVerifyErrors(file, unit);
@@ -179,6 +189,7 @@
         }
       });
     }
+    timerLibraryAnalyzerVerify.stop();
 
     // Return full results.
     Map<FileState, UnitAnalysisResult> results = {};
@@ -187,6 +198,7 @@
       errors = _filterIgnoredErrors(file, errors);
       results[file] = new UnitAnalysisResult(file, unit, errors);
     });
+    timerLibraryAnalyzer.stop();
     return results;
   }
 
@@ -239,7 +251,7 @@
       errorListener.onError(pendingError.toAnalysisError());
     }
 
-    unit.accept(new DeadCodeVerifier(errorReporter, isNonNullableLibrary,
+    unit.accept(new DeadCodeVerifier(errorReporter, unit.featureSet,
         typeSystem: _context.typeSystem));
 
     // Dart2js analysis.
@@ -631,11 +643,9 @@
       }
     }
 
-    if (_elementFactory != null) {
-      new DeclarationSplicer(unitElement).splice(unit);
-    } else {
-      new DeclarationResolver().resolve(unit, unitElement);
-    }
+    timerLibraryAnalyzerSplicer.start();
+    new DeclarationResolver().resolve(unit, unitElement);
+    timerLibraryAnalyzerSplicer.stop();
 
     unit.accept(new AstRewriteVisitor(_context.typeSystem, _libraryElement,
         source, _typeProvider, errorListener,
@@ -643,14 +653,13 @@
 
     // TODO(scheglov) remove EnumMemberBuilder class
 
-    new TypeParameterBoundsResolver(
-            _context.typeSystem, _libraryElement, source, errorListener,
-            isNonNullableUnit: isNonNullableLibrary)
+    new TypeParameterBoundsResolver(_context.typeSystem, _libraryElement,
+            source, errorListener, unit.featureSet)
         .resolveTypeBounds(unit);
 
     unit.accept(new TypeResolverVisitor(
         _libraryElement, source, _typeProvider, errorListener,
-        isNonNullableUnit: isNonNullableLibrary));
+        featureSet: unit.featureSet));
 
     unit.accept(new VariableResolverVisitor(
         _libraryElement, source, _typeProvider, errorListener,
diff --git a/pkg/analyzer/lib/src/dart/analysis/library_context.dart b/pkg/analyzer/lib/src/dart/analysis/library_context.dart
index 421a8df..f8f7f01 100644
--- a/pkg/analyzer/lib/src/dart/analysis/library_context.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/library_context.dart
@@ -12,6 +12,7 @@
 import 'package:analyzer/src/dart/analysis/library_graph.dart';
 import 'package:analyzer/src/dart/analysis/performance_logger.dart';
 import 'package:analyzer/src/dart/analysis/restricted_analysis_context.dart';
+import 'package:analyzer/src/dart/analysis/session.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/inheritance_manager2.dart';
 import 'package:analyzer/src/generated/engine.dart'
@@ -30,6 +31,14 @@
 import 'package:analyzer/src/summary2/reference.dart';
 import 'package:meta/meta.dart';
 
+var counterInputLibrariesFiles = 0;
+var counterLinkedLibraries = 0;
+var counterLoadedLibraries = 0;
+var timerBundleToBytes = Stopwatch();
+var timerInputLibraries = Stopwatch();
+var timerLinking = Stopwatch();
+var timerLoad2 = Stopwatch();
+
 /**
  * Context information necessary to analyze one or more libraries within an
  * [AnalysisDriver].
@@ -54,6 +63,8 @@
   LinkedElementFactory elementFactory;
   InheritanceManager2 inheritanceManager;
 
+  var loadedBundles = Set<LibraryCycle>.identity();
+
   LibraryContext({
     @required AnalysisSession session,
     @required PerformanceLog logger,
@@ -72,13 +83,15 @@
       store.addStore(externalSummaries);
     }
 
+    var synchronousSession =
+        SynchronousSession(analysisOptions, declaredVariables);
     analysisContext = new RestrictedAnalysisContext(
-      analysisOptions,
-      declaredVariables,
+      synchronousSession,
       sourceFactory,
     );
 
     if (useSummary2) {
+      _createElementFactory();
       load2(targetLibrary);
     } else {
       // Fill the store with summaries required for the initial library.
@@ -142,6 +155,8 @@
       return;
     }
 
+    timerLoad2.start();
+
     var libraries = <String, FileState>{};
     void appendLibraryFiles(FileState library) {
       // Stop if this library is already a part of the context.
@@ -189,8 +204,10 @@
       }
       int numOfLoaded = libraries.length - libraryUrisToLink.length;
       logger.writeln('Loaded $numOfLoaded linked bundles.');
+      counterLoadedLibraries += numOfLoaded;
     });
 
+    timerLinking.start();
     var linkedLibraries = <String, LinkedLibraryBuilder>{};
     logger.run('Link libraries', () {
       linkedLibraries = link(libraryUrisToLink, (String uri) {
@@ -202,26 +219,35 @@
       }, DeclaredVariables(), analysisContext.analysisOptions);
       logger.writeln('Linked ${linkedLibraries.length} libraries.');
     });
+    timerLinking.stop();
+    counterLinkedLibraries += linkedLibraries.length;
 
     // Store freshly linked libraries into the byte store.
     // Append them to the context.
+    timerBundleToBytes.start();
     for (String uri in linkedLibraries.keys) {
+      counterLoadedLibraries++;
       FileState library = libraries[uri];
       String key = library.transitiveSignatureLinked;
 
+      timerBundleToBytes.start();
       LinkedLibraryBuilder linkedBuilder = linkedLibraries[uri];
       List<int> bytes = linkedBuilder.toBuffer();
+      timerBundleToBytes.stop();
       byteStore.put(key, bytes);
+      counterUnlinkedLinkedBytes += bytes.length;
 
       LinkedLibrary linked = new LinkedLibrary.fromBuffer(bytes);
       store.addLinkedLibrary(uri, linked);
       _linkedDataInBytes += bytes.length;
     }
+    timerBundleToBytes.stop();
+    timerLoad2.stop();
   }
 
   /// Load data required to access elements of the given [targetLibrary].
   void load2(FileState targetLibrary) {
-    var loadedBundles = Set<LibraryCycle>.identity();
+    timerLoad2.start();
     var inputBundles = <LinkedNodeBundle>[];
 
     void loadBundle(LibraryCycle cycle) {
@@ -235,17 +261,20 @@
         var bytes = byteStore.get(key);
 
         if (bytes == null) {
+          timerInputLibraries.start();
           var inputLibraries = <link2.LinkInputLibrary>[];
           logger.run('Prepare input libraries', () {
             for (var libraryFile in cycle.libraries) {
+              counterInputLibrariesFiles++;
               var librarySource = libraryFile.source;
               if (librarySource == null) continue;
 
               var inputUnits = <link2.LinkInputUnit>[];
               for (var file in libraryFile.libraryFiles) {
                 var isSynthetic = !file.exists;
+                var unit = file.takeUnitForLinking();
                 inputUnits.add(
-                  link2.LinkInputUnit(file.source, isSynthetic, file.parse()),
+                  link2.LinkInputUnit(file.source, isSynthetic, unit),
                 );
               }
 
@@ -255,29 +284,48 @@
             }
             logger.writeln('Prepared ${inputLibraries.length} libraries.');
           });
+          timerInputLibraries.stop();
 
+          timerLinking.start();
           link2.LinkResult linkResult;
           logger.run('Link libraries', () {
-            linkResult = link2.link(
-              analysisContext.analysisOptions,
-              analysisContext.sourceFactory,
-              analysisContext.declaredVariables,
-              inputBundles,
-              inputLibraries,
-            );
+            linkResult = link2.link(elementFactory, inputLibraries);
             logger.writeln('Linked ${inputLibraries.length} libraries.');
           });
+          timerLinking.stop();
+          counterLinkedLibraries += linkResult.bundle.libraries.length;
 
+          timerBundleToBytes.start();
           bytes = linkResult.bundle.toBuffer();
+          timerBundleToBytes.stop();
           byteStore.put(key, bytes);
           logger.writeln('Stored ${bytes.length} bytes.');
+          counterUnlinkedLinkedBytes += bytes.length;
         } else {
+          // TODO(scheglov) Take / clear parsed units in files.
           logger.writeln('Loaded ${bytes.length} bytes.');
         }
 
-        inputBundles.add(
-          LinkedNodeBundle.fromBuffer(bytes),
+        // We are about to load dart:core, but if we have just linked it, the
+        // linker might have set the type provider. So, clear it, and recreate
+        // the element factory - it is empty anyway.
+        var hasDartCoreBeforeBundle = elementFactory.hasDartCore;
+        if (!hasDartCoreBeforeBundle) {
+          analysisContext.clearTypeProvider();
+          _createElementFactory();
+        }
+
+        var bundle = LinkedNodeBundle.fromBuffer(bytes);
+        inputBundles.add(bundle);
+        elementFactory.addBundle(
+          LinkedBundleContext(elementFactory, bundle),
         );
+        counterLoadedLibraries += bundle.libraries.length;
+
+        // If the first bundle, with dart:core, create the type provider.
+        if (!hasDartCoreBeforeBundle && elementFactory.hasDartCore) {
+          _createElementFactoryTypeProvider();
+        }
       });
     }
 
@@ -286,31 +334,7 @@
       loadBundle(libraryCycle);
     });
 
-    var rootReference = Reference.root();
-    rootReference.getChild('dart:core').getChild('dynamic').element =
-        DynamicElementImpl.instance;
-
-    elementFactory = LinkedElementFactory(
-      analysisContext,
-      analysisSession,
-      rootReference,
-    );
-
-    for (var bundle in inputBundles) {
-      elementFactory.addBundle(
-        LinkedBundleContext(elementFactory, bundle),
-      );
-    }
-
-    var dartCore = elementFactory.libraryOfUri('dart:core');
-    var dartAsync = elementFactory.libraryOfUri('dart:async');
-    var typeProvider = SummaryTypeProvider()
-      ..initializeCore(dartCore)
-      ..initializeAsync(dartAsync);
-    analysisContext.typeProvider = typeProvider;
-
-    dartCore.createLoadLibraryFunction(typeProvider);
-    dartAsync.createLoadLibraryFunction(typeProvider);
+    timerLoad2.stop();
   }
 
   /// Return `true` if this context grew too large, and should be recreated.
@@ -321,4 +345,28 @@
   bool pack() {
     return _linkedDataInBytes > _maxLinkedDataInBytes;
   }
+
+  void _createElementFactory() {
+    elementFactory = LinkedElementFactory(
+      analysisContext,
+      analysisSession,
+      Reference.root(),
+    );
+
+    var dartCoreRef = elementFactory.rootReference.getChild('dart:core');
+    dartCoreRef.getChild('dynamic').element = DynamicElementImpl.instance;
+    dartCoreRef.getChild('Never').element = NeverElementImpl.instance;
+  }
+
+  void _createElementFactoryTypeProvider() {
+    var dartCore = elementFactory.libraryOfUri('dart:core');
+    var dartAsync = elementFactory.libraryOfUri('dart:async');
+    var typeProvider = SummaryTypeProvider()
+      ..initializeCore(dartCore)
+      ..initializeAsync(dartAsync);
+    analysisContext.typeProvider = typeProvider;
+
+    dartCore.createLoadLibraryFunction(typeProvider);
+    dartAsync.createLoadLibraryFunction(typeProvider);
+  }
 }
diff --git a/pkg/analyzer/lib/src/dart/analysis/restricted_analysis_context.dart b/pkg/analyzer/lib/src/dart/analysis/restricted_analysis_context.dart
index a68cdcd..60b7db7 100644
--- a/pkg/analyzer/lib/src/dart/analysis/restricted_analysis_context.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/restricted_analysis_context.dart
@@ -4,6 +4,7 @@
 
 import 'package:analyzer/dart/analysis/declared_variables.dart';
 import 'package:analyzer/src/context/context.dart';
+import 'package:analyzer/src/dart/analysis/session.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/source.dart';
@@ -14,42 +15,36 @@
 /// functionality (which is task based), except what we intend to expose
 /// through the new API.
 class RestrictedAnalysisContext implements AnalysisContextImpl {
-  @override
-  final AnalysisOptionsImpl analysisOptions;
-
-  @override
-  final DeclaredVariables declaredVariables;
+  final SynchronousSession synchronousSession;
 
   @override
   final SourceFactory sourceFactory;
 
-  TypeProvider _typeProvider;
-
-  TypeSystem _typeSystem;
-
-  RestrictedAnalysisContext(
-      this.analysisOptions, this.declaredVariables, this.sourceFactory);
+  RestrictedAnalysisContext(this.synchronousSession, this.sourceFactory);
 
   @override
-  TypeProvider get typeProvider => _typeProvider;
+  AnalysisOptionsImpl get analysisOptions => synchronousSession.analysisOptions;
+
+  @override
+  DeclaredVariables get declaredVariables =>
+      synchronousSession.declaredVariables;
+
+  @override
+  TypeProvider get typeProvider => synchronousSession.typeProvider;
 
   @override
   set typeProvider(TypeProvider typeProvider) {
-    if (_typeProvider != null) {
-      throw StateError('TypeProvider can be set only once.');
-    }
-    _typeProvider = typeProvider;
+    synchronousSession.typeProvider = typeProvider;
   }
 
   @override
-  TypeSystem get typeSystem {
-    return _typeSystem ??= Dart2TypeSystem(
-      typeProvider,
-      implicitCasts: analysisOptions.implicitCasts,
-    );
-  }
+  TypeSystem get typeSystem => synchronousSession.typeSystem;
 
   noSuchMethod(Invocation invocation) {
     return super.noSuchMethod(invocation);
   }
+
+  void clearTypeProvider() {
+    synchronousSession.clearTypeProvider();
+  }
 }
diff --git a/pkg/analyzer/lib/src/dart/analysis/session.dart b/pkg/analyzer/lib/src/dart/analysis/session.dart
index 5c88736..30db6fa 100644
--- a/pkg/analyzer/lib/src/dart/analysis/session.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/session.dart
@@ -14,6 +14,7 @@
 import 'package:analyzer/src/dart/analysis/driver.dart' as driver;
 import 'package:analyzer/src/dart/analysis/top_level_declaration.dart';
 import 'package:analyzer/src/dart/analysis/uri_converter.dart';
+import 'package:analyzer/src/generated/engine.dart' show AnalysisOptionsImpl;
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/source.dart';
 
@@ -192,3 +193,38 @@
     }
   }
 }
+
+/// Data structure containing information about the analysis session that is
+/// available synchronously.
+class SynchronousSession {
+  final AnalysisOptionsImpl analysisOptions;
+
+  final DeclaredVariables declaredVariables;
+
+  TypeProvider _typeProvider;
+
+  TypeSystem _typeSystem;
+
+  SynchronousSession(this.analysisOptions, this.declaredVariables);
+
+  TypeProvider get typeProvider => _typeProvider;
+
+  set typeProvider(TypeProvider typeProvider) {
+    if (_typeProvider != null) {
+      throw StateError('TypeProvider can be set only once.');
+    }
+    _typeProvider = typeProvider;
+  }
+
+  TypeSystem get typeSystem {
+    return _typeSystem ??= Dart2TypeSystem(
+      typeProvider,
+      implicitCasts: analysisOptions.implicitCasts,
+    );
+  }
+
+  void clearTypeProvider() {
+    _typeProvider = null;
+    _typeSystem = null;
+  }
+}
diff --git a/pkg/analyzer/lib/src/dart/ast/ast.dart b/pkg/analyzer/lib/src/dart/ast/ast.dart
index 1eee9ae..e3064ce 100644
--- a/pkg/analyzer/lib/src/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/src/dart/ast/ast.dart
@@ -2057,9 +2057,6 @@
   /// has not yet been performed.
   LocalVariableInfo localVariableInfo = new LocalVariableInfo();
 
-  /// Is `true` if this unit has been parsed as non-nullable.
-  final bool isNonNullable;
-
   @override
   final FeatureSet featureSet;
 
@@ -2074,9 +2071,7 @@
       List<Directive> directives,
       List<CompilationUnitMember> declarations,
       this.endToken,
-      this.featureSet)
-      : this.isNonNullable =
-            featureSet?.isEnabled(Feature.non_nullable) ?? false {
+      this.featureSet) {
     _scriptTag = _becomeParentOf(scriptTag);
     _directives = new NodeListImpl<Directive>(this, directives);
     _declarations = new NodeListImpl<CompilationUnitMember>(this, declarations);
diff --git a/pkg/analyzer/lib/src/dart/constant/compute.dart b/pkg/analyzer/lib/src/dart/constant/compute.dart
index 43dbc77..3fc6ca9 100644
--- a/pkg/analyzer/lib/src/dart/constant/compute.dart
+++ b/pkg/analyzer/lib/src/dart/constant/compute.dart
@@ -37,9 +37,7 @@
   }
 }
 
-/**
- * [graph.Node] that is used to compute constants in dependency order.
- */
+/// [graph.Node] that is used to compute constants in dependency order.
 class _ConstantNode extends graph.Node<_ConstantNode> {
   final ConstantEvaluationEngine evaluationEngine;
   final Map<ConstantEvaluationTarget, _ConstantNode> nodeMap;
@@ -65,9 +63,7 @@
   }
 }
 
-/**
- * [graph.DependencyWalker] for computing constants and detecting cycles.
- */
+/// [graph.DependencyWalker] for computing constants and detecting cycles.
 class _ConstantWalker extends graph.DependencyWalker<_ConstantNode> {
   final ConstantEvaluationEngine evaluationEngine;
 
diff --git a/pkg/analyzer/lib/src/dart/constant/evaluation.dart b/pkg/analyzer/lib/src/dart/constant/evaluation.dart
index bac1408..3c98239 100644
--- a/pkg/analyzer/lib/src/dart/constant/evaluation.dart
+++ b/pkg/analyzer/lib/src/dart/constant/evaluation.dart
@@ -29,81 +29,57 @@
     show Dart2TypeSystem, TypeSystem;
 import 'package:analyzer/src/task/api/model.dart';
 
-/**
- * Helper class encapsulating the methods for evaluating constants and
- * constant instance creation expressions.
- */
+/// Helper class encapsulating the methods for evaluating constants and
+/// constant instance creation expressions.
 class ConstantEvaluationEngine {
-  /**
-   * Parameter to "fromEnvironment" methods that denotes the default value.
-   */
+  /// Parameter to "fromEnvironment" methods that denotes the default value.
   static String _DEFAULT_VALUE_PARAM = "defaultValue";
 
-  /**
-   * Source of RegExp matching declarable operator names.
-   * From sdk/lib/internal/symbol.dart.
-   */
+  /// Source of RegExp matching declarable operator names.
+  /// From sdk/lib/internal/symbol.dart.
   static String _OPERATOR_RE =
       "(?:[\\-+*/%&|^]|\\[\\]=?|==|~/?|<[<=]?|>[>=]?|unary-)";
 
-  /**
-   * Source of RegExp matching Dart reserved words.
-   * From sdk/lib/internal/symbol.dart.
-   */
+  /// Source of RegExp matching Dart reserved words.
+  /// From sdk/lib/internal/symbol.dart.
   static String _RESERVED_WORD_RE =
       "(?:assert|break|c(?:a(?:se|tch)|lass|on(?:st|tinue))|"
       "d(?:efault|o)|e(?:lse|num|xtends)|f(?:alse|inal(?:ly)?|or)|"
       "i[fns]|n(?:ew|ull)|ret(?:hrow|urn)|s(?:uper|witch)|t(?:h(?:is|row)|"
       "r(?:ue|y))|v(?:ar|oid)|w(?:hile|ith))";
 
-  /**
-   * Source of RegExp matching any public identifier.
-   * From sdk/lib/internal/symbol.dart.
-   */
+  /// Source of RegExp matching any public identifier.
+  /// From sdk/lib/internal/symbol.dart.
   static String _PUBLIC_IDENTIFIER_RE =
       "(?!$_RESERVED_WORD_RE\\b(?!\\\$))[a-zA-Z\$][\\w\$]*";
 
-  /**
-   * RegExp that validates a non-empty non-private symbol.
-   * From sdk/lib/internal/symbol.dart.
-   */
+  /// RegExp that validates a non-empty non-private symbol.
+  /// From sdk/lib/internal/symbol.dart.
   static RegExp _PUBLIC_SYMBOL_PATTERN = new RegExp(
       "^(?:$_OPERATOR_RE\$|$_PUBLIC_IDENTIFIER_RE(?:=?\$|[.](?!\$)))+?\$");
 
-  /**
-   * The type provider used to access the known types.
-   */
+  /// The type provider used to access the known types.
   final TypeProvider typeProvider;
 
-  /**
-   * The type system.  This is used to guess the types of constants when their
-   * exact value is unknown.
-   */
+  /// The type system.  This is used to guess the types of constants when their
+  /// exact value is unknown.
   final TypeSystem typeSystem;
 
-  /**
-   * The set of variables declared on the command line using '-D'.
-   */
+  /// The set of variables declared on the command line using '-D'.
   final DeclaredVariables _declaredVariables;
 
-  /**
-   * Return the object representing the state of active experiments.
-   */
+  /// Return the object representing the state of active experiments.
   final ExperimentStatus experimentStatus;
 
-  /**
-   * Validator used to verify correct dependency analysis when running unit
-   * tests.
-   */
+  /// Validator used to verify correct dependency analysis when running unit
+  /// tests.
   final ConstantEvaluationValidator validator;
 
-  /**
-   * Initialize a newly created [ConstantEvaluationEngine].  The [typeProvider]
-   * is used to access known types.  [_declaredVariables] is the set of
-   * variables declared on the command line using '-D'.  The [validator], if
-   * given, is used to verify correct dependency analysis when running unit
-   * tests.
-   */
+  /// Initialize a newly created [ConstantEvaluationEngine].  The [typeProvider]
+  /// is used to access known types.  [_declaredVariables] is the set of
+  /// variables declared on the command line using '-D'.  The [validator], if
+  /// given, is used to verify correct dependency analysis when running unit
+  /// tests.
   ConstantEvaluationEngine(TypeProvider typeProvider, this._declaredVariables,
       {ConstantEvaluationValidator validator,
       ExperimentStatus experimentStatus,
@@ -116,15 +92,13 @@
         typeSystem = typeSystem ?? new Dart2TypeSystem(typeProvider),
         experimentStatus = experimentStatus ?? new ExperimentStatus();
 
-  /**
-   * Check that the arguments to a call to fromEnvironment() are correct. The
-   * [arguments] are the AST nodes of the arguments. The [argumentValues] are
-   * the values of the unnamed arguments. The [namedArgumentValues] are the
-   * values of the named arguments. The [expectedDefaultValueType] is the
-   * allowed type of the "defaultValue" parameter (if present). Note:
-   * "defaultValue" is always allowed to be null. Return `true` if the arguments
-   * are correct, `false` if there is an error.
-   */
+  /// Check that the arguments to a call to fromEnvironment() are correct. The
+  /// [arguments] are the AST nodes of the arguments. The [argumentValues] are
+  /// the values of the unnamed arguments. The [namedArgumentValues] are the
+  /// values of the named arguments. The [expectedDefaultValueType] is the
+  /// allowed type of the "defaultValue" parameter (if present). Note:
+  /// "defaultValue" is always allowed to be null. Return `true` if the
+  /// arguments are correct, `false` if there is an error.
   bool checkFromEnvironmentArguments(
       NodeList<Expression> arguments,
       List<DartObjectImpl> argumentValues,
@@ -159,13 +133,11 @@
     return true;
   }
 
-  /**
-   * Check that the arguments to a call to Symbol() are correct. The [arguments]
-   * are the AST nodes of the arguments. The [argumentValues] are the values of
-   * the unnamed arguments. The [namedArgumentValues] are the values of the
-   * named arguments. Return `true` if the arguments are correct, `false` if
-   * there is an error.
-   */
+  /// Check that the arguments to a call to Symbol() are correct. The
+  /// [arguments] are the AST nodes of the arguments. The [argumentValues] are
+  /// the values of the unnamed arguments. The [namedArgumentValues] are the
+  /// values of the named arguments. Return `true` if the arguments are correct,
+  /// `false` if there is an error.
   bool checkSymbolArguments(
       NodeList<Expression> arguments,
       List<DartObjectImpl> argumentValues,
@@ -183,9 +155,7 @@
     return isValidPublicSymbol(name);
   }
 
-  /**
-   * Compute the constant value associated with the given [constant].
-   */
+  /// Compute the constant value associated with the given [constant].
   void computeConstantValue(ConstantEvaluationTarget constant) {
     validator.beforeComputeValue(constant);
     if (constant is ParameterElementImpl) {
@@ -283,17 +253,16 @@
     } else {
       // Should not happen.
       assert(false);
-      AnalysisEngine.instance.logger.logError(
-          "Constant value computer trying to compute the value of a node of type ${constant.runtimeType}");
+      AnalysisEngine.instance.logger
+          .logError("Constant value computer trying to compute "
+              "the value of a node of type ${constant.runtimeType}");
       return;
     }
   }
 
-  /**
-   * Determine which constant elements need to have their values computed
-   * prior to computing the value of [constant], and report them using
-   * [callback].
-   */
+  /// Determine which constant elements need to have their values computed
+  /// prior to computing the value of [constant], and report them using
+  /// [callback].
   void computeDependencies(
       ConstantEvaluationTarget constant, ReferenceFinderCallback callback) {
     ReferenceFinder referenceFinder = new ReferenceFinder(callback);
@@ -316,12 +285,13 @@
           return;
         } else if (constant.isFactory) {
           // Factory constructor, but getConstRedirectedConstructor returned
-          // null.  This can happen if we're visiting one of the special external
-          // const factory constructors in the SDK, or if the code contains
-          // errors (such as delegating to a non-const constructor, or delegating
-          // to a constructor that can't be resolved).  In any of these cases,
-          // we'll evaluate calls to this constructor without having to refer to
-          // any other constants.  So we don't need to report any dependencies.
+          // null.  This can happen if we're visiting one of the special
+          // external const factory constructors in the SDK, or if the code
+          // contains errors (such as delegating to a non-const constructor, or
+          // delegating to a constructor that can't be resolved).  In any of
+          // these cases, we'll evaluate calls to this constructor without
+          // having to refer to any other constants.  So we don't need to report
+          // any dependencies.
           return;
         }
         bool defaultSuperInvocationNeeded = true;
@@ -397,20 +367,19 @@
     } else {
       // Should not happen.
       assert(false);
-      AnalysisEngine.instance.logger.logError(
-          "Constant value computer trying to compute the value of a node of type ${constant.runtimeType}");
+      AnalysisEngine.instance.logger
+          .logError("Constant value computer trying to compute "
+              "the value of a node of type ${constant.runtimeType}");
     }
   }
 
-  /**
-   * Evaluate a call to fromEnvironment() on the bool, int, or String class. The
-   * [environmentValue] is the value fetched from the environment. The
-   * [builtInDefaultValue] is the value that should be used as the default if no
-   * "defaultValue" argument appears in [namedArgumentValues]. The
-   * [namedArgumentValues] are the values of the named parameters passed to
-   * fromEnvironment(). Return a [DartObjectImpl] object corresponding to the
-   * evaluated result.
-   */
+  /// Evaluate a call to fromEnvironment() on the bool, int, or String class.
+  /// The [environmentValue] is the value fetched from the environment. The
+  /// [builtInDefaultValue] is the value that should be used as the default if
+  /// no "defaultValue" argument appears in [namedArgumentValues]. The
+  /// [namedArgumentValues] are the values of the named parameters passed to
+  /// fromEnvironment(). Return a [DartObjectImpl] object corresponding to the
+  /// evaluated result.
   DartObjectImpl computeValueFromEnvironment(
       DartObject environmentValue,
       DartObjectImpl builtInDefaultValue,
@@ -748,7 +717,7 @@
         DartObjectImpl evaluationResult = condition.accept(initializerVisitor);
         if (evaluationResult == null ||
             !evaluationResult.isBool ||
-            evaluationResult.toBoolValue() != true) {
+            evaluationResult.toBoolValue() == false) {
           errorReporter.reportErrorForNode(
               CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION, node);
           return null;
@@ -793,14 +762,12 @@
     }
   }
 
-  /**
-   * Attempt to follow the chain of factory redirections until a constructor is
-   * reached which is not a const factory constructor. Return the constant
-   * constructor which terminates the chain of factory redirections, if the
-   * chain terminates. If there is a problem (e.g. a redirection can't be found,
-   * or a cycle is encountered), the chain will be followed as far as possible
-   * and then a const factory constructor will be returned.
-   */
+  /// Attempt to follow the chain of factory redirections until a constructor is
+  /// reached which is not a const factory constructor. Return the constant
+  /// constructor which terminates the chain of factory redirections, if the
+  /// chain terminates. If there is a problem (e.g. a redirection can't be
+  /// found, or a cycle is encountered), the chain will be followed as far as
+  /// possible and then a const factory constructor will be returned.
   ConstructorElement followConstantRedirectionChain(
       ConstructorElement constructor) {
     HashSet<ConstructorElement> constructorsVisited =
@@ -827,12 +794,10 @@
     return constructor;
   }
 
-  /**
-   * Generate an error indicating that the given [constant] is not a valid
-   * compile-time constant because it references at least one of the constants
-   * in the given [cycle], each of which directly or indirectly references the
-   * constant.
-   */
+  /// Generate an error indicating that the given [constant] is not a valid
+  /// compile-time constant because it references at least one of the constants
+  /// in the given [cycle], each of which directly or indirectly references the
+  /// constant.
   void generateCycleError(Iterable<ConstantEvaluationTarget> cycle,
       ConstantEvaluationTarget constant) {
     if (constant is VariableElement) {
@@ -853,15 +818,14 @@
       // Should not happen.  Formal parameter defaults and annotations should
       // never appear as part of a cycle because they can't be referred to.
       assert(false);
-      AnalysisEngine.instance.logger.logError(
-          "Constant value computer trying to report a cycle error for a node of type ${constant.runtimeType}");
+      AnalysisEngine.instance.logger
+          .logError("Constant value computer trying to report a cycle error "
+              "for a node of type ${constant.runtimeType}");
     }
   }
 
-  /**
-   * If [constructor] redirects to another const constructor, return the
-   * const constructor it redirects to.  Otherwise return `null`.
-   */
+  /// If [constructor] redirects to another const constructor, return the
+  /// const constructor it redirects to.  Otherwise return `null`.
   ConstructorElement getConstRedirectedConstructor(
       ConstructorElement constructor) {
     if (!constructor.isFactory) {
@@ -890,10 +854,8 @@
     return redirectedConstructor;
   }
 
-  /**
-   * Check if the object [obj] matches the type [type] according to runtime type
-   * checking rules.
-   */
+  /// Check if the object [obj] matches the type [type] according to runtime
+  /// type checking rules.
   bool runtimeTypeMatch(DartObjectImpl obj, DartType type) {
     if (obj.isNull) {
       return true;
@@ -919,75 +881,54 @@
     return objType.isSubtypeOf(type);
   }
 
-  /**
-   * Determine whether the given string is a valid name for a public symbol
-   * (i.e. whether it is allowed for a call to the Symbol constructor).
-   */
+  /// Determine whether the given string is a valid name for a public symbol
+  /// (i.e. whether it is allowed for a call to the Symbol constructor).
   static bool isValidPublicSymbol(String name) =>
       name.isEmpty || name == "void" || _PUBLIC_SYMBOL_PATTERN.hasMatch(name);
 }
 
-/**
- * Interface for [AnalysisTarget]s for which constant evaluation can be
- * performed.
- */
+/// Interface for [AnalysisTarget]s for which constant evaluation can be
+/// performed.
 abstract class ConstantEvaluationTarget extends AnalysisTarget {
-  /**
-   * Return the [AnalysisContext] which should be used to evaluate this
-   * constant.
-   */
+  /// Return the [AnalysisContext] which should be used to evaluate this
+  /// constant.
   AnalysisContext get context;
 
-  /**
-   * Return whether this constant is evaluated.
-   */
+  /// Return whether this constant is evaluated.
   bool get isConstantEvaluated;
 }
 
-/**
- * Interface used by unit tests to verify correct dependency analysis during
- * constant evaluation.
- */
+/// Interface used by unit tests to verify correct dependency analysis during
+/// constant evaluation.
 abstract class ConstantEvaluationValidator {
-  /**
-   * This method is called just before computing the constant value associated
-   * with [constant]. Unit tests will override this method to introduce
-   * additional error checking.
-   */
+  /// This method is called just before computing the constant value associated
+  /// with [constant]. Unit tests will override this method to introduce
+  /// additional error checking.
   void beforeComputeValue(ConstantEvaluationTarget constant);
 
-  /**
-   * This method is called just before getting the constant initializers
-   * associated with the [constructor]. Unit tests will override this method to
-   * introduce additional error checking.
-   */
+  /// This method is called just before getting the constant initializers
+  /// associated with the [constructor]. Unit tests will override this method to
+  /// introduce additional error checking.
   void beforeGetConstantInitializers(ConstructorElement constructor);
 
-  /**
-   * This method is called just before retrieving an evaluation result from an
-   * element. Unit tests will override it to introduce additional error
-   * checking.
-   */
+  /// This method is called just before retrieving an evaluation result from an
+  /// element. Unit tests will override it to introduce additional error
+  /// checking.
   void beforeGetEvaluationResult(ConstantEvaluationTarget constant);
 
-  /**
-   * This method is called just before getting the constant value of a field
-   * with an initializer.  Unit tests will override this method to introduce
-   * additional error checking.
-   */
+  /// This method is called just before getting the constant value of a field
+  /// with an initializer.  Unit tests will override this method to introduce
+  /// additional error checking.
   void beforeGetFieldEvaluationResult(FieldElementImpl field);
 
-  /**
-   * This method is called just before getting a parameter's default value. Unit
-   * tests will override this method to introduce additional error checking.
-   */
+  /// This method is called just before getting a parameter's default value.
+  /// Unit tests will override this method to introduce additional error
+  /// checking.
   void beforeGetParameterDefault(ParameterElement parameter);
 }
 
-/**
- * Implementation of [ConstantEvaluationValidator] used in production; does no
- * validation.
- */
+/// Implementation of [ConstantEvaluationValidator] used in production; does no
+/// validation.
 class ConstantEvaluationValidator_ForProduction
     implements ConstantEvaluationValidator {
   @override
@@ -1006,38 +947,28 @@
   void beforeGetParameterDefault(ParameterElement parameter) {}
 }
 
-/**
- * A visitor used to evaluate constant expressions to produce their compile-time
- * value.
- */
+/// A visitor used to evaluate constant expressions to produce their
+/// compile-time value.
 class ConstantVisitor extends UnifyingAstVisitor<DartObjectImpl> {
-  /**
-   * The evaluation engine used to access the feature set, type system, and type
-   * provider.
-   */
+  /// The evaluation engine used to access the feature set, type system, and
+  /// type provider.
   final ConstantEvaluationEngine evaluationEngine;
 
   final Map<String, DartObjectImpl> _lexicalEnvironment;
 
-  /**
-   * Error reporter that we use to report errors accumulated while computing the
-   * constant.
-   */
+  /// Error reporter that we use to report errors accumulated while computing
+  /// the constant.
   final ErrorReporter _errorReporter;
 
-  /**
-   * Helper class used to compute constant values.
-   */
+  /// Helper class used to compute constant values.
   DartObjectComputer _dartObjectComputer;
 
-  /**
-   * Initialize a newly created constant visitor. The [evaluationEngine] is
-   * used to evaluate instance creation expressions. The [lexicalEnvironment]
-   * is a map containing values which should override identifiers, or `null` if
-   * no overriding is necessary. The [_errorReporter] is used to report errors
-   * found during evaluation.  The [validator] is used by unit tests to verify
-   * correct dependency analysis.
-   */
+  /// Initialize a newly created constant visitor. The [evaluationEngine] is
+  /// used to evaluate instance creation expressions. The [lexicalEnvironment]
+  /// is a map containing values which should override identifiers, or `null` if
+  /// no overriding is necessary. The [_errorReporter] is used to report errors
+  /// found during evaluation.  The [validator] is used by unit tests to verify
+  /// correct dependency analysis.
   ConstantVisitor(this.evaluationEngine, this._errorReporter,
       {Map<String, DartObjectImpl> lexicalEnvironment})
       : _lexicalEnvironment = lexicalEnvironment {
@@ -1045,26 +976,18 @@
         new DartObjectComputer(_errorReporter, evaluationEngine);
   }
 
-  /**
-   * Return the object representing the state of active experiments.
-   */
+  /// Return the object representing the state of active experiments.
   ExperimentStatus get experimentStatus => evaluationEngine.experimentStatus;
 
-  /**
-   * Convenience getter to gain access to the [evaluationEngine]'s type system.
-   */
+  /// Convenience getter to gain access to the [evaluationEngine]'s type system.
   TypeSystem get typeSystem => evaluationEngine.typeSystem;
 
-  /**
-   * Convenience getter to gain access to the [evaluationEngine]'s type
-   * provider.
-   */
+  /// Convenience getter to gain access to the [evaluationEngine]'s type
+  /// provider.
   TypeProvider get _typeProvider => evaluationEngine.typeProvider;
 
-  /**
-   * Given a [type] that may contain free type variables, evaluate them against
-   * the current lexical environment and return the substituted type.
-   */
+  /// Given a [type] that may contain free type variables, evaluate them against
+  /// the current lexical environment and return the substituted type.
   DartType evaluateType(DartType type) {
     if (type is TypeParameterType) {
       return null;
@@ -1087,9 +1010,7 @@
     return type;
   }
 
-  /**
-   * Given a [type], returns the constant value that contains that type value.
-   */
+  /// Given a [type], returns the constant value that contains that type value.
   DartObjectImpl typeConstant(DartType type) {
     return new DartObjectImpl(_typeProvider.typeType, new TypeState(type));
   }
@@ -1550,11 +1471,9 @@
   @override
   DartObjectImpl visitTypeName(TypeName node) => visitTypeAnnotation(node);
 
-  /**
-   * Add the entries produced by evaluating the given collection [element] to
-   * the given [list]. Return `true` if the evaluation of one or more of the
-   * elements failed.
-   */
+  /// Add the entries produced by evaluating the given collection [element] to
+  /// the given [list]. Return `true` if the evaluation of one or more of the
+  /// elements failed.
   bool _addElementsToList(List<DartObject> list, CollectionElement element) {
     if (element is IfElement) {
       bool conditionValue = _evaluateCondition(element.condition);
@@ -1586,11 +1505,9 @@
     return true;
   }
 
-  /**
-   * Add the entries produced by evaluating the given map [element] to the given
-   * [map]. Return `true` if the evaluation of one or more of the entries
-   * failed.
-   */
+  /// Add the entries produced by evaluating the given map [element] to the
+  /// given [map]. Return `true` if the evaluation of one or more of the entries
+  /// failed.
   bool _addElementsToMap(
       Map<DartObjectImpl, DartObjectImpl> map, CollectionElement element) {
     if (element is IfElement) {
@@ -1624,11 +1541,9 @@
     return true;
   }
 
-  /**
-   * Add the entries produced by evaluating the given collection [element] to
-   * the given [set]. Return `true` if the evaluation of one or more of the
-   * elements failed.
-   */
+  /// Add the entries produced by evaluating the given collection [element] to
+  /// the given [set]. Return `true` if the evaluation of one or more of the
+  /// elements failed.
   bool _addElementsToSet(Set<DartObject> set, CollectionElement element) {
     if (element is IfElement) {
       bool conditionValue = _evaluateCondition(element.condition);
@@ -1660,10 +1575,8 @@
     return true;
   }
 
-  /**
-   * Create an error associated with the given [node]. The error will have the
-   * given error [code].
-   */
+  /// Create an error associated with the given [node]. The error will have the
+  /// given error [code].
   void _error(AstNode node, ErrorCode code) {
     if (code == null) {
       var parent = node?.parent;
@@ -1680,32 +1593,30 @@
         code ?? CompileTimeErrorCode.INVALID_CONSTANT, node);
   }
 
-  /**
-   * Evaluate the given [condition] with the assumption that it must be a
-   * `bool`.
-   */
+  /// Evaluate the given [condition] with the assumption that it must be a
+  /// `bool`.
   bool _evaluateCondition(Expression condition) {
     DartObjectImpl conditionResult = condition.accept(this);
     bool conditionValue = conditionResult?.toBoolValue();
     if (conditionValue == null) {
-      // TODO(brianwilkerson) Figure out why the static type is sometimes null.
-      DartType staticType = condition.staticType;
-      if (staticType == null ||
-          typeSystem.isAssignableTo(staticType, _typeProvider.boolType)) {
-        // If the static type is not assignable, then we will have already
-        // reported this error.
-        _errorReporter.reportErrorForNode(
-            CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION, condition);
+      if (conditionResult?.type != _typeProvider.boolType) {
+        // TODO(brianwilkerson) Figure out why the static type is sometimes null.
+        DartType staticType = condition.staticType;
+        if (staticType == null ||
+            typeSystem.isAssignableTo(staticType, _typeProvider.boolType)) {
+          // If the static type is not assignable, then we will have already
+          // reported this error.
+          _errorReporter.reportErrorForNode(
+              CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION, condition);
+        }
       }
     }
     return conditionValue;
   }
 
-  /**
-   * Return the constant value of the static constant represented by the given
-   * [element]. The [node] is the node to be used if an error needs to be
-   * reported.
-   */
+  /// Return the constant value of the static constant represented by the given
+  /// [element]. The [node] is the node to be used if an error needs to be
+  /// reported.
   DartObjectImpl _getConstantValue(AstNode node, Element element) {
     Element variableElement =
         element is PropertyAccessorElement ? element.variable : element;
@@ -1740,10 +1651,8 @@
     return null;
   }
 
-  /**
-   * Return `true` if the given [targetResult] represents a string and the
-   * [identifier] is "length".
-   */
+  /// Return `true` if the given [targetResult] represents a string and the
+  /// [identifier] is "length".
   bool _isStringLength(
       DartObjectImpl targetResult, SimpleIdentifier identifier) {
     if (targetResult == null || targetResult.type != _typeProvider.stringType) {
@@ -1764,10 +1673,8 @@
     }
   }
 
-  /**
-   * Return the value of the given [expression], or a representation of 'null'
-   * if the expression cannot be evaluated.
-   */
+  /// Return the value of the given [expression], or a representation of 'null'
+  /// if the expression cannot be evaluated.
   DartObjectImpl _valueOf(Expression expression) {
     DartObjectImpl expressionValue = expression.accept(this);
     if (expressionValue != null) {
@@ -1777,32 +1684,22 @@
   }
 }
 
-/**
- * A utility class that contains methods for manipulating instances of a Dart
- * class and for collecting errors during evaluation.
- */
+/// A utility class that contains methods for manipulating instances of a Dart
+/// class and for collecting errors during evaluation.
 class DartObjectComputer {
-  /**
-   * The error reporter that we are using to collect errors.
-   */
+  /// The error reporter that we are using to collect errors.
   final ErrorReporter _errorReporter;
 
-  /**
-   * The evaluation engine used to access the type system, and type provider.
-   */
+  /// The evaluation engine used to access the type system, and type provider.
   final ConstantEvaluationEngine _evaluationEngine;
 
   DartObjectComputer(this._errorReporter, this._evaluationEngine);
 
-  /**
-   * Convenience getter to gain access to the [evaluationEngine]'s type
-   * provider.
-   */
+  /// Convenience getter to gain access to the [evaluationEngine]'s type
+  /// provider.
   TypeProvider get _typeProvider => _evaluationEngine.typeProvider;
 
-  /**
-   * Convenience getter to gain access to the [evaluationEngine]'s type system.
-   */
+  /// Convenience getter to gain access to the [evaluationEngine]'s type system.
   TypeSystem get _typeSystem => _evaluationEngine.typeSystem;
 
   DartObjectImpl add(BinaryExpression node, DartObjectImpl leftOperand,
@@ -1818,10 +1715,9 @@
     return null;
   }
 
-  /**
-   * Return the result of applying boolean conversion to the [evaluationResult].
-   * The [node] is the node against which errors should be reported.
-   */
+  /// Return the result of applying boolean conversion to the
+  /// [evaluationResult]. The [node] is the node against which errors should be
+  /// reported.
   DartObjectImpl applyBooleanConversion(
       AstNode node, DartObjectImpl evaluationResult) {
     if (evaluationResult != null) {
@@ -2165,11 +2061,9 @@
     return null;
   }
 
-  /**
-   * Return the result of invoking the 'length' getter on the
-   * [evaluationResult]. The [node] is the node against which errors should be
-   * reported.
-   */
+  /// Return the result of invoking the 'length' getter on the
+  /// [evaluationResult]. The [node] is the node against which errors should be
+  /// reported.
   EvaluationResultImpl stringLength(
       Expression node, EvaluationResultImpl evaluationResult) {
     if (evaluationResult.value != null) {
@@ -2213,76 +2107,54 @@
   }
 }
 
-/**
- * The result of attempting to evaluate an expression.
- */
+/// The result of attempting to evaluate an expression.
 class EvaluationResult {
   // TODO(brianwilkerson) Merge with EvaluationResultImpl
-  /**
-   * The value of the expression.
-   */
+  /// The value of the expression.
   final DartObject value;
 
-  /**
-   * The errors that should be reported for the expression(s) that were
-   * evaluated.
-   */
+  /// The errors that should be reported for the expression(s) that were
+  /// evaluated.
   final List<AnalysisError> _errors;
 
-  /**
-   * Initialize a newly created result object with the given [value] and set of
-   * [_errors]. Clients should use one of the factory methods: [forErrors] and
-   * [forValue].
-   */
+  /// Initialize a newly created result object with the given [value] and set of
+  /// [_errors]. Clients should use one of the factory methods: [forErrors] and
+  /// [forValue].
   EvaluationResult(this.value, this._errors);
 
-  /**
-   * Return a list containing the errors that should be reported for the
-   * expression(s) that were evaluated. If there are no such errors, the list
-   * will be empty. The list can be empty even if the expression is not a valid
-   * compile time constant if the errors would have been reported by other parts
-   * of the analysis engine.
-   */
+  /// Return a list containing the errors that should be reported for the
+  /// expression(s) that were evaluated. If there are no such errors, the list
+  /// will be empty. The list can be empty even if the expression is not a valid
+  /// compile time constant if the errors would have been reported by other
+  /// parts of the analysis engine.
   List<AnalysisError> get errors => _errors ?? AnalysisError.NO_ERRORS;
 
-  /**
-   * Return `true` if the expression is a compile-time constant expression that
-   * would not throw an exception when evaluated.
-   */
+  /// Return `true` if the expression is a compile-time constant expression that
+  /// would not throw an exception when evaluated.
   bool get isValid => _errors == null;
 
-  /**
-   * Return an evaluation result representing the result of evaluating an
-   * expression that is not a compile-time constant because of the given
-   * [errors].
-   */
+  /// Return an evaluation result representing the result of evaluating an
+  /// expression that is not a compile-time constant because of the given
+  /// [errors].
   static EvaluationResult forErrors(List<AnalysisError> errors) =>
       new EvaluationResult(null, errors);
 
-  /**
-   * Return an evaluation result representing the result of evaluating an
-   * expression that is a compile-time constant that evaluates to the given
-   * [value].
-   */
+  /// Return an evaluation result representing the result of evaluating an
+  /// expression that is a compile-time constant that evaluates to the given
+  /// [value].
   static EvaluationResult forValue(DartObject value) =>
       new EvaluationResult(value, null);
 }
 
-/**
- * The result of attempting to evaluate a expression.
- */
+/// The result of attempting to evaluate a expression.
 class EvaluationResultImpl {
-  /**
-   * The errors encountered while trying to evaluate the compile time constant.
-   * These errors may or may not have prevented the expression from being a
-   * valid compile time constant.
-   */
+  /// The errors encountered while trying to evaluate the compile time constant.
+  /// These errors may or may not have prevented the expression from being a
+  /// valid compile time constant.
   List<AnalysisError> _errors;
 
-  /**
-   * The value of the expression, or `null` if the value couldn't be computed
-   * due to errors.
-   */
+  /// The value of the expression, or `null` if the value couldn't be computed
+  /// due to errors.
   final DartObjectImpl value;
 
   EvaluationResultImpl(this.value, [List<AnalysisError> errors]) {
diff --git a/pkg/analyzer/lib/src/dart/constant/utilities.dart b/pkg/analyzer/lib/src/dart/constant/utilities.dart
index 60cecdd..e99b3c5 100644
--- a/pkg/analyzer/lib/src/dart/constant/utilities.dart
+++ b/pkg/analyzer/lib/src/dart/constant/utilities.dart
@@ -28,15 +28,11 @@
   return constructor;
 }
 
-/**
- * Callback used by [ReferenceFinder] to report that a dependency was found.
- */
+/// Callback used by [ReferenceFinder] to report that a dependency was found.
 typedef void ReferenceFinderCallback(ConstantEvaluationTarget dependency);
 
-/**
- * An [AstCloner] that copies the necessary information from the AST to allow
- * constants to be evaluated.
- */
+/// An [AstCloner] that copies the necessary information from the AST to allow
+/// constants to be evaluated.
 class ConstantAstCloner extends AstCloner {
   ConstantAstCloner() : super(true);
 
@@ -137,15 +133,11 @@
   }
 }
 
-/**
- * A visitor used to traverse the AST structures of all of the compilation units
- * being resolved and build the full set of dependencies for all constant
- * expressions.
- */
+/// A visitor used to traverse the AST structures of all of the compilation
+/// units being resolved and build the full set of dependencies for all constant
+/// expressions.
 class ConstantExpressionsDependenciesFinder extends RecursiveAstVisitor {
-  /**
-   * The constants whose values need to be computed.
-   */
+  /// The constants whose values need to be computed.
   HashSet<ConstantEvaluationTarget> dependencies =
       new HashSet<ConstantEvaluationTarget>();
 
@@ -204,23 +196,17 @@
   }
 }
 
-/**
- * A visitor used to traverse the AST structures of all of the compilation units
- * being resolved and build tables of the constant variables, constant
- * constructors, constant constructor invocations, and annotations found in
- * those compilation units.
- */
+/// A visitor used to traverse the AST structures of all of the compilation
+/// units being resolved and build tables of the constant variables, constant
+/// constructors, constant constructor invocations, and annotations found in
+/// those compilation units.
 class ConstantFinder extends RecursiveAstVisitor<void> {
-  /**
-   * The elements and AST nodes whose constant values need to be computed.
-   */
+  /// The elements and AST nodes whose constant values need to be computed.
   List<ConstantEvaluationTarget> constantsToCompute =
       <ConstantEvaluationTarget>[];
 
-  /**
-   * A flag indicating whether instance variables marked as "final" should be
-   * treated as "const".
-   */
+  /// A flag indicating whether instance variables marked as "final" should be
+  /// treated as "const".
   bool treatFinalInstanceVarAsConst = false;
 
   @override
@@ -296,22 +282,16 @@
   }
 }
 
-/**
- * An object used to add reference information for a given variable to the
- * bi-directional mapping used to order the evaluation of constants.
- */
+/// An object used to add reference information for a given variable to the
+/// bi-directional mapping used to order the evaluation of constants.
 class ReferenceFinder extends RecursiveAstVisitor<void> {
-  /**
-   * The callback which should be used to report any dependencies that were
-   * found.
-   */
+  /// The callback which should be used to report any dependencies that were
+  /// found.
   final ReferenceFinderCallback _callback;
 
-  /**
-   * Initialize a newly created reference finder to find references from a given
-   * variable to other variables and to add those references to the given graph.
-   * The [_callback] will be invoked for every dependency found.
-   */
+  /// Initialize a newly created reference finder to find references from a
+  /// given variable to other variables and to add those references to the given
+  /// graph. The [_callback] will be invoked for every dependency found.
   ReferenceFinder(this._callback);
 
   @override
diff --git a/pkg/analyzer/lib/src/dart/constant/value.dart b/pkg/analyzer/lib/src/dart/constant/value.dart
index 1b93859..db0ed6f 100644
--- a/pkg/analyzer/lib/src/dart/constant/value.dart
+++ b/pkg/analyzer/lib/src/dart/constant/value.dart
@@ -2,9 +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.
 
-/**
- * The implementation of the class [DartObject].
- */
+/// The implementation of the class [DartObject].
 import 'dart:collection';
 
 import 'package:analyzer/dart/constant/value.dart';
@@ -16,33 +14,21 @@
 import 'package:analyzer/src/generated/type_system.dart';
 import 'package:analyzer/src/generated/utilities_general.dart';
 
-/**
- * The state of an object representing a boolean value.
- */
+/// The state of an object representing a boolean value.
 class BoolState extends InstanceState {
-  /**
-   * An instance representing the boolean value 'false'.
-   */
+  /// An instance representing the boolean value 'false'.
   static BoolState FALSE_STATE = new BoolState(false);
 
-  /**
-   * An instance representing the boolean value 'true'.
-   */
+  /// An instance representing the boolean value 'true'.
   static BoolState TRUE_STATE = new BoolState(true);
 
-  /**
-   * A state that can be used to represent a boolean whose value is not known.
-   */
+  /// A state that can be used to represent a boolean whose value is not known.
   static BoolState UNKNOWN_VALUE = new BoolState(null);
 
-  /**
-   * The value of this instance.
-   */
+  /// The value of this instance.
   final bool value;
 
-  /**
-   * Initialize a newly created state to represent the given [value].
-   */
+  /// Initialize a newly created state to represent the given [value].
   BoolState(this.value);
 
   @override
@@ -92,8 +78,6 @@
         return UNKNOWN_VALUE;
       }
       return BoolState.from(identical(value, rightValue));
-    } else if (rightOperand is DynamicState) {
-      return UNKNOWN_VALUE;
     }
     return FALSE_STATE;
   }
@@ -134,70 +118,50 @@
   @override
   String toString() => value == null ? "-unknown-" : (value ? "true" : "false");
 
-  /**
-   * Return the boolean state representing the given boolean [value].
-   */
+  /// Return the boolean state representing the given boolean [value].
   static BoolState from(bool value) =>
       value ? BoolState.TRUE_STATE : BoolState.FALSE_STATE;
 }
 
-/**
- * Information about a const constructor invocation.
- */
+/// Information about a const constructor invocation.
 class ConstructorInvocation {
-  /**
-   * The constructor that was called.
-   */
+  /// The constructor that was called.
   final ConstructorElement constructor;
 
-  /**
-   * Values of specified arguments, actual values for positional, and `null`
-   * for named (which are provided as [namedArguments]).
-   */
+  /// Values of specified arguments, actual values for positional, and `null`
+  /// for named (which are provided as [namedArguments]).
   final List<DartObjectImpl> _argumentValues;
 
-  /**
-   * The named arguments passed to the constructor.
-   */
+  /// The named arguments passed to the constructor.
   final Map<String, DartObjectImpl> namedArguments;
 
   ConstructorInvocation(
       this.constructor, this._argumentValues, this.namedArguments);
 
-  /**
-   * The positional arguments passed to the constructor.
-   */
+  /// The positional arguments passed to the constructor.
   List<DartObjectImpl> get positionalArguments {
     return _argumentValues.takeWhile((v) => v != null).toList();
   }
 }
 
-/**
- * A representation of an instance of a Dart class.
- */
+/// A representation of an instance of a Dart class.
 class DartObjectImpl implements DartObject {
   /// When `true`, `operator==` only compares constant values, ignoring types.
   ///
   /// This is a temporary hack to work around dartbug.com/35908.
-  /// TODO(paulberry): when #35908 is fixed, remove this hack.
+  // TODO(paulberry): when #35908 is fixed, remove this hack.
   static bool _ignoreTypesInEqualityComparison = false;
 
   @override
   final ParameterizedType type;
 
-  /**
-   * The state of the object.
-   */
+  /// The state of the object.
   final InstanceState _state;
 
-  /**
-   * Initialize a newly created object to have the given [type] and [_state].
-   */
+  /// Initialize a newly created object to have the given [type] and [_state].
   DartObjectImpl(this.type, this._state);
 
-  /**
-   * Create an object to represent an unknown value.
-   */
+  /// Create an object to represent an unknown value.
   factory DartObjectImpl.validWithUnknownValue(ParameterizedType type) {
     if (type.element.library.isDartCore) {
       String typeName = type.name;
@@ -222,34 +186,24 @@
   @override
   bool get hasKnownValue => !_state.isUnknown;
 
-  /**
-   * Return `true` if this object represents an object whose type is 'bool'.
-   */
+  /// Return `true` if this object represents an object whose type is 'bool'.
   bool get isBool => _state.isBool;
 
-  /**
-   * Return `true` if this object represents an object whose type is either
-   * 'bool', 'num', 'String', or 'Null'.
-   */
+  /// Return `true` if this object represents an object whose type is either
+  /// 'bool', 'num', 'String', or 'Null'.
   bool get isBoolNumStringOrNull => _state.isBoolNumStringOrNull;
 
-  /**
-   * Return `true` if this object represents an object whose type is 'int'.
-   */
+  /// Return `true` if this object represents an object whose type is 'int'.
   bool get isInt => _state.isInt;
 
   @override
   bool get isNull => _state is NullState;
 
-  /**
-   * Return `true` if this object represents an unknown value.
-   */
+  /// Return `true` if this object represents an unknown value.
   bool get isUnknown => _state.isUnknown;
 
-  /**
-   * Return `true` if this object represents an instance of a user-defined
-   * class.
-   */
+  /// Return `true` if this object represents an instance of a user-defined
+  /// class.
   bool get isUserDefinedObject => _state is GenericState;
 
   @override
@@ -261,22 +215,18 @@
     return false;
   }
 
-  /**
-   * Return the result of invoking the '+' operator on this object with the
-   * given [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.
-   */
+  /// Return the result of invoking the '+' operator on this object with the
+  /// given [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 add(TypeProvider typeProvider, DartObjectImpl rightOperand) {
     InstanceState result = _state.add(rightOperand._state);
     if (result is IntState) {
       return new DartObjectImpl(typeProvider.intType, result);
     } else if (result is DoubleState) {
       return new DartObjectImpl(typeProvider.doubleType, result);
-    } else if (result is NumState) {
-      return new DartObjectImpl(typeProvider.numType, result);
     } else if (result is StringState) {
       return new DartObjectImpl(typeProvider.stringType, result);
     }
@@ -284,19 +234,15 @@
     throw new StateError("add returned a ${result.runtimeType}");
   }
 
-  /**
-   * Return the result of invoking the '~' operator on this object. 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.
-   */
+  /// Return the result of invoking the '~' operator on this object. 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 bitNot(TypeProvider typeProvider) =>
       new DartObjectImpl(typeProvider.intType, _state.bitNot());
 
-  /**
-   * Return the result of casting this object to the given [castType].
-   */
+  /// Return the result of casting this object to the given [castType].
   DartObjectImpl castToType(TypeProvider typeProvider, TypeSystem typeSystem,
       DartObjectImpl castType) {
     _assertType(castType);
@@ -310,26 +256,22 @@
     return this;
   }
 
-  /**
-   * 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.
-   */
+  /// 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 concatenate(
           TypeProvider typeProvider, DartObjectImpl rightOperand) =>
       new DartObjectImpl(
           typeProvider.stringType, _state.concatenate(rightOperand._state));
 
-  /**
-   * Return the result of applying boolean conversion to this object. 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.
-   */
+  /// Return the result of applying boolean conversion to this object. 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 convertToBool(TypeProvider typeProvider) {
     InterfaceType boolType = typeProvider.boolType;
     if (identical(type, boolType)) {
@@ -338,14 +280,12 @@
     return new DartObjectImpl(boolType, _state.convertToBool());
   }
 
-  /**
-   * 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.
-   */
+  /// 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 divide(
       TypeProvider typeProvider, DartObjectImpl rightOperand) {
     InstanceState result = _state.divide(rightOperand._state);
@@ -353,21 +293,17 @@
       return new DartObjectImpl(typeProvider.intType, result);
     } else if (result is DoubleState) {
       return new DartObjectImpl(typeProvider.doubleType, result);
-    } else if (result is NumState) {
-      return new DartObjectImpl(typeProvider.numType, result);
     }
     // We should never get here.
     throw new StateError("divide returned a ${result.runtimeType}");
   }
 
-  /**
-   * 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.
-   */
+  /// 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 eagerAnd(
       TypeProvider typeProvider, DartObjectImpl rightOperand, bool allowBool) {
     if (allowBool && isBool && rightOperand.isBool) {
@@ -381,14 +317,12 @@
         CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_INT);
   }
 
-  /**
-   * 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.
-   */
+  /// 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 eagerOr(
       TypeProvider typeProvider, DartObjectImpl rightOperand, bool allowBool) {
     if (allowBool && isBool && rightOperand.isBool) {
@@ -402,14 +336,12 @@
         CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_INT);
   }
 
-  /**
-   * 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.
-   */
+  /// 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 eagerXor(
       TypeProvider typeProvider, DartObjectImpl rightOperand, bool allowBool) {
     if (allowBool && isBool && rightOperand.isBool) {
@@ -423,14 +355,12 @@
         CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_INT);
   }
 
-  /**
-   * 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.
-   */
+  /// 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 equalEqual(
       TypeProvider typeProvider, DartObjectImpl rightOperand) {
     if (isNull || rightOperand.isNull) {
@@ -467,35 +397,30 @@
     return null;
   }
 
-  /**
-   * Return the result of invoking the '&gt;' 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.
-   */
+  /// Return the result of invoking the '&gt;' 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 greaterThan(
           TypeProvider typeProvider, DartObjectImpl rightOperand) =>
       new DartObjectImpl(
           typeProvider.boolType, _state.greaterThan(rightOperand._state));
 
-  /**
-   * Return the result of invoking the '&gt;=' 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.
-   */
+  /// Return the result of invoking the '&gt;=' 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 greaterThanOrEqual(
           TypeProvider typeProvider, DartObjectImpl rightOperand) =>
       new DartObjectImpl(typeProvider.boolType,
           _state.greaterThanOrEqual(rightOperand._state));
 
-  /**
-   * Return the result of testing whether this object has the given [testedType].
-   */
+  /// Return the result of testing whether this object has the given
+  /// [testedType].
   DartObjectImpl hasType(TypeProvider typeProvider, TypeSystem typeSystem,
       DartObjectImpl testedType) {
     _assertType(testedType);
@@ -515,14 +440,12 @@
     return new DartObjectImpl(typeProvider.boolType, 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.
-   */
+  /// 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 integerDivide(
           TypeProvider typeProvider, DartObjectImpl rightOperand) =>
       new DartObjectImpl(
@@ -532,7 +455,7 @@
   /// object and sub-objects.
   ///
   /// This is a temporary hack to work around dartbug.com/35908.
-  /// TODO(paulberry): when #35908 is fixed, remove this hack.
+  // TODO(paulberry): when #35908 is fixed, remove this hack.
   bool isEqualIgnoringTypesRecursively(Object other) {
     bool oldIgnoreTypesInEqualityComparison = _ignoreTypesInEqualityComparison;
     _ignoreTypesInEqualityComparison = true;
@@ -543,38 +466,32 @@
     }
   }
 
-  /**
-   * Return the result of invoking the identical function on this object with
-   * the [rightOperand]. The [typeProvider] is the type provider used to find
-   * known types.
-   */
+  /// Return the result of invoking the identical function on this object with
+  /// the [rightOperand]. The [typeProvider] is the type provider used to find
+  /// known types.
   DartObjectImpl isIdentical(
       TypeProvider typeProvider, DartObjectImpl rightOperand) {
     return new DartObjectImpl(
         typeProvider.boolType, _state.isIdentical(rightOperand._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.
-   */
+  /// 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 lazyAnd(
           TypeProvider typeProvider, DartObjectImpl rightOperandComputer()) =>
       new DartObjectImpl(typeProvider.boolType,
           _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.
-   */
+  /// 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) {
@@ -592,129 +509,107 @@
         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.
-   *
-   * Throws an [EvaluationException] if the operator is not appropriate for an
-   * object of this kind.
-   */
+  /// 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 lazyOr(
           TypeProvider typeProvider, DartObjectImpl rightOperandComputer()) =>
       new DartObjectImpl(typeProvider.boolType,
           _state.lazyOr(() => rightOperandComputer()?._state));
 
-  /**
-   * Return the result of invoking the '&lt;' 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.
-   */
+  /// Return the result of invoking the '&lt;' 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 lessThan(
           TypeProvider typeProvider, DartObjectImpl rightOperand) =>
       new DartObjectImpl(
           typeProvider.boolType, _state.lessThan(rightOperand._state));
 
-  /**
-   * Return the result of invoking the '&lt;=' 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.
-   */
+  /// Return the result of invoking the '&lt;=' 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 lessThanOrEqual(
           TypeProvider typeProvider, DartObjectImpl rightOperand) =>
       new DartObjectImpl(
           typeProvider.boolType, _state.lessThanOrEqual(rightOperand._state));
 
-  /**
-   * Return the result of invoking the '!' operator on this object. 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.
-   */
+  /// Return the result of invoking the '!' operator on this object. 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 logicalNot(TypeProvider typeProvider) =>
       new DartObjectImpl(typeProvider.boolType, _state.logicalNot());
 
-  /**
-   * Return the result of invoking the '&gt;&gt;&gt;' 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.
-   */
+  /// Return the result of invoking the '&gt;&gt;&gt;' 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 logicalShiftRight(
           TypeProvider typeProvider, DartObjectImpl rightOperand) =>
       new DartObjectImpl(
           typeProvider.intType, _state.logicalShiftRight(rightOperand._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.
-   */
+  /// 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 minus(TypeProvider typeProvider, DartObjectImpl rightOperand) {
     InstanceState result = _state.minus(rightOperand._state);
     if (result is IntState) {
       return new DartObjectImpl(typeProvider.intType, result);
     } else if (result is DoubleState) {
       return new DartObjectImpl(typeProvider.doubleType, result);
-    } else if (result is NumState) {
-      return new DartObjectImpl(typeProvider.numType, result);
     }
     // We should never get here.
     throw new StateError("minus returned a ${result.runtimeType}");
   }
 
-  /**
-   * Return the result of invoking the '-' operator on this object. 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.
-   */
+  /// Return the result of invoking the '-' operator on this object. 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 negated(TypeProvider typeProvider) {
     InstanceState result = _state.negated();
     if (result is IntState) {
       return new DartObjectImpl(typeProvider.intType, result);
     } else if (result is DoubleState) {
       return new DartObjectImpl(typeProvider.doubleType, result);
-    } else if (result is NumState) {
-      return new DartObjectImpl(typeProvider.numType, result);
     }
     // We should never get here.
     throw new StateError("negated returned a ${result.runtimeType}");
   }
 
-  /**
-   * 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.
-   */
+  /// 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 notEqual(
       TypeProvider typeProvider, DartObjectImpl rightOperand) {
     return equalEqual(typeProvider, rightOperand).logicalNot(typeProvider);
   }
 
-  /**
-   * Return the result of converting this object to a 'String'. The
-   * [typeProvider] is the type provider used to find known types.
-   *
-   * Throws an [EvaluationException] if the object cannot be converted to a
-   * 'String'.
-   */
+  /// Return the result of converting this object to a 'String'. The
+  /// [typeProvider] is the type provider used to find known types.
+  ///
+  /// Throws an [EvaluationException] if the object cannot be converted to a
+  /// 'String'.
   DartObjectImpl performToString(TypeProvider typeProvider) {
     InterfaceType stringType = typeProvider.stringType;
     if (identical(type, stringType)) {
@@ -723,14 +618,12 @@
     return new DartObjectImpl(stringType, _state.convertToString());
   }
 
-  /**
-   * 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.
-   */
+  /// 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 remainder(
       TypeProvider typeProvider, DartObjectImpl rightOperand) {
     InstanceState result = _state.remainder(rightOperand._state);
@@ -738,65 +631,53 @@
       return new DartObjectImpl(typeProvider.intType, result);
     } else if (result is DoubleState) {
       return new DartObjectImpl(typeProvider.doubleType, result);
-    } else if (result is NumState) {
-      return new DartObjectImpl(typeProvider.numType, result);
     }
     // We should never get here.
     throw new StateError("remainder returned a ${result.runtimeType}");
   }
 
-  /**
-   * Return the result of invoking the '&lt;&lt;' 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.
-   */
+  /// Return the result of invoking the '&lt;&lt;' 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 shiftLeft(
           TypeProvider typeProvider, DartObjectImpl rightOperand) =>
       new DartObjectImpl(
           typeProvider.intType, _state.shiftLeft(rightOperand._state));
 
-  /**
-   * Return the result of invoking the '&gt;&gt;' 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.
-   */
+  /// Return the result of invoking the '&gt;&gt;' 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 shiftRight(
           TypeProvider typeProvider, DartObjectImpl rightOperand) =>
       new DartObjectImpl(
           typeProvider.intType, _state.shiftRight(rightOperand._state));
 
-  /**
-   * Return the result of invoking the 'length' getter on this object. 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.
-   */
+  /// Return the result of invoking the 'length' getter on this object. 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 stringLength(TypeProvider typeProvider) =>
       new DartObjectImpl(typeProvider.intType, _state.stringLength());
 
-  /**
-   * 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.
-   */
+  /// 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 times(TypeProvider typeProvider, DartObjectImpl rightOperand) {
     InstanceState result = _state.times(rightOperand._state);
     if (result is IntState) {
       return new DartObjectImpl(typeProvider.intType, result);
     } else if (result is DoubleState) {
       return new DartObjectImpl(typeProvider.doubleType, result);
-    } else if (result is NumState) {
-      return new DartObjectImpl(typeProvider.numType, result);
     }
     // We should never get here.
     throw new StateError("times returned a ${result.runtimeType}");
@@ -820,10 +701,8 @@
     return null;
   }
 
-  /**
-   * If this constant represents a library function or static method, returns
-   * it, otherwise returns `null`.
-   */
+  /// If this constant represents a library function or static method, returns
+  /// it, otherwise returns `null`.
   ExecutableElement toFunctionValue() {
     InstanceState state = _state;
     return state is FunctionState ? state._element : null;
@@ -895,10 +774,8 @@
     return null;
   }
 
-  /**
-   * Throw an exception if the given [object]'s state does not represent a Type
-   * value.
-   */
+  /// Throw an exception if the given [object]'s state does not represent a Type
+  /// value.
   void _assertType(DartObjectImpl object) {
     if (object._state is! TypeState) {
       throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_TYPE_TYPE);
@@ -906,33 +783,22 @@
   }
 }
 
-/**
- * The state of an object representing a double.
- */
+/// The state of an object representing a double.
 class DoubleState extends NumState {
-  /**
-   * A state that can be used to represent a double whose value is not known.
-   */
+  /// A state that can be used to represent a double whose value is not known.
   static DoubleState UNKNOWN_VALUE = new DoubleState(null);
 
-  /**
-   * The value of this instance.
-   */
+  /// The value of this instance.
   final double value;
 
-  /**
-   * Initialize a newly created state to represent a double with the given
-   * [value].
-   */
+  /// Initialize a newly created state to represent a double with the given
+  /// [value].
   DoubleState(this.value);
 
   @override
   int get hashCode => value == null ? 0 : value.hashCode;
 
   @override
-  bool get isBoolNumStringOrNull => true;
-
-  @override
   bool get isUnknown => value == null;
 
   @override
@@ -960,8 +826,6 @@
         return UNKNOWN_VALUE;
       }
       return new DoubleState(value + rightValue);
-    } else if (rightOperand is DynamicState || rightOperand is NumState) {
-      return UNKNOWN_VALUE;
     }
     throw new EvaluationException(
         CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
@@ -993,20 +857,12 @@
         return UNKNOWN_VALUE;
       }
       return new DoubleState(value / rightValue);
-    } else if (rightOperand is DynamicState || rightOperand is NumState) {
-      return UNKNOWN_VALUE;
     }
     throw new EvaluationException(
         CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
   }
 
   @override
-  BoolState equalEqual(InstanceState rightOperand) {
-    assertBoolNumStringOrNull(rightOperand);
-    return isIdentical(rightOperand);
-  }
-
-  @override
   BoolState greaterThan(InstanceState rightOperand) {
     assertNumOrNull(rightOperand);
     if (value == null) {
@@ -1024,8 +880,6 @@
         return BoolState.UNKNOWN_VALUE;
       }
       return BoolState.from(value > rightValue);
-    } else if (rightOperand is DynamicState || rightOperand is NumState) {
-      return BoolState.UNKNOWN_VALUE;
     }
     throw new EvaluationException(
         CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
@@ -1049,8 +903,6 @@
         return BoolState.UNKNOWN_VALUE;
       }
       return BoolState.from(value >= rightValue);
-    } else if (rightOperand is DynamicState || rightOperand is NumState) {
-      return BoolState.UNKNOWN_VALUE;
     }
     throw new EvaluationException(
         CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
@@ -1076,8 +928,6 @@
       }
       double result = value / rightValue;
       return new IntState(result.toInt());
-    } else if (rightOperand is DynamicState || rightOperand is NumState) {
-      return IntState.UNKNOWN_VALUE;
     }
     throw new EvaluationException(
         CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
@@ -1100,8 +950,6 @@
         return BoolState.UNKNOWN_VALUE;
       }
       return BoolState.from(value == rightValue.toDouble());
-    } else if (rightOperand is DynamicState || rightOperand is NumState) {
-      return BoolState.UNKNOWN_VALUE;
     }
     return BoolState.FALSE_STATE;
   }
@@ -1129,8 +977,6 @@
         return BoolState.UNKNOWN_VALUE;
       }
       return BoolState.from(value < rightValue);
-    } else if (rightOperand is DynamicState || rightOperand is NumState) {
-      return BoolState.UNKNOWN_VALUE;
     }
     throw new EvaluationException(
         CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
@@ -1154,8 +1000,6 @@
         return BoolState.UNKNOWN_VALUE;
       }
       return BoolState.from(value <= rightValue);
-    } else if (rightOperand is DynamicState || rightOperand is NumState) {
-      return BoolState.UNKNOWN_VALUE;
     }
     throw new EvaluationException(
         CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
@@ -1179,8 +1023,6 @@
         return UNKNOWN_VALUE;
       }
       return new DoubleState(value - rightValue);
-    } else if (rightOperand is DynamicState || rightOperand is NumState) {
-      return UNKNOWN_VALUE;
     }
     throw new EvaluationException(
         CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
@@ -1212,8 +1054,6 @@
         return UNKNOWN_VALUE;
       }
       return new DoubleState(value % rightValue);
-    } else if (rightOperand is DynamicState || rightOperand is NumState) {
-      return UNKNOWN_VALUE;
     }
     throw new EvaluationException(
         CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
@@ -1237,8 +1077,6 @@
         return UNKNOWN_VALUE;
       }
       return new DoubleState(value * rightValue);
-    } else if (rightOperand is DynamicState || rightOperand is NumState) {
-      return UNKNOWN_VALUE;
     }
     throw new EvaluationException(
         CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
@@ -1248,207 +1086,22 @@
   String toString() => value == null ? "-unknown-" : value.toString();
 }
 
-/**
- * The state of an object representing a Dart object for which there is no type
- * information.
- */
-class DynamicState extends InstanceState {
-  /**
-   * The unique instance of this class.
-   */
-  static DynamicState DYNAMIC_STATE = new DynamicState();
-
-  @override
-  bool get isBool => true;
-
-  @override
-  bool get isBoolNumStringOrNull => true;
-
-  @override
-  String get typeName => "dynamic";
-
-  @override
-  NumState add(InstanceState rightOperand) {
-    assertNumOrNull(rightOperand);
-    return _unknownNum(rightOperand);
-  }
-
-  @override
-  IntState bitAnd(InstanceState rightOperand) {
-    assertIntOrNull(rightOperand);
-    return IntState.UNKNOWN_VALUE;
-  }
-
-  @override
-  IntState bitNot() => IntState.UNKNOWN_VALUE;
-
-  @override
-  IntState bitOr(InstanceState rightOperand) {
-    assertIntOrNull(rightOperand);
-    return IntState.UNKNOWN_VALUE;
-  }
-
-  @override
-  IntState bitXor(InstanceState rightOperand) {
-    assertIntOrNull(rightOperand);
-    return IntState.UNKNOWN_VALUE;
-  }
-
-  @override
-  StringState concatenate(InstanceState rightOperand) {
-    assertString(rightOperand);
-    return StringState.UNKNOWN_VALUE;
-  }
-
-  @override
-  BoolState convertToBool() => BoolState.UNKNOWN_VALUE;
-
-  @override
-  StringState convertToString() => StringState.UNKNOWN_VALUE;
-
-  @override
-  NumState divide(InstanceState rightOperand) {
-    assertNumOrNull(rightOperand);
-    return _unknownNum(rightOperand);
-  }
-
-  @override
-  BoolState equalEqual(InstanceState rightOperand) {
-    assertBoolNumStringOrNull(rightOperand);
-    return BoolState.UNKNOWN_VALUE;
-  }
-
-  @override
-  BoolState greaterThan(InstanceState rightOperand) {
-    assertNumOrNull(rightOperand);
-    return BoolState.UNKNOWN_VALUE;
-  }
-
-  @override
-  BoolState greaterThanOrEqual(InstanceState rightOperand) {
-    assertNumOrNull(rightOperand);
-    return BoolState.UNKNOWN_VALUE;
-  }
-
-  @override
-  IntState integerDivide(InstanceState rightOperand) {
-    assertNumOrNull(rightOperand);
-    return IntState.UNKNOWN_VALUE;
-  }
-
-  @override
-  BoolState isIdentical(InstanceState rightOperand) {
-    return BoolState.UNKNOWN_VALUE;
-  }
-
-  @override
-  BoolState lazyAnd(InstanceState rightOperandComputer()) {
-    assertBool(rightOperandComputer());
-    return BoolState.UNKNOWN_VALUE;
-  }
-
-  @override
-  BoolState lazyEqualEqual(InstanceState rightOperand) {
-    return BoolState.UNKNOWN_VALUE;
-  }
-
-  @override
-  BoolState lazyOr(InstanceState rightOperandComputer()) {
-    InstanceState rightOperand = rightOperandComputer();
-    assertBool(rightOperand);
-    return rightOperand.convertToBool();
-  }
-
-  @override
-  BoolState lessThan(InstanceState rightOperand) {
-    assertNumOrNull(rightOperand);
-    return BoolState.UNKNOWN_VALUE;
-  }
-
-  @override
-  BoolState lessThanOrEqual(InstanceState rightOperand) {
-    assertNumOrNull(rightOperand);
-    return BoolState.UNKNOWN_VALUE;
-  }
-
-  @override
-  BoolState logicalNot() => BoolState.UNKNOWN_VALUE;
-
-  @override
-  NumState minus(InstanceState rightOperand) {
-    assertNumOrNull(rightOperand);
-    return _unknownNum(rightOperand);
-  }
-
-  @override
-  NumState negated() => NumState.UNKNOWN_VALUE;
-
-  @override
-  NumState remainder(InstanceState rightOperand) {
-    assertNumOrNull(rightOperand);
-    return _unknownNum(rightOperand);
-  }
-
-  @override
-  IntState shiftLeft(InstanceState rightOperand) {
-    assertIntOrNull(rightOperand);
-    return IntState.UNKNOWN_VALUE;
-  }
-
-  @override
-  IntState shiftRight(InstanceState rightOperand) {
-    assertIntOrNull(rightOperand);
-    return IntState.UNKNOWN_VALUE;
-  }
-
-  @override
-  NumState times(InstanceState rightOperand) {
-    assertNumOrNull(rightOperand);
-    return _unknownNum(rightOperand);
-  }
-
-  /**
-   * Return an object representing an unknown numeric value whose type is based
-   * on the type of the [rightOperand].
-   */
-  NumState _unknownNum(InstanceState rightOperand) {
-    if (rightOperand is IntState) {
-      return IntState.UNKNOWN_VALUE;
-    } else if (rightOperand is DoubleState) {
-      return DoubleState.UNKNOWN_VALUE;
-    }
-    return NumState.UNKNOWN_VALUE;
-  }
-}
-
-/**
- * Exception that would be thrown during the evaluation of Dart code.
- */
+/// Exception that would be thrown during the evaluation of Dart code.
 class EvaluationException {
-  /**
-   * The error code associated with the exception.
-   */
+  /// The error code associated with the exception.
   final ErrorCode errorCode;
 
-  /**
-   * Initialize a newly created exception to have the given [errorCode].
-   */
+  /// Initialize a newly created exception to have the given [errorCode].
   EvaluationException(this.errorCode);
 }
 
-/**
- * The state of an object representing a function.
- */
+/// The state of an object representing a function.
 class FunctionState extends InstanceState {
-  /**
-   * The element representing the function being modeled.
-   */
+  /// The element representing the function being modeled.
   final ExecutableElement _element;
 
-  /**
-   * Initialize a newly created state to represent the function with the given
-   * [element].
-   */
+  /// Initialize a newly created state to represent the function with the given
+  /// [element].
   FunctionState(this._element);
 
   @override
@@ -1485,8 +1138,6 @@
         return BoolState.UNKNOWN_VALUE;
       }
       return BoolState.from(_element == rightElement);
-    } else if (rightOperand is DynamicState) {
-      return BoolState.UNKNOWN_VALUE;
     }
     return BoolState.FALSE_STATE;
   }
@@ -1500,36 +1151,24 @@
   String toString() => _element == null ? "-unknown-" : _element.name;
 }
 
-/**
- * The state of an object representing a Dart object for which there is no more
- * specific state.
- */
+/// The state of an object representing a Dart object for which there is no more
+/// specific state.
 class GenericState extends InstanceState {
-  /**
-   * Pseudo-field that we use to represent fields in the superclass.
-   */
+  /// Pseudo-field that we use to represent fields in the superclass.
   static String SUPERCLASS_FIELD = "(super)";
 
-  /**
-   * A state that can be used to represent an object whose state is not known.
-   */
+  /// A state that can be used to represent an object whose state is not known.
   static GenericState UNKNOWN_VALUE =
       new GenericState(new HashMap<String, DartObjectImpl>());
 
-  /**
-   * The values of the fields of this instance.
-   */
+  /// The values of the fields of this instance.
   final Map<String, DartObjectImpl> _fieldMap;
 
-  /**
-   * Information about the constructor invoked to generate this instance.
-   */
+  /// Information about the constructor invoked to generate this instance.
   final ConstructorInvocation invocation;
 
-  /**
-   * Initialize a newly created state to represent a newly created object. The
-   * [fieldMap] contains the values of the fields of the instance.
-   */
+  /// Initialize a newly created state to represent a newly created object. The
+  /// [fieldMap] contains the values of the fields of the instance.
   GenericState(this._fieldMap, {this.invocation});
 
   @override
@@ -1582,9 +1221,6 @@
 
   @override
   BoolState isIdentical(InstanceState rightOperand) {
-    if (rightOperand is DynamicState) {
-      return BoolState.UNKNOWN_VALUE;
-    }
     return BoolState.from(this == rightOperand);
   }
 
@@ -1613,54 +1249,36 @@
   }
 }
 
-/**
- * The state of an object representing a Dart object.
- */
+/// The state of an object representing a Dart object.
 abstract class InstanceState {
-  /**
-   * If this represents a generic dart object, return a map from its field names
-   * to their values. Otherwise return null.
-   */
+  /// If this represents a generic dart object, return a map from its field
+  /// names to their values. Otherwise return null.
   Map<String, DartObjectImpl> get fields => null;
 
-  /**
-   * Return `true` if this object represents an object whose type is 'bool'.
-   */
+  /// Return `true` if this object represents an object whose type is 'bool'.
   bool get isBool => false;
 
-  /**
-   * Return `true` if this object represents an object whose type is either
-   * 'bool', 'num', 'String', or 'Null'.
-   */
+  /// Return `true` if this object represents an object whose type is either
+  /// 'bool', 'num', 'String', or 'Null'.
   bool get isBoolNumStringOrNull => false;
 
-  /**
-   * Return `true` if this object represents an object whose type is 'int'.
-   */
+  /// Return `true` if this object represents an object whose type is 'int'.
   bool get isInt => false;
 
-  /**
-   * Return `true` if this object represents the value 'null'.
-   */
+  /// Return `true` if this object represents the value 'null'.
   bool get isNull => false;
 
-  /**
-   * Return `true` if this object represents an unknown value.
-   */
+  /// Return `true` if this object represents an unknown value.
   bool get isUnknown => false;
 
-  /**
-   * Return the name of the type of this value.
-   */
+  /// Return the name of the type of this value.
   String get typeName;
 
-  /**
-   * 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.
-   */
+  /// 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.
   InstanceState add(InstanceState rightOperand) {
     if (this is StringState && rightOperand is StringState) {
       return concatenate(rightOperand);
@@ -1671,75 +1289,53 @@
         CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
   }
 
-  /**
-   * Throw an exception if the given [state] does not represent a boolean value.
-   */
+  /// Throw an exception if the given [state] does not represent a boolean value.
   void assertBool(InstanceState state) {
-    if (!(state is BoolState || state is DynamicState)) {
+    if (state is! BoolState) {
       throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL);
     }
   }
 
-  /**
-   * Throw an exception if the given [state] does not represent a boolean,
-   * numeric, string or null value.
-   */
+  /// Throw an exception if the given [state] does not represent a boolean,
+  /// numeric, string or null value.
   void assertBoolNumStringOrNull(InstanceState state) {
     if (!(state is BoolState ||
-        state is DoubleState ||
-        state is IntState ||
         state is NumState ||
         state is StringState ||
-        state is NullState ||
-        state is DynamicState)) {
+        state is NullState)) {
       throw new EvaluationException(
           CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING);
     }
   }
 
-  /**
-   * Throw an exception if the given [state] does not represent an integer or
-   * null value.
-   */
+  /// Throw an exception if the given [state] does not represent an integer or
+  /// null value.
   void assertIntOrNull(InstanceState state) {
-    if (!(state is IntState ||
-        state is NumState ||
-        state is NullState ||
-        state is DynamicState)) {
+    if (!(state is IntState || state is NullState)) {
       throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_TYPE_INT);
     }
   }
 
-  /**
-   * Throw an exception if the given [state] does not represent a boolean,
-   * numeric, string or null value.
-   */
+  /// Throw an exception if the given [state] does not represent a boolean,
+  /// numeric, string or null value.
   void assertNumOrNull(InstanceState state) {
-    if (!(state is DoubleState ||
-        state is IntState ||
-        state is NumState ||
-        state is NullState ||
-        state is DynamicState)) {
+    if (!(state is NumState || state is NullState)) {
       throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_TYPE_NUM);
     }
   }
 
-  /**
-   * Throw an exception if the given [state] does not represent a String value.
-   */
+  /// Throw an exception if the given [state] does not represent a String value.
   void assertString(InstanceState state) {
-    if (!(state is StringState || state is DynamicState)) {
+    if (state is! StringState) {
       throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL);
     }
   }
 
-  /**
-   * 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.
-   */
+  /// 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.
   IntState bitAnd(InstanceState rightOperand) {
     assertIntOrNull(this);
     assertIntOrNull(rightOperand);
@@ -1747,25 +1343,21 @@
         CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
   }
 
-  /**
-   * Return the result of invoking the '~' operator on this object.
-   *
-   * Throws an [EvaluationException] if the operator is not appropriate for an
-   * object of this kind.
-   */
+  /// Return the result of invoking the '~' operator on this object.
+  ///
+  /// Throws an [EvaluationException] if the operator is not appropriate for an
+  /// object of this kind.
   IntState bitNot() {
     assertIntOrNull(this);
     throw new EvaluationException(
         CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
   }
 
-  /**
-   * 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.
-   */
+  /// 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.
   IntState bitOr(InstanceState rightOperand) {
     assertIntOrNull(this);
     assertIntOrNull(rightOperand);
@@ -1773,13 +1365,11 @@
         CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
   }
 
-  /**
-   * 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.
-   */
+  /// 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.
   IntState bitXor(InstanceState rightOperand) {
     assertIntOrNull(this);
     assertIntOrNull(rightOperand);
@@ -1787,42 +1377,34 @@
         CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
   }
 
-  /**
-   * 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.
-   */
+  /// 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.
   StringState concatenate(InstanceState rightOperand) {
     assertString(rightOperand);
     throw new EvaluationException(
         CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
   }
 
-  /**
-   * Return the result of applying boolean conversion to this object.
-   *
-   * Throws an [EvaluationException] if the operator is not appropriate for an
-   * object of this kind.
-   */
+  /// Return the result of applying boolean conversion to this object.
+  ///
+  /// Throws an [EvaluationException] if the operator is not appropriate for an
+  /// object of this kind.
   BoolState convertToBool() => BoolState.FALSE_STATE;
 
-  /**
-   * Return the result of converting this object to a String.
-   *
-   * Throws an [EvaluationException] if the operator is not appropriate for an
-   * object of this kind.
-   */
+  /// Return the result of converting this object to a String.
+  ///
+  /// Throws an [EvaluationException] if the operator is not appropriate for an
+  /// object of this kind.
   StringState convertToString();
 
-  /**
-   * 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.
-   */
+  /// 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.
   NumState divide(InstanceState rightOperand) {
     assertNumOrNull(this);
     assertNumOrNull(rightOperand);
@@ -1830,22 +1412,18 @@
         CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
   }
 
-  /**
-   * 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.
-   */
+  /// 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 equalEqual(InstanceState rightOperand);
 
-  /**
-   * Return the result of invoking the '&gt;' operator on this object with the
-   * [rightOperand].
-   *
-   * Throws an [EvaluationException] if the operator is not appropriate for an
-   * object of this kind.
-   */
+  /// Return the result of invoking the '&gt;' operator on this object with the
+  /// [rightOperand].
+  ///
+  /// Throws an [EvaluationException] if the operator is not appropriate for an
+  /// object of this kind.
   BoolState greaterThan(InstanceState rightOperand) {
     assertNumOrNull(this);
     assertNumOrNull(rightOperand);
@@ -1853,13 +1431,11 @@
         CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
   }
 
-  /**
-   * Return the result of invoking the '&gt;=' operator on this object with the
-   * [rightOperand].
-   *
-   * Throws an [EvaluationException] if the operator is not appropriate for an
-   * object of this kind.
-   */
+  /// Return the result of invoking the '&gt;=' operator on this object with the
+  /// [rightOperand].
+  ///
+  /// Throws an [EvaluationException] if the operator is not appropriate for an
+  /// object of this kind.
   BoolState greaterThanOrEqual(InstanceState rightOperand) {
     assertNumOrNull(this);
     assertNumOrNull(rightOperand);
@@ -1867,13 +1443,11 @@
         CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
   }
 
-  /**
-   * 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.
-   */
+  /// 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.
   IntState integerDivide(InstanceState rightOperand) {
     assertNumOrNull(this);
     assertNumOrNull(rightOperand);
@@ -1881,19 +1455,15 @@
         CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
   }
 
-  /**
-   * Return the result of invoking the identical function on this object with
-   * the [rightOperand].
-   */
+  /// Return the result of invoking the identical function on this object with
+  /// the [rightOperand].
   BoolState isIdentical(InstanceState rightOperand);
 
-  /**
-   * 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.
-   */
+  /// 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 lazyAnd(InstanceState rightOperandComputer()) {
     assertBool(this);
     if (convertToBool() == BoolState.FALSE_STATE) {
@@ -1904,22 +1474,18 @@
     return rightOperand.convertToBool();
   }
 
-  /**
-   * 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.
-   */
+  /// 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].
-   *
-   * Throws an [EvaluationException] if the operator is not appropriate for an
-   * object of this kind.
-   */
+  /// 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 lazyOr(InstanceState rightOperandComputer()) {
     assertBool(this);
     if (convertToBool() == BoolState.TRUE_STATE) {
@@ -1930,13 +1496,11 @@
     return rightOperand.convertToBool();
   }
 
-  /**
-   * Return the result of invoking the '&lt;' operator on this object with the
-   * [rightOperand].
-   *
-   * Throws an [EvaluationException] if the operator is not appropriate for an
-   * object of this kind.
-   */
+  /// Return the result of invoking the '&lt;' operator on this object with the
+  /// [rightOperand].
+  ///
+  /// Throws an [EvaluationException] if the operator is not appropriate for an
+  /// object of this kind.
   BoolState lessThan(InstanceState rightOperand) {
     assertNumOrNull(this);
     assertNumOrNull(rightOperand);
@@ -1944,13 +1508,11 @@
         CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
   }
 
-  /**
-   * Return the result of invoking the '&lt;=' operator on this object with the
-   * [rightOperand].
-   *
-   * Throws an [EvaluationException] if the operator is not appropriate for an
-   * object of this kind.
-   */
+  /// Return the result of invoking the '&lt;=' operator on this object with the
+  /// [rightOperand].
+  ///
+  /// Throws an [EvaluationException] if the operator is not appropriate for an
+  /// object of this kind.
   BoolState lessThanOrEqual(InstanceState rightOperand) {
     assertNumOrNull(this);
     assertNumOrNull(rightOperand);
@@ -1958,13 +1520,11 @@
         CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
   }
 
-  /**
-   * 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.
-   */
+  /// 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 logicalAnd(InstanceState rightOperand) {
     assertBool(this);
     assertBool(rightOperand);
@@ -1976,24 +1536,20 @@
     return BoolState.from(leftValue & rightValue);
   }
 
-  /**
-   * Return the result of invoking the '!' operator on this object.
-   *
-   * Throws an [EvaluationException] if the operator is not appropriate for an
-   * object of this kind.
-   */
+  /// Return the result of invoking the '!' operator on this object.
+  ///
+  /// Throws an [EvaluationException] if the operator is not appropriate for an
+  /// object of this kind.
   BoolState logicalNot() {
     assertBool(this);
     return BoolState.TRUE_STATE;
   }
 
-  /**
-   * 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.
-   */
+  /// 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 logicalOr(InstanceState rightOperand) {
     assertBool(this);
     assertBool(rightOperand);
@@ -2005,13 +1561,11 @@
     return BoolState.from(leftValue | rightValue);
   }
 
-  /**
-   * Return the result of invoking the '&gt;&gt;' operator on this object with
-   * the [rightOperand].
-   *
-   * Throws an [EvaluationException] if the operator is not appropriate for an
-   * object of this kind.
-   */
+  /// Return the result of invoking the '&gt;&gt;' operator on this object with
+  /// the [rightOperand].
+  ///
+  /// Throws an [EvaluationException] if the operator is not appropriate for an
+  /// object of this kind.
   IntState logicalShiftRight(InstanceState rightOperand) {
     assertIntOrNull(this);
     assertIntOrNull(rightOperand);
@@ -2019,13 +1573,11 @@
         CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
   }
 
-  /**
-   * 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.
-   */
+  /// 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 logicalXor(InstanceState rightOperand) {
     assertBool(this);
     assertBool(rightOperand);
@@ -2037,13 +1589,11 @@
     return BoolState.from(leftValue ^ rightValue);
   }
 
-  /**
-   * 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.
-   */
+  /// 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.
   NumState minus(InstanceState rightOperand) {
     assertNumOrNull(this);
     assertNumOrNull(rightOperand);
@@ -2051,25 +1601,21 @@
         CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
   }
 
-  /**
-   * Return the result of invoking the '-' operator on this object.
-   *
-   * Throws an [EvaluationException] if the operator is not appropriate for an
-   * object of this kind.
-   */
+  /// Return the result of invoking the '-' operator on this object.
+  ///
+  /// Throws an [EvaluationException] if the operator is not appropriate for an
+  /// object of this kind.
   NumState negated() {
     assertNumOrNull(this);
     throw new EvaluationException(
         CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
   }
 
-  /**
-   * 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.
-   */
+  /// 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.
   NumState remainder(InstanceState rightOperand) {
     assertNumOrNull(this);
     assertNumOrNull(rightOperand);
@@ -2077,13 +1623,11 @@
         CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
   }
 
-  /**
-   * Return the result of invoking the '&lt;&lt;' operator on this object with
-   * the [rightOperand].
-   *
-   * Throws an [EvaluationException] if the operator is not appropriate for an
-   * object of this kind.
-   */
+  /// Return the result of invoking the '&lt;&lt;' operator on this object with
+  /// the [rightOperand].
+  ///
+  /// Throws an [EvaluationException] if the operator is not appropriate for an
+  /// object of this kind.
   IntState shiftLeft(InstanceState rightOperand) {
     assertIntOrNull(this);
     assertIntOrNull(rightOperand);
@@ -2091,13 +1635,11 @@
         CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
   }
 
-  /**
-   * Return the result of invoking the '&gt;&gt;' operator on this object with
-   * the [rightOperand].
-   *
-   * Throws an [EvaluationException] if the operator is not appropriate for an
-   * object of this kind.
-   */
+  /// Return the result of invoking the '&gt;&gt;' operator on this object with
+  /// the [rightOperand].
+  ///
+  /// Throws an [EvaluationException] if the operator is not appropriate for an
+  /// object of this kind.
   IntState shiftRight(InstanceState rightOperand) {
     assertIntOrNull(this);
     assertIntOrNull(rightOperand);
@@ -2105,25 +1647,21 @@
         CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
   }
 
-  /**
-   * Return the result of invoking the 'length' getter on this object.
-   *
-   * Throws an [EvaluationException] if the operator is not appropriate for an
-   * object of this kind.
-   */
+  /// Return the result of invoking the 'length' getter on this object.
+  ///
+  /// Throws an [EvaluationException] if the operator is not appropriate for an
+  /// object of this kind.
   IntState stringLength() {
     assertString(this);
     throw new EvaluationException(
         CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
   }
 
-  /**
-   * 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.
-   */
+  /// 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.
   NumState times(InstanceState rightOperand) {
     assertNumOrNull(this);
     assertNumOrNull(rightOperand);
@@ -2132,33 +1670,22 @@
   }
 }
 
-/**
- * The state of an object representing an int.
- */
+/// The state of an object representing an int.
 class IntState extends NumState {
-  /**
-   * A state that can be used to represent an int whose value is not known.
-   */
+  /// A state that can be used to represent an int whose value is not known.
   static IntState UNKNOWN_VALUE = new IntState(null);
 
-  /**
-   * The value of this instance.
-   */
+  /// The value of this instance.
   final int value;
 
-  /**
-   * Initialize a newly created state to represent an int with the given
-   * [value].
-   */
+  /// Initialize a newly created state to represent an int with the given
+  /// [value].
   IntState(this.value);
 
   @override
   int get hashCode => value == null ? 0 : value.hashCode;
 
   @override
-  bool get isBoolNumStringOrNull => true;
-
-  @override
   bool get isInt => true;
 
   @override
@@ -2192,8 +1719,6 @@
         return DoubleState.UNKNOWN_VALUE;
       }
       return new DoubleState(value.toDouble() + rightValue);
-    } else if (rightOperand is DynamicState || rightOperand is NumState) {
-      return UNKNOWN_VALUE;
     }
     throw new EvaluationException(
         CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
@@ -2211,8 +1736,6 @@
         return UNKNOWN_VALUE;
       }
       return new IntState(value & rightValue);
-    } else if (rightOperand is DynamicState || rightOperand is NumState) {
-      return UNKNOWN_VALUE;
     }
     throw new EvaluationException(
         CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
@@ -2238,8 +1761,6 @@
         return UNKNOWN_VALUE;
       }
       return new IntState(value | rightValue);
-    } else if (rightOperand is DynamicState || rightOperand is NumState) {
-      return UNKNOWN_VALUE;
     }
     throw new EvaluationException(
         CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
@@ -2257,8 +1778,6 @@
         return UNKNOWN_VALUE;
       }
       return new IntState(value ^ rightValue);
-    } else if (rightOperand is DynamicState || rightOperand is NumState) {
-      return UNKNOWN_VALUE;
     }
     throw new EvaluationException(
         CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
@@ -2291,20 +1810,12 @@
         return DoubleState.UNKNOWN_VALUE;
       }
       return new DoubleState(value.toDouble() / rightValue);
-    } else if (rightOperand is DynamicState || rightOperand is NumState) {
-      return DoubleState.UNKNOWN_VALUE;
     }
     throw new EvaluationException(
         CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
   }
 
   @override
-  BoolState equalEqual(InstanceState rightOperand) {
-    assertBoolNumStringOrNull(rightOperand);
-    return isIdentical(rightOperand);
-  }
-
-  @override
   BoolState greaterThan(InstanceState rightOperand) {
     assertNumOrNull(rightOperand);
     if (value == null) {
@@ -2322,8 +1833,6 @@
         return BoolState.UNKNOWN_VALUE;
       }
       return BoolState.from(value.toDouble() > rightValue);
-    } else if (rightOperand is DynamicState || rightOperand is NumState) {
-      return BoolState.UNKNOWN_VALUE;
     }
     throw new EvaluationException(
         CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
@@ -2347,8 +1856,6 @@
         return BoolState.UNKNOWN_VALUE;
       }
       return BoolState.from(value.toDouble() >= rightValue);
-    } else if (rightOperand is DynamicState || rightOperand is NumState) {
-      return BoolState.UNKNOWN_VALUE;
     }
     throw new EvaluationException(
         CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
@@ -2376,8 +1883,6 @@
       }
       double result = value.toDouble() / rightValue;
       return new IntState(result.toInt());
-    } else if (rightOperand is DynamicState || rightOperand is NumState) {
-      return UNKNOWN_VALUE;
     }
     throw new EvaluationException(
         CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
@@ -2400,8 +1905,6 @@
         return BoolState.UNKNOWN_VALUE;
       }
       return BoolState.from(rightValue == value.toDouble());
-    } else if (rightOperand is DynamicState || rightOperand is NumState) {
-      return BoolState.UNKNOWN_VALUE;
     }
     return BoolState.FALSE_STATE;
   }
@@ -2429,8 +1932,6 @@
         return BoolState.UNKNOWN_VALUE;
       }
       return BoolState.from(value.toDouble() < rightValue);
-    } else if (rightOperand is DynamicState || rightOperand is NumState) {
-      return BoolState.UNKNOWN_VALUE;
     }
     throw new EvaluationException(
         CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
@@ -2454,8 +1955,6 @@
         return BoolState.UNKNOWN_VALUE;
       }
       return BoolState.from(value.toDouble() <= rightValue);
-    } else if (rightOperand is DynamicState || rightOperand is NumState) {
-      return BoolState.UNKNOWN_VALUE;
     }
     throw new EvaluationException(
         CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
@@ -2487,8 +1986,6 @@
         }
         return new IntState(value ~/ divisor);
       }
-    } else if (rightOperand is DynamicState || rightOperand is NumState) {
-      return UNKNOWN_VALUE;
     }
     throw new EvaluationException(
         CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
@@ -2515,8 +2012,6 @@
         return DoubleState.UNKNOWN_VALUE;
       }
       return new DoubleState(value.toDouble() - rightValue);
-    } else if (rightOperand is DynamicState || rightOperand is NumState) {
-      return UNKNOWN_VALUE;
     }
     throw new EvaluationException(
         CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
@@ -2553,8 +2048,6 @@
         return DoubleState.UNKNOWN_VALUE;
       }
       return new DoubleState(value.toDouble() % rightValue);
-    } else if (rightOperand is DynamicState || rightOperand is NumState) {
-      return UNKNOWN_VALUE;
     }
     throw new EvaluationException(
         CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
@@ -2576,8 +2069,6 @@
       if (rightValue >= 0) {
         return new IntState(value << rightValue);
       }
-    } else if (rightOperand is DynamicState || rightOperand is NumState) {
-      return UNKNOWN_VALUE;
     }
     throw new EvaluationException(
         CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
@@ -2599,8 +2090,6 @@
       if (rightValue >= 0) {
         return new IntState(value >> rightValue);
       }
-    } else if (rightOperand is DynamicState || rightOperand is NumState) {
-      return UNKNOWN_VALUE;
     }
     throw new EvaluationException(
         CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
@@ -2627,8 +2116,6 @@
         return DoubleState.UNKNOWN_VALUE;
       }
       return new DoubleState(value.toDouble() * rightValue);
-    } else if (rightOperand is DynamicState || rightOperand is NumState) {
-      return UNKNOWN_VALUE;
     }
     throw new EvaluationException(
         CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
@@ -2638,19 +2125,13 @@
   String toString() => value == null ? "-unknown-" : value.toString();
 }
 
-/**
- * The state of an object representing a list.
- */
+/// The state of an object representing a list.
 class ListState extends InstanceState {
-  /**
-   * The elements of the list.
-   */
+  /// The elements of the list.
   final List<DartObjectImpl> _elements;
 
-  /**
-   * Initialize a newly created state to represent a list with the given
-   * [elements].
-   */
+  /// Initialize a newly created state to represent a list with the given
+  /// [elements].
   ListState(this._elements);
 
   @override
@@ -2697,9 +2178,6 @@
 
   @override
   BoolState isIdentical(InstanceState rightOperand) {
-    if (rightOperand is DynamicState) {
-      return BoolState.UNKNOWN_VALUE;
-    }
     return BoolState.from(this == rightOperand);
   }
 
@@ -2726,19 +2204,13 @@
   }
 }
 
-/**
- * The state of an object representing a map.
- */
+/// The state of an object representing a map.
 class MapState extends InstanceState {
-  /**
-   * The entries in the map.
-   */
+  /// The entries in the map.
   final Map<DartObjectImpl, DartObjectImpl> _entries;
 
-  /**
-   * Initialize a newly created state to represent a map with the given
-   * [entries].
-   */
+  /// Initialize a newly created state to represent a map with the given
+  /// [entries].
   MapState(this._entries);
 
   @override
@@ -2786,9 +2258,6 @@
 
   @override
   BoolState isIdentical(InstanceState rightOperand) {
-    if (rightOperand is DynamicState) {
-      return BoolState.UNKNOWN_VALUE;
-    }
     return BoolState.from(this == rightOperand);
   }
 
@@ -2817,13 +2286,9 @@
   }
 }
 
-/**
- * The state of an object representing the value 'null'.
- */
+/// The state of an object representing the value 'null'.
 class NullState extends InstanceState {
-  /**
-   * An instance representing the boolean value 'null'.
-   */
+  /// An instance representing the boolean value 'null'.
   static NullState NULL_STATE = new NullState();
 
   @override
@@ -2858,9 +2323,6 @@
 
   @override
   BoolState isIdentical(InstanceState rightOperand) {
-    if (rightOperand is DynamicState) {
-      return BoolState.UNKNOWN_VALUE;
-    }
     return BoolState.from(rightOperand is NullState);
   }
 
@@ -2879,140 +2341,25 @@
   String toString() => "null";
 }
 
-/**
- * The state of an object representing a number of an unknown type (a 'num').
- */
-class NumState extends InstanceState {
-  /**
-   * A state that can be used to represent a number whose value is not known.
-   */
-  static NumState UNKNOWN_VALUE = new NumState();
-
-  @override
-  int get hashCode => 7;
-
+/// The state of an object representing a number.
+abstract class NumState extends InstanceState {
   @override
   bool get isBoolNumStringOrNull => true;
 
   @override
-  bool get isUnknown => identical(this, UNKNOWN_VALUE);
-
-  @override
-  String get typeName => "num";
-
-  @override
-  bool operator ==(Object object) => object is NumState;
-
-  @override
-  NumState add(InstanceState rightOperand) {
-    assertNumOrNull(rightOperand);
-    return UNKNOWN_VALUE;
-  }
-
-  @override
-  StringState convertToString() => StringState.UNKNOWN_VALUE;
-
-  @override
-  NumState divide(InstanceState rightOperand) {
-    assertNumOrNull(rightOperand);
-    return DoubleState.UNKNOWN_VALUE;
-  }
-
-  @override
   BoolState equalEqual(InstanceState rightOperand) {
     assertBoolNumStringOrNull(rightOperand);
-    return BoolState.UNKNOWN_VALUE;
+    return isIdentical(rightOperand);
   }
-
-  @override
-  BoolState greaterThan(InstanceState rightOperand) {
-    assertNumOrNull(rightOperand);
-    return BoolState.UNKNOWN_VALUE;
-  }
-
-  @override
-  BoolState greaterThanOrEqual(InstanceState rightOperand) {
-    assertNumOrNull(rightOperand);
-    return BoolState.UNKNOWN_VALUE;
-  }
-
-  @override
-  IntState integerDivide(InstanceState rightOperand) {
-    assertNumOrNull(rightOperand);
-    if (rightOperand is IntState) {
-      int rightValue = rightOperand.value;
-      if (rightValue == null) {
-        return IntState.UNKNOWN_VALUE;
-      } else if (rightValue == 0) {
-        throw new EvaluationException(
-            CompileTimeErrorCode.CONST_EVAL_THROWS_IDBZE);
-      }
-    } else if (rightOperand is DynamicState) {
-      return IntState.UNKNOWN_VALUE;
-    }
-    return IntState.UNKNOWN_VALUE;
-  }
-
-  @override
-  BoolState isIdentical(InstanceState rightOperand) {
-    return BoolState.UNKNOWN_VALUE;
-  }
-
-  @override
-  BoolState lazyEqualEqual(InstanceState rightOperand) {
-    return BoolState.UNKNOWN_VALUE;
-  }
-
-  @override
-  BoolState lessThan(InstanceState rightOperand) {
-    assertNumOrNull(rightOperand);
-    return BoolState.UNKNOWN_VALUE;
-  }
-
-  @override
-  BoolState lessThanOrEqual(InstanceState rightOperand) {
-    assertNumOrNull(rightOperand);
-    return BoolState.UNKNOWN_VALUE;
-  }
-
-  @override
-  NumState minus(InstanceState rightOperand) {
-    assertNumOrNull(rightOperand);
-    return UNKNOWN_VALUE;
-  }
-
-  @override
-  NumState negated() => UNKNOWN_VALUE;
-
-  @override
-  NumState remainder(InstanceState rightOperand) {
-    assertNumOrNull(rightOperand);
-    return UNKNOWN_VALUE;
-  }
-
-  @override
-  NumState times(InstanceState rightOperand) {
-    assertNumOrNull(rightOperand);
-    return UNKNOWN_VALUE;
-  }
-
-  @override
-  String toString() => "-unknown-";
 }
 
-/**
- * The state of an object representing a set.
- */
+/// The state of an object representing a set.
 class SetState extends InstanceState {
-  /**
-   * The elements of the set.
-   */
+  /// The elements of the set.
   final Set<DartObjectImpl> _elements;
 
-  /**
-   * Initialize a newly created state to represent a set with the given
-   * [elements].
-   */
+  /// Initialize a newly created state to represent a set with the given
+  /// [elements].
   SetState(this._elements);
 
   @override
@@ -3059,9 +2406,6 @@
 
   @override
   BoolState isIdentical(InstanceState rightOperand) {
-    if (rightOperand is DynamicState) {
-      return BoolState.UNKNOWN_VALUE;
-    }
     return BoolState.from(this == rightOperand);
   }
 
@@ -3088,23 +2432,15 @@
   }
 }
 
-/**
- * The state of an object representing a string.
- */
+/// The state of an object representing a string.
 class StringState extends InstanceState {
-  /**
-   * A state that can be used to represent a double whose value is not known.
-   */
+  /// A state that can be used to represent a double whose value is not known.
   static StringState UNKNOWN_VALUE = new StringState(null);
 
-  /**
-   * The value of this instance.
-   */
+  /// The value of this instance.
   final String value;
 
-  /**
-   * Initialize a newly created state to represent the given [value].
-   */
+  /// Initialize a newly created state to represent the given [value].
   StringState(this.value);
 
   @override
@@ -3134,8 +2470,6 @@
         return UNKNOWN_VALUE;
       }
       return new StringState("$value$rightValue");
-    } else if (rightOperand is DynamicState) {
-      return UNKNOWN_VALUE;
     }
     return super.concatenate(rightOperand);
   }
@@ -3160,8 +2494,6 @@
         return BoolState.UNKNOWN_VALUE;
       }
       return BoolState.from(value == rightValue);
-    } else if (rightOperand is DynamicState) {
-      return BoolState.UNKNOWN_VALUE;
     }
     return BoolState.FALSE_STATE;
   }
@@ -3183,18 +2515,12 @@
   String toString() => value == null ? "-unknown-" : "'$value'";
 }
 
-/**
- * The state of an object representing a symbol.
- */
+/// The state of an object representing a symbol.
 class SymbolState extends InstanceState {
-  /**
-   * The value of this instance.
-   */
+  /// The value of this instance.
   final String value;
 
-  /**
-   * Initialize a newly created state to represent the given [value].
-   */
+  /// Initialize a newly created state to represent the given [value].
   SymbolState(this.value);
 
   @override
@@ -3232,8 +2558,6 @@
         return BoolState.UNKNOWN_VALUE;
       }
       return BoolState.from(value == rightValue);
-    } else if (rightOperand is DynamicState) {
-      return BoolState.UNKNOWN_VALUE;
     }
     return BoolState.FALSE_STATE;
   }
@@ -3247,18 +2571,12 @@
   String toString() => value == null ? "-unknown-" : "#$value";
 }
 
-/**
- * The state of an object representing a type.
- */
+/// The state of an object representing a type.
 class TypeState extends InstanceState {
-  /**
-   * The element representing the type being modeled.
-   */
+  /// The element representing the type being modeled.
   final DartType _type;
 
-  /**
-   * Initialize a newly created state to represent the given [value].
-   */
+  /// Initialize a newly created state to represent the given [value].
   TypeState(this._type);
 
   @override
@@ -3296,8 +2614,6 @@
         return BoolState.UNKNOWN_VALUE;
       }
       return BoolState.from(_type == rightType);
-    } else if (rightOperand is DynamicState) {
-      return BoolState.UNKNOWN_VALUE;
     }
     return BoolState.FALSE_STATE;
   }
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index 9bad2c1..3543c8e 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -5585,11 +5585,7 @@
         var function = context.getGeneticTypeAliasFunction(linkedNode);
         if (function != null) {
           var reference = context.getGenericFunctionTypeReference(function);
-          return _function = GenericFunctionTypeElementImpl.forLinkedNode(
-            this,
-            reference,
-            function,
-          );
+          return _function = reference.element;
         } else {
           return null;
         }
@@ -6254,6 +6250,9 @@
   /// The context of the defining unit.
   final LinkedUnitContext linkedContext;
 
+  @override
+  final bool isNonNullableByDefault;
+
   /// The compilation unit that defines this library.
   CompilationUnitElement _definingCompilationUnit;
 
@@ -6304,8 +6303,8 @@
 
   /// Initialize a newly created library element in the given [context] to have
   /// the given [name] and [offset].
-  LibraryElementImpl(
-      this.context, this.session, String name, int offset, this.nameLength)
+  LibraryElementImpl(this.context, this.session, String name, int offset,
+      this.nameLength, this.isNonNullableByDefault)
       : resynthesizerContext = null,
         unlinkedDefiningUnit = null,
         linkedContext = null,
@@ -6322,6 +6321,7 @@
       CompilationUnit linkedNode)
       : resynthesizerContext = null,
         unlinkedDefiningUnit = null,
+        isNonNullableByDefault = linkedContext.isNNBD,
         super.forLinkedNode(null, reference, linkedNode) {
     _name = name;
     _nameOffset = offset;
@@ -6333,7 +6333,8 @@
 
   /// Initialize a newly created library element in the given [context] to have
   /// the given [name].
-  LibraryElementImpl.forNode(this.context, this.session, LibraryIdentifier name)
+  LibraryElementImpl.forNode(this.context, this.session, LibraryIdentifier name,
+      this.isNonNullableByDefault)
       : nameLength = name != null ? name.length : 0,
         resynthesizerContext = null,
         unlinkedDefiningUnit = null,
@@ -6350,6 +6351,7 @@
       this.resynthesizerContext,
       this.unlinkedDefiningUnit)
       : linkedContext = null,
+        isNonNullableByDefault = unlinkedDefiningUnit.isNNBD,
         super.forSerialized(null) {
     _name = name;
     _nameOffset = offset;
@@ -7815,6 +7817,30 @@
   }
 }
 
+/// The synthetic element representing the declaration of the type `Never`.
+class NeverElementImpl extends ElementImpl implements TypeDefiningElement {
+  /// Return the unique instance of this class.
+  static NeverElementImpl get instance =>
+      BottomTypeImpl.instance.element as NeverElementImpl;
+
+  @override
+  BottomTypeImpl type;
+
+  /// Initialize a newly created instance of this class. Instances of this class
+  /// should <b>not</b> be created except as part of creating the type
+  /// associated with this element. The single instance of this class should be
+  /// accessed through the method [instance].
+  NeverElementImpl() : super('Never', -1) {
+    setModifier(Modifier.SYNTHETIC, true);
+  }
+
+  @override
+  ElementKind get kind => ElementKind.NEVER;
+
+  @override
+  T accept<T>(ElementVisitor<T> visitor) => null;
+}
+
 /// A [VariableElementImpl], which is not a parameter.
 abstract class NonParameterVariableElementImpl extends VariableElementImpl {
   /// The unlinked representation of the variable in the summary.
@@ -7897,10 +7923,11 @@
   FunctionElement get initializer {
     if (_initializer == null) {
       if (linkedNode != null) {
-        if (linkedContext.readInitializer(linkedNode) != null) {
+        if (linkedContext.hasInitializer(linkedNode)) {
           _initializer = new FunctionElementImpl('', -1)
             ..isSynthetic = true
-            .._type = FunctionTypeImpl.synthetic(type, [], []);
+            .._type = FunctionTypeImpl.synthetic(type, [], [])
+            ..enclosingElement = this;
         }
       }
       if (_unlinkedVariable != null) {
@@ -8220,7 +8247,7 @@
   FunctionElement get initializer {
     if (_initializer == null) {
       if (linkedNode != null) {
-        if (linkedContext.readInitializer(linkedNode) != null) {
+        if (linkedContext.hasDefaultValue(linkedNode)) {
           _initializer = new FunctionElementImpl('', -1)..isSynthetic = true;
         }
       }
@@ -9545,6 +9572,10 @@
   }
 
   TypeParameterType get type {
+    // Note: TypeParameterElement.type has nullability suffix `star` regardless
+    // of whether it appears in a migrated library.  This is because for type
+    // parameters of synthetic function types, the ancestor chain is broken and
+    // we can't find the enclosing library to tell whether it is migrated.
     return _type ??= new TypeParameterTypeImpl(this);
   }
 
diff --git a/pkg/analyzer/lib/src/dart/element/handle.dart b/pkg/analyzer/lib/src/dart/element/handle.dart
index f316eb7..67f745c 100644
--- a/pkg/analyzer/lib/src/dart/element/handle.dart
+++ b/pkg/analyzer/lib/src/dart/element/handle.dart
@@ -894,6 +894,9 @@
   LibraryElement get actualElement => super.actualElement as LibraryElement;
 
   @override
+  bool get isNonNullableByDefault => actualElement.isNonNullableByDefault;
+
+  @override
   CompilationUnitElement get definingCompilationUnit =>
       actualElement.definingCompilationUnit;
 
diff --git a/pkg/analyzer/lib/src/dart/element/type.dart b/pkg/analyzer/lib/src/dart/element/type.dart
index 9b55e2c..ec7f129 100644
--- a/pkg/analyzer/lib/src/dart/element/type.dart
+++ b/pkg/analyzer/lib/src/dart/element/type.dart
@@ -63,7 +63,9 @@
   /**
    * Prevent the creation of instances of this class.
    */
-  BottomTypeImpl._() : super(null, "<bottom>");
+  BottomTypeImpl._() : super(new NeverElementImpl(), "Never") {
+    (element as NeverElementImpl).type = this;
+  }
 
   @override
   int get hashCode => 0;
@@ -2919,6 +2921,9 @@
 
   /**
    * Return the same type, but with the given [nullabilitySuffix].
+   *
+   * If the nullability of `this` already matches [nullabilitySuffix], `this`
+   * is returned.
    */
   TypeImpl withNullability(NullabilitySuffix nullabilitySuffix);
 
diff --git a/pkg/analyzer/lib/src/dart/element/wrapped.dart b/pkg/analyzer/lib/src/dart/element/wrapped.dart
index 5a9be7c..ab41831 100644
--- a/pkg/analyzer/lib/src/dart/element/wrapped.dart
+++ b/pkg/analyzer/lib/src/dart/element/wrapped.dart
@@ -426,6 +426,9 @@
   AnalysisContext get context => wrappedLib.context;
 
   @override
+  bool get isNonNullableByDefault => wrappedLib.isNonNullableByDefault;
+
+  @override
   CompilationUnitElement get definingCompilationUnit =>
       wrappedLib.definingCompilationUnit;
 
diff --git a/pkg/analyzer/lib/src/dart/error/hint_codes.dart b/pkg/analyzer/lib/src/dart/error/hint_codes.dart
index 134f410..a4376d3 100644
--- a/pkg/analyzer/lib/src/dart/error/hint_codes.dart
+++ b/pkg/analyzer/lib/src/dart/error/hint_codes.dart
@@ -628,6 +628,13 @@
       correction: "Try updating the SDK constraints.");
 
   /**
+   * The type Never is being used in code that is expected to run on versions of
+   * the SDK that did not support it.
+   */
+  static const HintCode SDK_VERSION_NEVER = const HintCode(
+      'SDK_VERSION_NEVER', "The type Never is not yet supported.");
+
+  /**
    * The for, if or spread element is being used in code that is expected to run
    * on versions of the SDK that did not support them.
    */
diff --git a/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart
index 23844eb..184d379 100644
--- a/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart
@@ -577,15 +577,15 @@
   }
 
   void _setResolution(MethodInvocation node, DartType type) {
-    if (type == _dynamicType || _isCoreFunction(type)) {
-      _setDynamicResolution(node);
-      return;
-    }
-
     // TODO(scheglov) We need this for StaticTypeAnalyzer to run inference.
     // But it seems weird. Do we need to know the raw type of a function?!
     node.methodName.staticType = type;
 
+    if (type == _dynamicType || _isCoreFunction(type)) {
+      _setDynamicResolution(node, setNameTypeToDynamic: false);
+      return;
+    }
+
     if (type is InterfaceType) {
       var call = _inheritance.getMember(type, _nameCall);
       if (call != null && call.element.kind == ElementKind.METHOD) {
diff --git a/pkg/analyzer/lib/src/dart/resolver/scope.dart b/pkg/analyzer/lib/src/dart/resolver/scope.dart
index f1fb360..e2194c6 100644
--- a/pkg/analyzer/lib/src/dart/resolver/scope.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/scope.dart
@@ -7,6 +7,7 @@
 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/element/type.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/java_engine.dart';
 import 'package:analyzer/src/generated/source.dart';
@@ -526,7 +527,7 @@
       for (int i = 0; i < _importedNamespaces.length; i++) {
         Element element = lookup(_importedNamespaces[i]);
         if (element != null) {
-          if (element.library.isInSdk) {
+          if (element is NeverElementImpl || element.library.isInSdk) {
             sdkElements.add(element);
           } else {
             nonSdkElements.add(element);
@@ -725,6 +726,7 @@
     // which is not possible for `dynamic`.
     if (library.isDartCore) {
       definedNames['dynamic'] = DynamicElementImpl.instance;
+      definedNames['Never'] = BottomTypeImpl.instance.element;
     }
 
     return new Namespace(definedNames);
diff --git a/pkg/analyzer/lib/src/dart/scanner/scanner.dart b/pkg/analyzer/lib/src/dart/scanner/scanner.dart
index 616b9fc..b446a32 100644
--- a/pkg/analyzer/lib/src/dart/scanner/scanner.dart
+++ b/pkg/analyzer/lib/src/dart/scanner/scanner.dart
@@ -138,7 +138,11 @@
     lineStarts.add(offset - column + 1);
   }
 
-  Token tokenize() {
+  /// The fasta parser handles error tokens produced by the scanner
+  /// but the old parser used by angular does not
+  /// and expects that scanner errors to be reported by this method.
+  /// Set [reportScannerErrors] `true` when using the old parser.
+  Token tokenize({bool reportScannerErrors = true}) {
     fasta.ScannerResult result = fasta.scanString(_contents,
         configuration: _featureSet != null
             ? buildConfig(_featureSet)
@@ -156,12 +160,19 @@
 
     lineStarts.addAll(result.lineStarts);
     fasta.Token token = result.tokens;
-    // The default recovery strategy used by scanString
-    // places all error tokens at the head of the stream.
-    while (token.type == TokenType.BAD_INPUT) {
-      translateErrorToken(token, reportError);
-      token = token.next;
+
+    // The fasta parser handles error tokens produced by the scanner
+    // but the old parser used by angular does not
+    // and expects that scanner errors to be reported here
+    if (reportScannerErrors) {
+      // The default recovery strategy used by scanString
+      // places all error tokens at the head of the stream.
+      while (token.type == TokenType.BAD_INPUT) {
+        translateErrorToken(token, reportError);
+        token = token.next;
+      }
     }
+
     firstToken = token;
     // Update all token offsets based upon the reader's starting offset
     if (_readerOffset != -1) {
@@ -188,6 +199,8 @@
       featureSet == null
           ? fasta.ScannerConfiguration()
           : fasta.ScannerConfiguration(
+              enableExtensionMethods:
+                  featureSet.isEnabled(Feature.extension_methods),
               enableTripleShift: featureSet.isEnabled(Feature.triple_shift),
               enableNonNullable: featureSet.isEnabled(Feature.non_nullable));
 }
diff --git a/pkg/analyzer/lib/src/generated/declaration_resolver.dart b/pkg/analyzer/lib/src/generated/declaration_resolver.dart
index 31c567f..16e265d 100644
--- a/pkg/analyzer/lib/src/generated/declaration_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/declaration_resolver.dart
@@ -9,6 +9,7 @@
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/exception/exception.dart';
+import 'package:analyzer/src/dart/analysis/driver.dart';
 import 'package:analyzer/src/dart/ast/ast.dart';
 import 'package:analyzer/src/dart/element/builder.dart';
 import 'package:analyzer/src/dart/element/element.dart';
@@ -27,13 +28,17 @@
   /// The compilation unit containing the AST nodes being visited.
   CompilationUnitElementImpl _enclosingUnit;
 
-  /// The type provider used to access the known types.
-  TypeProvider _typeProvider;
-
   /// The [ElementWalker] we are using to keep track of progress through the
   /// element model.
   ElementWalker _walker;
 
+  /// Is `true` if the current [ClassDeclaration] has a const constructor.
+  bool _hasConstConstructor = false;
+
+  /// The number of [GenericFunctionType] nodes that we encountered so far.
+  /// We use it to request the corresponding resolved node.
+  int _nextGenericFunctionTypeId = 0;
+
   DeclarationResolver();
 
   /// Resolve the declarations within the given compilation [unit] to the
@@ -42,7 +47,6 @@
   /// not match each other.
   void resolve(CompilationUnit unit, CompilationUnitElement element) {
     _enclosingUnit = element;
-    _typeProvider = _enclosingUnit.context?.typeProvider;
     _walker = new ElementWalker.forCompilationUnit(element);
     unit.element = element;
     try {
@@ -82,6 +86,14 @@
 
   @override
   void visitClassDeclaration(ClassDeclaration node) {
+    _hasConstConstructor = false;
+    for (var member in node.members) {
+      if (member is ConstructorDeclaration && member.constKeyword != null) {
+        _hasConstConstructor = true;
+        break;
+      }
+    }
+
     ClassElement element = _match(node.name, _walker.getClass());
     _walk(new ElementWalker.forClass(element), () {
       super.visitClassDeclaration(node);
@@ -191,6 +203,10 @@
     super.visitFieldDeclaration(node);
     FieldElement firstFieldElement = node.fields.variables[0].declaredElement;
     resolveMetadata(node, node.metadata, firstFieldElement);
+    if (node.fields.isConst ||
+        !node.isStatic && node.fields.isFinal && _hasConstConstructor) {
+      _consumeGenericFunctionTypeIds(node.fields);
+    }
   }
 
   @override
@@ -273,15 +289,21 @@
     if (_walker.elementBuilder != null) {
       _walker.elementBuilder.visitGenericFunctionType(node);
     } else {
-      DartType type = node.type;
-      if (type != null) {
-        Element element = type.element;
-        if (element is GenericFunctionTypeElement) {
-          _setGenericFunctionType(node.returnType, element.returnType);
-          _walk(new ElementWalker.forGenericFunctionType(element), () {
-            super.visitGenericFunctionType(node);
-          });
-        }
+      Element element;
+      if (AnalysisDriver.useSummary2 && _enclosingUnit.linkedContext != null) {
+        var id = _nextGenericFunctionTypeId++;
+        var context = _enclosingUnit.linkedContext;
+        var linkedNode = context.getGenericFunctionType(id);
+        element = linkedNode.declaredElement;
+        (node as GenericFunctionTypeImpl).declaredElement = element;
+      } else {
+        element = node.type?.element;
+      }
+      if (element is GenericFunctionTypeElement) {
+        _setGenericFunctionType(node.returnType, element.returnType);
+        _walk(new ElementWalker.forGenericFunctionType(element), () {
+          super.visitGenericFunctionType(node);
+        });
       }
     }
   }
@@ -426,11 +448,15 @@
     super.visitTopLevelVariableDeclaration(node);
     VariableElement firstElement = node.variables.variables[0].declaredElement;
     resolveMetadata(node, node.metadata, firstElement);
+    if (node.variables.isConst) {
+      _consumeGenericFunctionTypeIds(node.variables);
+    }
   }
 
   @override
   void visitTypeParameter(TypeParameter node) {
-    if (node.parent.parent is FunctionTypedFormalParameter) {
+    if (node.parent.parent is FunctionTypedFormalParameter &&
+        !AnalysisDriver.useSummary2) {
       // Work around dartbug.com/28515.
       // TODO(paulberry): remove this once dartbug.com/28515 is fixed.
       var element = new TypeParameterElementImpl.forNode(node.name);
@@ -476,6 +502,14 @@
     }
   }
 
+  /// See [_ConsumeGenericFunctionTypeIdsVisitor].
+  void _consumeGenericFunctionTypeIds(VariableDeclarationList node) {
+    if (AnalysisDriver.useSummary2) {
+      var visitor = _ConsumeGenericFunctionTypeIdsVisitor(this);
+      node.variables.accept(visitor);
+    }
+  }
+
   /// Updates [identifier] to point to [element], after ensuring that the
   /// element has the expected name.
   ///
@@ -951,6 +985,24 @@
   static bool _isNotSynthetic(Element e) => !e.isSynthetic;
 }
 
+/// For consistency we set identifiers for [GenericFunctionType]s in constant
+/// variable initializers, and instance final fields of classes with constant
+/// constructors. However [DeclarationResolver] does not visit these
+/// initializers, in builds separate local elements. We still need to consume
+/// them to ensure that identifiers expected by the element model, and by
+/// [DeclarationResolver] match.
+class _ConsumeGenericFunctionTypeIdsVisitor extends RecursiveAstVisitor<void> {
+  final DeclarationResolver resolver;
+
+  _ConsumeGenericFunctionTypeIdsVisitor(this.resolver);
+
+  @override
+  void visitGenericFunctionType(GenericFunctionType node) {
+    resolver._nextGenericFunctionTypeId++;
+    super.visitGenericFunctionType(node);
+  }
+}
+
 class _ElementMismatchException extends AnalysisException {
   /// Creates an exception to refer to the given [compilationUnit], [element],
   /// and [cause].
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index dae105c..a5e2927 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -5,6 +5,7 @@
 import 'dart:collection';
 import "dart:math" as math;
 
+import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/standard_resolution_map.dart';
 import 'package:analyzer/dart/ast/token.dart';
@@ -39,6 +40,16 @@
  */
 class ErrorVerifier extends RecursiveAstVisitor<void> {
   /**
+   * Properties on the object class which are safe to call on nullable types.
+   * 
+   * Note that this must include tear-offs.
+   *
+   * TODO(mfairhurst): Calculate these fields rather than hard-code them.
+   */
+  static final _objectPropertyNames =
+      Set.from(['hashCode', 'runtimeType', 'noSuchMethod', 'toString']);
+
+  /**
    * The error reporter by which errors will be reported.
    */
   final ErrorReporter _errorReporter;
@@ -354,12 +365,14 @@
   @override
   void visitAssertInitializer(AssertInitializer node) {
     _checkForNonBoolExpression(node);
+    _checkForNullableDereference(node.condition);
     super.visitAssertInitializer(node);
   }
 
   @override
   void visitAssertStatement(AssertStatement node) {
     _checkForNonBoolExpression(node);
+    _checkForNullableDereference(node.condition);
     super.visitAssertStatement(node);
   }
 
@@ -545,7 +558,7 @@
 
   @override
   void visitCompilationUnit(CompilationUnit node) {
-    _isNonNullable = (node as CompilationUnitImpl).isNonNullable;
+    _isNonNullable = node.featureSet.isEnabled(Feature.non_nullable);
     _checkDuplicateUnitMembers(node);
     _checkForDeferredPrefixCollisions(node);
     super.visitCompilationUnit(node);
@@ -1053,6 +1066,7 @@
     }
     _checkTypeArguments(node);
     _checkForImplicitDynamicInvoke(node);
+    _checkForNullableDereference(methodName);
     _checkForMissingRequiredParam(
         node.staticInvokeType, node.argumentList, node.methodName);
     if (node.operator?.type != TokenType.QUESTION_PERIOD &&
@@ -1133,8 +1147,7 @@
     }
     String property = node.identifier.name;
     if (node.staticElement is ExecutableElement &&
-        property != 'hashCode' &&
-        property != 'runtimeType') {
+        !_objectPropertyNames.contains(property)) {
       _checkForNullableDereference(node.prefix);
     }
     super.visitPrefixedIdentifier(node);
@@ -1163,8 +1176,7 @@
     _checkForStaticAccessToInstanceMember(typeReference, propertyName);
     _checkForInstanceAccessToStaticMember(typeReference, propertyName);
     if (node.operator?.type != TokenType.QUESTION_PERIOD &&
-        propertyName.name != 'hashCode' &&
-        propertyName.name != 'runtimeType') {
+        !_objectPropertyNames.contains(propertyName.name)) {
       _checkForNullableDereference(node.target);
     }
     _checkForUnnecessaryNullAware(node.target, node.operator);
@@ -5303,7 +5315,7 @@
       return;
     }
     if (type is ParameterizedType) {
-      var element = type.element;
+      var element = typeName.name.staticElement;
       // prepare type parameters
       List<TypeParameterElement> parameterElements;
       if (element is ClassElement) {
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 0f3e861..f66ceb7 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -1485,9 +1485,10 @@
   /// Initialize a newly created dead code verifier that will report dead code
   /// to the given [errorReporter] and will use the given [typeSystem] if one is
   /// provided.
-  DeadCodeVerifier(this._errorReporter, this._isNonNullableUnit,
+  DeadCodeVerifier(this._errorReporter, FeatureSet featureSet,
       {TypeSystem typeSystem})
-      : this._typeSystem = typeSystem ?? new Dart2TypeSystem(null);
+      : this._typeSystem = typeSystem ?? new Dart2TypeSystem(null),
+        _isNonNullableUnit = featureSet.isEnabled(Feature.non_nullable);
 
   @override
   void visitAssignmentExpression(AssignmentExpression node) {
@@ -3401,6 +3402,23 @@
   }
 }
 
+/// A type provider that returns non-nullable versions of the SDK types.
+class NonNullableTypeProvider extends TypeProviderImpl {
+  NonNullableTypeProvider(
+      LibraryElement coreLibrary, LibraryElement asyncLibrary)
+      : super(coreLibrary, asyncLibrary);
+
+  @override
+  InterfaceType _getType(Namespace namespace, String typeName) {
+    InterfaceType type = super._getType(namespace, typeName);
+    if (type == null) {
+      return null;
+    }
+    return (type as TypeImpl).withNullability(NullabilitySuffix.none)
+        as InterfaceType;
+  }
+}
+
 /// Instances of the class `OverrideVerifier` visit all of the declarations in a
 /// compilation unit to verify that if they have an override annotation it is
 /// being used correctly.
@@ -6553,6 +6571,9 @@
     if (element == DynamicElementImpl.instance) {
       _setElement(typeName, element);
       type = DynamicTypeImpl.instance;
+    } else if (element is NeverElementImpl) {
+      _setElement(typeName, element);
+      type = element.type;
     } else if (element is FunctionTypeAliasElement) {
       _setElement(typeName, element);
       type = element.type as TypeImpl;
@@ -6971,14 +6992,13 @@
   Scope libraryScope = null;
   TypeNameResolver typeNameResolver = null;
 
-  TypeParameterBoundsResolver(
-      this.typeSystem, this.library, this.source, this.errorListener,
-      {bool isNonNullableUnit = false})
+  TypeParameterBoundsResolver(this.typeSystem, this.library, this.source,
+      this.errorListener, FeatureSet featureSet)
       : libraryScope = new LibraryScope(library),
         typeNameResolver = new TypeNameResolver(
             typeSystem,
             typeSystem.typeProvider,
-            isNonNullableUnit,
+            featureSet.isEnabled(Feature.non_nullable),
             library,
             source,
             errorListener);
@@ -7231,7 +7251,7 @@
   InterfaceType get mapType;
 
   /// Return the type representing the built-in type 'Never'.
-  InterfaceType get neverType;
+  DartType get neverType;
 
   /// Return a list containing all of the types that cannot be either extended
   /// or implemented.
@@ -7288,11 +7308,11 @@
 abstract class TypeProviderBase implements TypeProvider {
   @override
   List<InterfaceType> get nonSubtypableTypes => <InterfaceType>[
+        boolType,
+        doubleType,
+        intType,
         nullType,
         numType,
-        intType,
-        doubleType,
-        boolType,
         stringType
       ];
 
@@ -7321,18 +7341,12 @@
   /// The type representing the built-in type 'bool'.
   InterfaceType _boolType;
 
-  /// The type representing the type 'bottom'.
-  DartType _bottomType;
-
   /// The type representing the built-in type 'double'.
   InterfaceType _doubleType;
 
   /// The type representing the built-in type 'Deprecated'.
   InterfaceType _deprecatedType;
 
-  /// The type representing the built-in type 'dynamic'.
-  DartType _dynamicType;
-
   /// The type representing the built-in type 'Function'.
   InterfaceType _functionType;
 
@@ -7375,9 +7389,6 @@
   /// An shared object representing the value 'null'.
   DartObjectImpl _nullObject;
 
-  /// The type representing the type 'Never'.
-  InterfaceType _neverType;
-
   /// The type representing the type 'Null'.
   InterfaceType _nullType;
 
@@ -7418,7 +7429,7 @@
   InterfaceType get boolType => _boolType;
 
   @override
-  DartType get bottomType => _bottomType;
+  DartType get bottomType => BottomTypeImpl.instance;
 
   @override
   InterfaceType get deprecatedType => _deprecatedType;
@@ -7427,7 +7438,7 @@
   InterfaceType get doubleType => _doubleType;
 
   @override
-  DartType get dynamicType => _dynamicType;
+  DartType get dynamicType => DynamicTypeImpl.instance;
 
   @override
   InterfaceType get functionType => _functionType;
@@ -7469,7 +7480,7 @@
   InterfaceType get mapType => _mapType;
 
   @override
-  InterfaceType get neverType => _neverType;
+  DartType get neverType => BottomTypeImpl.instance;
 
   @override
   DartObjectImpl get nullObject {
@@ -7509,16 +7520,6 @@
   @override
   InterfaceType get typeType => _typeType;
 
-  InterfaceType _createNever(Namespace namespace) {
-    // TODO(brianwilkerson) Remove this method when the class is defined in the
-    //  SDK.
-    CompilationUnitElement compilationUnit =
-        boolType.element.getAncestor((e) => e is CompilationUnitElement);
-    ClassElementImpl element = ElementFactory.classElement('Never', objectType);
-    element.enclosingElement = compilationUnit;
-    return element.type;
-  }
-
   /// Return the type with the given [typeName] from the given [namespace], or
   /// `null` if there is no class with the given name.
   InterfaceType _getType(Namespace namespace, String typeName) {
@@ -7541,10 +7542,8 @@
         new NamespaceBuilder().createPublicNamespaceForLibrary(asyncLibrary);
 
     _boolType = _getType(coreNamespace, 'bool');
-    _bottomType = BottomTypeImpl.instance;
     _deprecatedType = _getType(coreNamespace, 'Deprecated');
     _doubleType = _getType(coreNamespace, 'double');
-    _dynamicType = DynamicTypeImpl.instance;
     _functionType = _getType(coreNamespace, 'Function');
     _futureOrType = _getType(asyncNamespace, 'FutureOr');
     _futureType = _getType(asyncNamespace, 'Future');
@@ -7552,8 +7551,6 @@
     _iterableType = _getType(coreNamespace, 'Iterable');
     _listType = _getType(coreNamespace, 'List');
     _mapType = _getType(coreNamespace, 'Map');
-    _neverType =
-        _getType(coreNamespace, 'Never') ?? _createNever(coreNamespace);
     _nullType = _getType(coreNamespace, 'Null');
     _numType = _getType(coreNamespace, 'num');
     _objectType = _getType(coreNamespace, 'Object');
@@ -7563,13 +7560,13 @@
     _stringType = _getType(coreNamespace, 'String');
     _symbolType = _getType(coreNamespace, 'Symbol');
     _typeType = _getType(coreNamespace, 'Type');
-    _futureDynamicType = _futureType.instantiate(<DartType>[_dynamicType]);
+    _futureDynamicType = _futureType.instantiate(<DartType>[dynamicType]);
     _futureNullType = _futureType.instantiate(<DartType>[_nullType]);
-    _iterableDynamicType = _iterableType.instantiate(<DartType>[_dynamicType]);
+    _iterableDynamicType = _iterableType.instantiate(<DartType>[dynamicType]);
     _iterableObjectType = _iterableType.instantiate(<DartType>[_objectType]);
     _mapObjectObjectType =
         _mapType.instantiate(<DartType>[_objectType, _objectType]);
-    _streamDynamicType = _streamType.instantiate(<DartType>[_dynamicType]);
+    _streamDynamicType = _streamType.instantiate(<DartType>[dynamicType]);
     // FutureOr<T> is still fairly new, so if we're analyzing an SDK that
     // doesn't have it yet, create an element for it.
     _futureOrType ??= createPlaceholderFutureOr(_futureType, _objectType);
@@ -7661,19 +7658,26 @@
   /// [nameScope] is the scope used to resolve identifiers in the node that will
   /// first be visited.  If `null` or unspecified, a new [LibraryScope] will be
   /// created based on [definingLibrary] and [typeProvider].
+  ///
+  /// Note: in a future release of the analyzer, the [featureSet] parameter will
+  /// be required.
   TypeResolverVisitor(LibraryElement definingLibrary, Source source,
       TypeProvider typeProvider, AnalysisErrorListener errorListener,
       {Scope nameScope,
-      this.isNonNullableUnit: false,
+      @Deprecated('Use featureSet instead') bool isNonNullableUnit: false,
+      FeatureSet featureSet,
       this.mode: TypeResolverMode.everything,
       bool shouldUseWithClauseInferredTypes: true,
       this.shouldSetElementSupertypes: false})
-      : super(definingLibrary, source, typeProvider, errorListener,
+      : isNonNullableUnit = featureSet?.isEnabled(Feature.non_nullable) ??
+            // ignore: deprecated_member_use_from_same_package
+            isNonNullableUnit,
+        super(definingLibrary, source, typeProvider, errorListener,
             nameScope: nameScope) {
     _dynamicType = typeProvider.dynamicType;
     _typeSystem = TypeSystem.create(definingLibrary.context);
     _typeNameResolver = new TypeNameResolver(_typeSystem, typeProvider,
-        isNonNullableUnit, definingLibrary, source, errorListener,
+        this.isNonNullableUnit, definingLibrary, source, errorListener,
         shouldUseWithClauseInferredTypes: shouldUseWithClauseInferredTypes);
   }
 
diff --git a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
index 14f6958..dc2e4ce 100644
--- a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
+++ b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
@@ -41,6 +41,11 @@
   final ResolverVisitor _resolver;
 
   /**
+   * The feature set that should be used to resolve types.
+   */
+  final FeatureSet _featureSet;
+
+  /**
    * The object providing access to the types defined by the language.
    */
   TypeProvider _typeProvider;
@@ -72,16 +77,12 @@
   TypePromotionManager _promoteManager;
 
   /**
-   * Whether NNBD is enabled for this compilation unit.
-   */
-  bool _nonNullableEnabled;
-
-  /**
-   * Initialize a newly created type analyzer.
+   * Initialize a newly created static type analyzer to analyze types for the
+   * [_resolver] based on the
    *
    * @param resolver the resolver driving this participant
    */
-  StaticTypeAnalyzer(this._resolver, FeatureSet featureSet) {
+  StaticTypeAnalyzer(this._resolver, this._featureSet) {
     _typeProvider = _resolver.typeProvider;
     _typeSystem = _resolver.typeSystem;
     _dynamicType = _typeProvider.dynamicType;
@@ -89,10 +90,14 @@
     AnalysisOptionsImpl analysisOptions =
         _resolver.definingLibrary.context.analysisOptions;
     _strictInference = analysisOptions.strictInference;
-    _nonNullableEnabled = featureSet.isEnabled(Feature.non_nullable);
   }
 
   /**
+   * Return `true` if NNBD is enabled for this compilation unit.
+   */
+  bool get _nonNullableEnabled => _featureSet.isEnabled(Feature.non_nullable);
+
+  /**
    * Given a constructor name [node] and a type [type], record an inferred type
    * for the constructor if in strong mode. This is used to fill in any
    * inferred type parameters found by the resolver.
@@ -228,7 +233,7 @@
    */
   @override
   void visitAdjacentStrings(AdjacentStrings node) {
-    _recordStaticType(node, _typeProvider.stringType);
+    _recordStaticType(node, _nonNullable(_typeProvider.stringType));
   }
 
   /**
@@ -310,7 +315,7 @@
       return;
     } else if (operator == TokenType.AMPERSAND_AMPERSAND_EQ ||
         operator == TokenType.BAR_BAR_EQ) {
-      _recordStaticType(node, _typeProvider.boolType);
+      _recordStaticType(node, _nonNullable(_typeProvider.boolType));
     } else {
       ExecutableElement staticMethodElement = node.staticElement;
       DartType staticType = _computeStaticReturnType(staticMethodElement);
@@ -318,7 +323,8 @@
           _getStaticType(node.leftHandSide, read: true),
           operator,
           node.rightHandSide.staticType,
-          staticType);
+          staticType,
+          _featureSet);
       _recordStaticType(node, staticType);
     }
   }
@@ -409,7 +415,8 @@
         node.leftOperand.staticType,
         node.operator.type,
         node.rightOperand.staticType,
-        staticType);
+        staticType,
+        _featureSet);
     _recordStaticType(node, staticType);
   }
 
@@ -419,7 +426,7 @@
    */
   @override
   void visitBooleanLiteral(BooleanLiteral node) {
-    _recordStaticType(node, _typeProvider.boolType);
+    _recordStaticType(node, _nonNullable(_typeProvider.boolType));
   }
 
   /**
@@ -458,7 +465,7 @@
    */
   @override
   void visitDoubleLiteral(DoubleLiteral node) {
-    _recordStaticType(node, _typeProvider.doubleType);
+    _recordStaticType(node, _nonNullable(_typeProvider.doubleType));
   }
 
   @override
@@ -597,9 +604,9 @@
     if (context == null ||
         _typeSystem.isAssignableTo(_typeProvider.intType, context) ||
         !_typeSystem.isAssignableTo(_typeProvider.doubleType, context)) {
-      _recordStaticType(node, _typeProvider.intType);
+      _recordStaticType(node, _nonNullable(_typeProvider.intType));
     } else {
-      _recordStaticType(node, _typeProvider.doubleType);
+      _recordStaticType(node, _nonNullable(_typeProvider.doubleType));
     }
   }
 
@@ -611,7 +618,7 @@
    */
   @override
   void visitIsExpression(IsExpression node) {
-    _recordStaticType(node, _typeProvider.boolType);
+    _recordStaticType(node, _nonNullable(_typeProvider.boolType));
   }
 
   /**
@@ -637,7 +644,9 @@
         }
       }
       _recordStaticType(
-          node, _typeProvider.listType.instantiate(<DartType>[staticType]));
+          node,
+          _nonNullable(
+              _typeProvider.listType.instantiate(<DartType>[staticType])));
       return;
     }
 
@@ -652,6 +661,8 @@
       // in fact had an error above, because it will still attempt to return
       // a type. Perhaps we should record inference from TypeSystem if
       // everything was successful?
+      // TODO(brianwilkerson) Determine whether we need to make the inferred
+      //  type non-nullable here or whether it will already be non-nullable.
       _resolver.inferenceContext.recordInference(node, inferred);
       _recordStaticType(node, inferred);
       return;
@@ -792,13 +803,13 @@
       if (_isNotTypeLiteral(node)) {
         staticType = staticElement.type;
       } else {
-        staticType = _typeProvider.typeType;
+        staticType = _nonNullable(_typeProvider.typeType);
       }
     } else if (staticElement is FunctionTypeAliasElement) {
       if (_isNotTypeLiteral(node)) {
         staticType = staticElement.type;
       } else {
-        staticType = _typeProvider.typeType;
+        staticType = _nonNullable(_typeProvider.typeType);
       }
     } else if (staticElement is MethodElement) {
       staticType = staticElement.type;
@@ -828,7 +839,7 @@
   void visitPrefixExpression(PrefixExpression node) {
     TokenType operator = node.operator.type;
     if (operator == TokenType.BANG) {
-      _recordStaticType(node, _typeProvider.boolType);
+      _recordStaticType(node, _nonNullable(_typeProvider.boolType));
     } else {
       // The other cases are equivalent to invoking a method.
       ExecutableElement staticMethodElement = node.staticElement;
@@ -838,7 +849,7 @@
         Expression operand = node.operand;
         var operandReadType = _getStaticType(operand, read: true);
         if (operandReadType.isDartCoreInt) {
-          staticType = _typeProvider.intType;
+          staticType = _nonNullable(_typeProvider.intType);
         } else {
           _checkForInvalidAssignmentIncDec(node, operand, staticType);
         }
@@ -935,14 +946,18 @@
         (node as SetOrMapLiteralImpl).becomeSet();
         var elementType = _getType(typeArguments[0]) ?? _dynamicType;
         _recordStaticType(
-            node, _typeProvider.setType.instantiate(<DartType>[elementType]));
+            node,
+            _nonNullable(
+                _typeProvider.setType.instantiate(<DartType>[elementType])));
         return;
       } else if (typeArguments.length == 2) {
         (node as SetOrMapLiteralImpl).becomeMap();
         var keyType = _getType(typeArguments[0]) ?? _dynamicType;
         var valueType = _getType(typeArguments[1]) ?? _dynamicType;
-        _recordStaticType(node,
-            _typeProvider.mapType.instantiate(<DartType>[keyType, valueType]));
+        _recordStaticType(
+            node,
+            _nonNullable(_typeProvider.mapType
+                .instantiate(<DartType>[keyType, valueType])));
         return;
       }
       // If we get here, then a nonsense number of type arguments were provided,
@@ -958,6 +973,9 @@
       assert(literalType.element == _typeProvider.setType.element);
       (node as SetOrMapLiteralImpl).becomeSet();
     }
+    // TODO(brianwilkerson) Decide whether the literalType needs to be made
+    //  non-nullable here or whether that will have happened in
+    //  _inferSetOrMapLiteralType.
     _resolver.inferenceContext.recordInference(node, literalType);
     _recordStaticType(node, literalType);
   }
@@ -1008,13 +1026,13 @@
       if (_isNotTypeLiteral(node)) {
         staticType = element.type;
       } else {
-        staticType = _typeProvider.typeType;
+        staticType = _nonNullable(_typeProvider.typeType);
       }
     } else if (element is FunctionTypeAliasElement) {
       if (_isNotTypeLiteral(node)) {
         staticType = element.type;
       } else {
-        staticType = _typeProvider.typeType;
+        staticType = _nonNullable(_typeProvider.typeType);
       }
     } else if (element is MethodElement) {
       staticType = element.type;
@@ -1023,7 +1041,7 @@
     } else if (element is ExecutableElement) {
       staticType = element.type;
     } else if (element is TypeParameterElement) {
-      staticType = _typeProvider.typeType;
+      staticType = _nonNullable(_typeProvider.typeType);
     } else if (element is VariableElement) {
       VariableElement variable = element;
       staticType = _promoteManager.getStaticType(variable);
@@ -1035,7 +1053,7 @@
       }
       staticType = _typeProvider.dynamicType;
     } else if (element is DynamicElementImpl) {
-      staticType = _typeProvider.typeType;
+      staticType = _nonNullable(_typeProvider.typeType);
     } else {
       staticType = _dynamicType;
     }
@@ -1049,7 +1067,7 @@
    */
   @override
   void visitSimpleStringLiteral(SimpleStringLiteral node) {
-    _recordStaticType(node, _typeProvider.stringType);
+    _recordStaticType(node, _nonNullable(_typeProvider.stringType));
   }
 
   /**
@@ -1058,7 +1076,7 @@
    */
   @override
   void visitStringInterpolation(StringInterpolation node) {
-    _recordStaticType(node, _typeProvider.stringType);
+    _recordStaticType(node, _nonNullable(_typeProvider.stringType));
   }
 
   @override
@@ -1074,7 +1092,7 @@
 
   @override
   void visitSymbolLiteral(SymbolLiteral node) {
-    _recordStaticType(node, _typeProvider.symbolType);
+    _recordStaticType(node, _nonNullable(_typeProvider.symbolType));
   }
 
   /**
@@ -1244,13 +1262,14 @@
       InterfaceType genericType = body.isAsynchronous
           ? _typeProvider.streamType
           : _typeProvider.iterableType;
-      return genericType.instantiate(<DartType>[type]);
+      return _nonNullable(genericType.instantiate(<DartType>[type]));
     } else if (body.isAsynchronous) {
       if (type.isDartAsyncFutureOr) {
         type = (type as InterfaceType).typeArguments[0];
       }
-      return _typeProvider.futureType
+      DartType futureType = _typeProvider.futureType
           .instantiate(<DartType>[_typeSystem.flatten(type)]);
+      return _nonNullable(futureType);
     } else {
       return type;
     }
@@ -1944,6 +1963,17 @@
   }
 
   /**
+   * Return the non-nullable variant of the [type] if NNBD is enabled, otherwise
+   * return the type itself.
+   */
+  DartType _nonNullable(DartType type) {
+    if (_nonNullableEnabled) {
+      return _typeSystem.promoteToNonNull(type);
+    }
+    return type;
+  }
+
+  /**
    * Record that the static type of the given node is the given type.
    *
    * @param expression the node whose type is to be recorded
diff --git a/pkg/analyzer/lib/src/generated/testing/element_factory.dart b/pkg/analyzer/lib/src/generated/testing/element_factory.dart
index 8dfa63d..e54a06c 100644
--- a/pkg/analyzer/lib/src/generated/testing/element_factory.dart
+++ b/pkg/analyzer/lib/src/generated/testing/element_factory.dart
@@ -412,12 +412,12 @@
     return spec;
   }
 
-  static LibraryElementImpl library(
-      AnalysisContext context, String libraryName) {
+  static LibraryElementImpl library(AnalysisContext context, String libraryName,
+      {bool isNonNullableByDefault: true}) {
     String fileName = "/$libraryName.dart";
     CompilationUnitElementImpl unit = compilationUnit(fileName);
-    LibraryElementImpl library = new LibraryElementImpl(
-        context, null, libraryName, 0, libraryName.length);
+    LibraryElementImpl library = new LibraryElementImpl(context, null,
+        libraryName, 0, libraryName.length, isNonNullableByDefault);
     library.definingCompilationUnit = unit;
     return library;
   }
diff --git a/pkg/analyzer/lib/src/generated/testing/test_type_provider.dart b/pkg/analyzer/lib/src/generated/testing/test_type_provider.dart
index da58fd1..82a7821 100644
--- a/pkg/analyzer/lib/src/generated/testing/test_type_provider.dart
+++ b/pkg/analyzer/lib/src/generated/testing/test_type_provider.dart
@@ -23,6 +23,8 @@
  * for the core library.
  */
 class TestTypeProvider extends TypeProviderBase {
+  final bool _isNonNullableByDefault;
+
   /**
    * The type representing the built-in type 'bool'.
    */
@@ -190,7 +192,9 @@
    */
   AnalysisDriver _driver;
 
-  TestTypeProvider([this._context, this._driver]);
+  /// TODO(paulberry): rework API and make _isNonNullableByDefault required.
+  TestTypeProvider(
+      [this._context, this._driver, this._isNonNullableByDefault = false]);
 
   @override
   InterfaceType get boolType {
@@ -471,7 +475,10 @@
       // Create a library element for "dart:core"
       // This enables the "isDartCoreNull" getter.
       var library = new LibraryElementImpl.forNode(
-          _context, null, AstTestFactory.libraryIdentifier2(["dart.core"]));
+          _context,
+          null,
+          AstTestFactory.libraryIdentifier2(["dart.core"]),
+          _isNonNullableByDefault);
       var unit = new CompilationUnitElementImpl();
       library.definingCompilationUnit = unit;
       unit.librarySource = unit.source = new StringSource('', null);
@@ -619,7 +626,10 @@
     }
     CompilationUnitElementImpl asyncUnit = new CompilationUnitElementImpl();
     LibraryElementImpl asyncLibrary = new LibraryElementImpl.forNode(
-        _context, null, AstTestFactory.libraryIdentifier2(["dart.async"]));
+        _context,
+        null,
+        AstTestFactory.libraryIdentifier2(["dart.async"]),
+        _isNonNullableByDefault);
     asyncLibrary.definingCompilationUnit = asyncUnit;
     asyncUnit.librarySource = asyncUnit.source = asyncSource;
 
diff --git a/pkg/analyzer/lib/src/generated/type_system.dart b/pkg/analyzer/lib/src/generated/type_system.dart
index a774f85..4ef1a61 100644
--- a/pkg/analyzer/lib/src/generated/type_system.dart
+++ b/pkg/analyzer/lib/src/generated/type_system.dart
@@ -5,6 +5,7 @@
 import 'dart:collection';
 import 'dart:math' as math;
 
+import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/ast/ast.dart' show AstNode;
 import 'package:analyzer/dart/ast/token.dart' show Keyword, TokenType;
 import 'package:analyzer/dart/element/element.dart';
@@ -648,7 +649,7 @@
 
   @override
   DartType refineBinaryExpressionType(DartType leftType, TokenType operator,
-      DartType rightType, DartType currentType) {
+      DartType rightType, DartType currentType, FeatureSet featureSet) {
     if (leftType is TypeParameterType &&
         leftType.element.bound == typeProvider.numType) {
       if (rightType == leftType || rightType == typeProvider.intType) {
@@ -658,6 +659,9 @@
             operator == TokenType.PLUS_EQ ||
             operator == TokenType.MINUS_EQ ||
             operator == TokenType.STAR_EQ) {
+          if (featureSet.isEnabled(Feature.non_nullable)) {
+            return promoteToNonNull(leftType as TypeImpl);
+          }
           return leftType;
         }
       }
@@ -666,13 +670,16 @@
             operator == TokenType.MINUS ||
             operator == TokenType.STAR ||
             operator == TokenType.SLASH) {
+          if (featureSet.isEnabled(Feature.non_nullable)) {
+            return promoteToNonNull(typeProvider.doubleType as TypeImpl);
+          }
           return typeProvider.doubleType;
         }
       }
       return currentType;
     }
-    return super
-        .refineBinaryExpressionType(leftType, operator, rightType, currentType);
+    return super.refineBinaryExpressionType(
+        leftType, operator, rightType, currentType, featureSet);
   }
 
   @override
@@ -2088,16 +2095,22 @@
   }
 
   /**
-   * Attempts to make a better guess for the type of a binary with the given
-   * [operator], given that resolution has so far produced the [currentType].
+   * Determine the type of a binary expression with the given [operator] whose
+   * left operand has the type [leftType] and whose right operand has the type
+   * [rightType], given that resolution has so far produced the [currentType].
+   * The [featureSet] is used to determine whether any features that effect the
+   * computation have been enabled.
    */
   DartType refineBinaryExpressionType(DartType leftType, TokenType operator,
-      DartType rightType, DartType currentType) {
+      DartType rightType, DartType currentType, FeatureSet featureSet) {
     // bool
     if (operator == TokenType.AMPERSAND_AMPERSAND ||
         operator == TokenType.BAR_BAR ||
         operator == TokenType.EQ_EQ ||
         operator == TokenType.BANG_EQ) {
+      if (featureSet.isEnabled(Feature.non_nullable)) {
+        return promoteToNonNull(typeProvider.boolType as TypeImpl);
+      }
       return typeProvider.boolType;
     }
     DartType intType = typeProvider.intType;
@@ -2113,6 +2126,9 @@
           operator == TokenType.STAR_EQ) {
         DartType doubleType = typeProvider.doubleType;
         if (rightType == doubleType) {
+          if (featureSet.isEnabled(Feature.non_nullable)) {
+            return promoteToNonNull(doubleType as TypeImpl);
+          }
           return doubleType;
         }
       }
@@ -2128,6 +2144,9 @@
           operator == TokenType.STAR_EQ ||
           operator == TokenType.TILDE_SLASH_EQ) {
         if (rightType == intType) {
+          if (featureSet.isEnabled(Feature.non_nullable)) {
+            return promoteToNonNull(intType as TypeImpl);
+          }
           return intType;
         }
       }
diff --git a/pkg/analyzer/lib/src/hint/sdk_constraint_verifier.dart b/pkg/analyzer/lib/src/hint/sdk_constraint_verifier.dart
index 1087abd..938d454 100644
--- a/pkg/analyzer/lib/src/hint/sdk_constraint_verifier.dart
+++ b/pkg/analyzer/lib/src/hint/sdk_constraint_verifier.dart
@@ -81,6 +81,12 @@
   bool get checkFutureAndStream => _checkFutureAndStream ??=
       !before_2_1_0.intersect(_versionConstraint).isEmpty;
 
+  /// Return `true` if references to the non-nullable features need to be
+  /// checked.
+  // TODO(brianwilkerson) Implement this as a version check when a version has
+  //  been selected.
+  bool get checkNnbd => true;
+
   /// Return `true` if references to set literals need to be checked.
   bool get checkSetLiterals =>
       _checkSetLiterals ??= !before_2_2_0.intersect(_versionConstraint).isEmpty;
@@ -214,6 +220,8 @@
       }
       _errorReporter.reportErrorForNode(
           HintCode.SDK_VERSION_ASYNC_EXPORTED_FROM_CORE, node, [element.name]);
+    } else if (checkNnbd && element == _typeProvider.neverType.element) {
+      _errorReporter.reportErrorForNode(HintCode.SDK_VERSION_NEVER, node);
     }
   }
 
diff --git a/pkg/analyzer/lib/src/lint/linter.dart b/pkg/analyzer/lib/src/lint/linter.dart
index 331d7a6..51a2b46 100644
--- a/pkg/analyzer/lib/src/lint/linter.dart
+++ b/pkg/analyzer/lib/src/lint/linter.dart
@@ -423,7 +423,7 @@
       ErrorCode errorCode,
       bool ignoreSyntheticNodes: true}) {
     if (node != null && (!node.isSynthetic || !ignoreSyntheticNodes)) {
-      reporter.reportErrorForNode(lintCode, node, arguments);
+      reporter.reportErrorForNode(errorCode ?? lintCode, node, arguments);
     }
   }
 
@@ -432,7 +432,7 @@
       ErrorCode errorCode,
       bool ignoreSyntheticTokens: true}) {
     if (token != null && (!token.isSynthetic || !ignoreSyntheticTokens)) {
-      reporter.reportErrorForToken(lintCode, token, arguments);
+      reporter.reportErrorForToken(errorCode ?? lintCode, token, arguments);
     }
   }
 
diff --git a/pkg/analyzer/lib/src/summary/format.dart b/pkg/analyzer/lib/src/summary/format.dart
index d655c4c..bcfbc8c 100644
--- a/pkg/analyzer/lib/src/summary/format.dart
+++ b/pkg/analyzer/lib/src/summary/format.dart
@@ -4726,14 +4726,12 @@
   LinkedNodeBuilder _variantField_11;
   List<LinkedNodeBuilder> _variantField_4;
   LinkedNodeBuilder _variantField_6;
-  int _variantField_15;
   LinkedNodeBuilder _variantField_7;
   int _variantField_17;
   LinkedNodeTypeBuilder _variantField_23;
   LinkedNodeBuilder _variantField_8;
-  int _variantField_16;
-  int _variantField_18;
-  int _variantField_19;
+  int _variantField_15;
+  idl.UnlinkedTokenType _variantField_28;
   bool _variantField_27;
   LinkedNodeBuilder _variantField_9;
   LinkedNodeBuilder _variantField_12;
@@ -4741,22 +4739,26 @@
   LinkedNodeBuilder _variantField_13;
   int _variantField_34;
   int _variantField_33;
-  List<int> _variantField_28;
+  List<String> _variantField_36;
   idl.LinkedNodeCommentType _variantField_29;
   List<LinkedNodeBuilder> _variantField_3;
   LinkedNodeBuilder _variantField_10;
   idl.LinkedNodeFormalParameterKind _variantField_26;
   double _variantField_21;
   LinkedNodeTypeBuilder _variantField_25;
+  int _flags;
+  String _variantField_1;
+  int _variantField_16;
   String _variantField_30;
   LinkedNodeBuilder _variantField_14;
-  bool _isSynthetic;
   idl.LinkedNodeKind _kind;
-  List<String> _variantField_36;
+  String _name;
   String _variantField_20;
   bool _variantField_31;
+  idl.UnlinkedTokenType _variantField_38;
   TopLevelInferenceErrorBuilder _variantField_35;
   String _variantField_22;
+  int _variantField_19;
   LinkedNodeVariablesDeclarationBuilder _variantField_32;
 
   @override
@@ -4881,14 +4883,14 @@
   }
 
   @override
-  List<LinkedNodeBuilder> get hideCombinator_hiddenNames {
-    assert(kind == idl.LinkedNodeKind.hideCombinator);
+  List<LinkedNodeBuilder> get implementsClause_interfaces {
+    assert(kind == idl.LinkedNodeKind.implementsClause);
     return _variantField_2 ??= <LinkedNodeBuilder>[];
   }
 
   @override
-  List<LinkedNodeBuilder> get implementsClause_interfaces {
-    assert(kind == idl.LinkedNodeKind.implementsClause);
+  List<LinkedNodeBuilder> get instanceCreationExpression_arguments {
+    assert(kind == idl.LinkedNodeKind.instanceCreationExpression);
     return _variantField_2 ??= <LinkedNodeBuilder>[];
   }
 
@@ -4905,12 +4907,6 @@
   }
 
   @override
-  List<LinkedNodeBuilder> get listLiteral_elements {
-    assert(kind == idl.LinkedNodeKind.listLiteral);
-    return _variantField_2 ??= <LinkedNodeBuilder>[];
-  }
-
-  @override
   List<LinkedNodeBuilder> get namespaceDirective_combinators {
     assert(kind == idl.LinkedNodeKind.exportDirective ||
         kind == idl.LinkedNodeKind.importDirective);
@@ -4924,18 +4920,6 @@
   }
 
   @override
-  List<LinkedNodeBuilder> get setOrMapLiteral_elements {
-    assert(kind == idl.LinkedNodeKind.setOrMapLiteral);
-    return _variantField_2 ??= <LinkedNodeBuilder>[];
-  }
-
-  @override
-  List<LinkedNodeBuilder> get showCombinator_shownNames {
-    assert(kind == idl.LinkedNodeKind.showCombinator);
-    return _variantField_2 ??= <LinkedNodeBuilder>[];
-  }
-
-  @override
   List<LinkedNodeBuilder> get stringInterpolation_elements {
     assert(kind == idl.LinkedNodeKind.stringInterpolation);
     return _variantField_2 ??= <LinkedNodeBuilder>[];
@@ -4960,6 +4944,19 @@
   }
 
   @override
+  List<LinkedNodeBuilder> get typedLiteral_typeArguments {
+    assert(kind == idl.LinkedNodeKind.listLiteral ||
+        kind == idl.LinkedNodeKind.setOrMapLiteral);
+    return _variantField_2 ??= <LinkedNodeBuilder>[];
+  }
+
+  @override
+  List<LinkedNodeBuilder> get typeName_typeArguments {
+    assert(kind == idl.LinkedNodeKind.typeName);
+    return _variantField_2 ??= <LinkedNodeBuilder>[];
+  }
+
+  @override
   List<LinkedNodeBuilder> get typeParameterList_typeParameters {
     assert(kind == idl.LinkedNodeKind.typeParameterList);
     return _variantField_2 ??= <LinkedNodeBuilder>[];
@@ -5027,13 +5024,13 @@
     _variantField_2 = value;
   }
 
-  set hideCombinator_hiddenNames(List<LinkedNodeBuilder> value) {
-    assert(kind == idl.LinkedNodeKind.hideCombinator);
+  set implementsClause_interfaces(List<LinkedNodeBuilder> value) {
+    assert(kind == idl.LinkedNodeKind.implementsClause);
     _variantField_2 = value;
   }
 
-  set implementsClause_interfaces(List<LinkedNodeBuilder> value) {
-    assert(kind == idl.LinkedNodeKind.implementsClause);
+  set instanceCreationExpression_arguments(List<LinkedNodeBuilder> value) {
+    assert(kind == idl.LinkedNodeKind.instanceCreationExpression);
     _variantField_2 = value;
   }
 
@@ -5047,11 +5044,6 @@
     _variantField_2 = value;
   }
 
-  set listLiteral_elements(List<LinkedNodeBuilder> value) {
-    assert(kind == idl.LinkedNodeKind.listLiteral);
-    _variantField_2 = value;
-  }
-
   set namespaceDirective_combinators(List<LinkedNodeBuilder> value) {
     assert(kind == idl.LinkedNodeKind.exportDirective ||
         kind == idl.LinkedNodeKind.importDirective);
@@ -5063,16 +5055,6 @@
     _variantField_2 = value;
   }
 
-  set setOrMapLiteral_elements(List<LinkedNodeBuilder> value) {
-    assert(kind == idl.LinkedNodeKind.setOrMapLiteral);
-    _variantField_2 = value;
-  }
-
-  set showCombinator_shownNames(List<LinkedNodeBuilder> value) {
-    assert(kind == idl.LinkedNodeKind.showCombinator);
-    _variantField_2 = value;
-  }
-
   set stringInterpolation_elements(List<LinkedNodeBuilder> value) {
     assert(kind == idl.LinkedNodeKind.stringInterpolation);
     _variantField_2 = value;
@@ -5093,6 +5075,17 @@
     _variantField_2 = value;
   }
 
+  set typedLiteral_typeArguments(List<LinkedNodeBuilder> value) {
+    assert(kind == idl.LinkedNodeKind.listLiteral ||
+        kind == idl.LinkedNodeKind.setOrMapLiteral);
+    _variantField_2 = value;
+  }
+
+  set typeName_typeArguments(List<LinkedNodeBuilder> value) {
+    assert(kind == idl.LinkedNodeKind.typeName);
+    _variantField_2 = value;
+  }
+
   set typeParameterList_typeParameters(List<LinkedNodeBuilder> value) {
     assert(kind == idl.LinkedNodeKind.typeParameterList);
     _variantField_2 = value;
@@ -5383,12 +5376,6 @@
   }
 
   @override
-  LinkedNodeBuilder get enumConstantDeclaration_name {
-    assert(kind == idl.LinkedNodeKind.enumConstantDeclaration);
-    return _variantField_6;
-  }
-
-  @override
   LinkedNodeBuilder get expressionFunctionBody_expression {
     assert(kind == idl.LinkedNodeKind.expressionFunctionBody);
     return _variantField_6;
@@ -5495,24 +5482,12 @@
   }
 
   @override
-  LinkedNodeBuilder get importDirective_prefix {
-    assert(kind == idl.LinkedNodeKind.importDirective);
-    return _variantField_6;
-  }
-
-  @override
   LinkedNodeBuilder get indexExpression_index {
     assert(kind == idl.LinkedNodeKind.indexExpression);
     return _variantField_6;
   }
 
   @override
-  LinkedNodeBuilder get instanceCreationExpression_arguments {
-    assert(kind == idl.LinkedNodeKind.instanceCreationExpression);
-    return _variantField_6;
-  }
-
-  @override
   LinkedNodeBuilder get interpolationExpression_expression {
     assert(kind == idl.LinkedNodeKind.interpolationExpression);
     return _variantField_6;
@@ -5836,11 +5811,6 @@
     _variantField_6 = value;
   }
 
-  set enumConstantDeclaration_name(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.enumConstantDeclaration);
-    _variantField_6 = value;
-  }
-
   set expressionFunctionBody_expression(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.expressionFunctionBody);
     _variantField_6 = value;
@@ -5931,21 +5901,11 @@
     _variantField_6 = value;
   }
 
-  set importDirective_prefix(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.importDirective);
-    _variantField_6 = value;
-  }
-
   set indexExpression_index(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.indexExpression);
     _variantField_6 = value;
   }
 
-  set instanceCreationExpression_arguments(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.instanceCreationExpression);
-    _variantField_6 = value;
-  }
-
   set interpolationExpression_expression(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.interpolationExpression);
     _variantField_6 = value;
@@ -6117,1132 +6077,6 @@
   }
 
   @override
-  int get annotation_atSign {
-    assert(kind == idl.LinkedNodeKind.annotation);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get argumentList_leftParenthesis {
-    assert(kind == idl.LinkedNodeKind.argumentList);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get asExpression_asOperator {
-    assert(kind == idl.LinkedNodeKind.asExpression);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get assertInitializer_assertKeyword {
-    assert(kind == idl.LinkedNodeKind.assertInitializer);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get assertStatement_assertKeyword {
-    assert(kind == idl.LinkedNodeKind.assertStatement);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get assignmentExpression_element {
-    assert(kind == idl.LinkedNodeKind.assignmentExpression);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get awaitExpression_awaitKeyword {
-    assert(kind == idl.LinkedNodeKind.awaitExpression);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get binaryExpression_element {
-    assert(kind == idl.LinkedNodeKind.binaryExpression);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get block_leftBracket {
-    assert(kind == idl.LinkedNodeKind.block);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get blockFunctionBody_keyword {
-    assert(kind == idl.LinkedNodeKind.blockFunctionBody);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get booleanLiteral_literal {
-    assert(kind == idl.LinkedNodeKind.booleanLiteral);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get breakStatement_breakKeyword {
-    assert(kind == idl.LinkedNodeKind.breakStatement);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get catchClause_catchKeyword {
-    assert(kind == idl.LinkedNodeKind.catchClause);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get classDeclaration_abstractKeyword {
-    assert(kind == idl.LinkedNodeKind.classDeclaration);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get classTypeAlias_abstractKeyword {
-    assert(kind == idl.LinkedNodeKind.classTypeAlias);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get commentReference_newKeyword {
-    assert(kind == idl.LinkedNodeKind.commentReference);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get compilationUnit_beginToken {
-    assert(kind == idl.LinkedNodeKind.compilationUnit);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get conditionalExpression_colon {
-    assert(kind == idl.LinkedNodeKind.conditionalExpression);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get configuration_ifKeyword {
-    assert(kind == idl.LinkedNodeKind.configuration);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get constructorDeclaration_constKeyword {
-    assert(kind == idl.LinkedNodeKind.constructorDeclaration);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get constructorFieldInitializer_equals {
-    assert(kind == idl.LinkedNodeKind.constructorFieldInitializer);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get constructorName_element {
-    assert(kind == idl.LinkedNodeKind.constructorName);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get continueStatement_continueKeyword {
-    assert(kind == idl.LinkedNodeKind.continueStatement);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get declaredIdentifier_keyword {
-    assert(kind == idl.LinkedNodeKind.declaredIdentifier);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get defaultFormalParameter_separator {
-    assert(kind == idl.LinkedNodeKind.defaultFormalParameter);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get doStatement_leftParenthesis {
-    assert(kind == idl.LinkedNodeKind.doStatement);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get doubleLiteral_literal {
-    assert(kind == idl.LinkedNodeKind.doubleLiteral);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get emptyFunctionBody_semicolon {
-    assert(kind == idl.LinkedNodeKind.emptyFunctionBody);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get emptyStatement_semicolon {
-    assert(kind == idl.LinkedNodeKind.emptyStatement);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get enumDeclaration_enumKeyword {
-    assert(kind == idl.LinkedNodeKind.enumDeclaration);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get expressionFunctionBody_arrow {
-    assert(kind == idl.LinkedNodeKind.expressionFunctionBody);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get expressionStatement_semicolon {
-    assert(kind == idl.LinkedNodeKind.expressionStatement);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get extendsClause_extendsKeyword {
-    assert(kind == idl.LinkedNodeKind.extendsClause);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get fieldDeclaration_covariantKeyword {
-    assert(kind == idl.LinkedNodeKind.fieldDeclaration);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get fieldFormalParameter_keyword {
-    assert(kind == idl.LinkedNodeKind.fieldFormalParameter);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get forEachParts_inKeyword {
-    assert(kind == idl.LinkedNodeKind.forEachPartsWithDeclaration ||
-        kind == idl.LinkedNodeKind.forEachPartsWithIdentifier);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get formalParameterList_leftDelimiter {
-    assert(kind == idl.LinkedNodeKind.formalParameterList);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get forMixin_awaitKeyword {
-    assert(kind == idl.LinkedNodeKind.forElement ||
-        kind == idl.LinkedNodeKind.forStatement);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get forParts_leftSeparator {
-    assert(kind == idl.LinkedNodeKind.forPartsWithDeclarations ||
-        kind == idl.LinkedNodeKind.forPartsWithExpression);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get functionDeclaration_externalKeyword {
-    assert(kind == idl.LinkedNodeKind.functionDeclaration);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get genericFunctionType_functionKeyword {
-    assert(kind == idl.LinkedNodeKind.genericFunctionType);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get ifMixin_elseKeyword {
-    assert(kind == idl.LinkedNodeKind.ifElement ||
-        kind == idl.LinkedNodeKind.ifStatement);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get implementsClause_implementsKeyword {
-    assert(kind == idl.LinkedNodeKind.implementsClause);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get importDirective_asKeyword {
-    assert(kind == idl.LinkedNodeKind.importDirective);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get indexExpression_element {
-    assert(kind == idl.LinkedNodeKind.indexExpression);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get instanceCreationExpression_keyword {
-    assert(kind == idl.LinkedNodeKind.instanceCreationExpression);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get integerLiteral_literal {
-    assert(kind == idl.LinkedNodeKind.integerLiteral);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get interpolationExpression_leftBracket {
-    assert(kind == idl.LinkedNodeKind.interpolationExpression);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get interpolationString_token {
-    assert(kind == idl.LinkedNodeKind.interpolationString);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get isExpression_isOperator {
-    assert(kind == idl.LinkedNodeKind.isExpression);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get label_colon {
-    assert(kind == idl.LinkedNodeKind.label);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get listLiteral_leftBracket {
-    assert(kind == idl.LinkedNodeKind.listLiteral);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get mapLiteralEntry_separator {
-    assert(kind == idl.LinkedNodeKind.mapLiteralEntry);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get methodDeclaration_externalKeyword {
-    assert(kind == idl.LinkedNodeKind.methodDeclaration);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get methodInvocation_operator {
-    assert(kind == idl.LinkedNodeKind.methodInvocation);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get mixinDeclaration_mixinKeyword {
-    assert(kind == idl.LinkedNodeKind.mixinDeclaration);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get nativeClause_nativeKeyword {
-    assert(kind == idl.LinkedNodeKind.nativeClause);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get nativeFunctionBody_nativeKeyword {
-    assert(kind == idl.LinkedNodeKind.nativeFunctionBody);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get nullLiteral_literal {
-    assert(kind == idl.LinkedNodeKind.nullLiteral);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get onClause_onKeyword {
-    assert(kind == idl.LinkedNodeKind.onClause);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get parenthesizedExpression_leftParenthesis {
-    assert(kind == idl.LinkedNodeKind.parenthesizedExpression);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get postfixExpression_element {
-    assert(kind == idl.LinkedNodeKind.postfixExpression);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get prefixedIdentifier_period {
-    assert(kind == idl.LinkedNodeKind.prefixedIdentifier);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get prefixExpression_element {
-    assert(kind == idl.LinkedNodeKind.prefixExpression);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get propertyAccess_operator {
-    assert(kind == idl.LinkedNodeKind.propertyAccess);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get redirectingConstructorInvocation_element {
-    assert(kind == idl.LinkedNodeKind.redirectingConstructorInvocation);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get rethrowExpression_rethrowKeyword {
-    assert(kind == idl.LinkedNodeKind.rethrowExpression);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get returnStatement_returnKeyword {
-    assert(kind == idl.LinkedNodeKind.returnStatement);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get scriptTag_scriptTag {
-    assert(kind == idl.LinkedNodeKind.scriptTag);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get setOrMapLiteral_leftBracket {
-    assert(kind == idl.LinkedNodeKind.setOrMapLiteral);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get simpleFormalParameter_keyword {
-    assert(kind == idl.LinkedNodeKind.simpleFormalParameter);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get simpleIdentifier_element {
-    assert(kind == idl.LinkedNodeKind.simpleIdentifier);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get simpleStringLiteral_token {
-    assert(kind == idl.LinkedNodeKind.simpleStringLiteral);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get spreadElement_spreadOperator {
-    assert(kind == idl.LinkedNodeKind.spreadElement);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get superConstructorInvocation_element {
-    assert(kind == idl.LinkedNodeKind.superConstructorInvocation);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get superExpression_superKeyword {
-    assert(kind == idl.LinkedNodeKind.superExpression);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get switchMember_keyword {
-    assert(kind == idl.LinkedNodeKind.switchCase ||
-        kind == idl.LinkedNodeKind.switchDefault);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get switchStatement_leftParenthesis {
-    assert(kind == idl.LinkedNodeKind.switchStatement);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get symbolLiteral_poundSign {
-    assert(kind == idl.LinkedNodeKind.symbolLiteral);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get thisExpression_thisKeyword {
-    assert(kind == idl.LinkedNodeKind.thisExpression);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get throwExpression_throwKeyword {
-    assert(kind == idl.LinkedNodeKind.throwExpression);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get topLevelVariableDeclaration_semicolon {
-    assert(kind == idl.LinkedNodeKind.topLevelVariableDeclaration);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get tryStatement_finallyKeyword {
-    assert(kind == idl.LinkedNodeKind.tryStatement);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get typeArgumentList_leftBracket {
-    assert(kind == idl.LinkedNodeKind.typeArgumentList);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get typeName_question {
-    assert(kind == idl.LinkedNodeKind.typeName);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get typeParameter_extendsKeyword {
-    assert(kind == idl.LinkedNodeKind.typeParameter);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get typeParameterList_leftBracket {
-    assert(kind == idl.LinkedNodeKind.typeParameterList);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get variableDeclaration_equals {
-    assert(kind == idl.LinkedNodeKind.variableDeclaration);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get variableDeclarationList_keyword {
-    assert(kind == idl.LinkedNodeKind.variableDeclarationList);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get variableDeclarationStatement_semicolon {
-    assert(kind == idl.LinkedNodeKind.variableDeclarationStatement);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get whileStatement_leftParenthesis {
-    assert(kind == idl.LinkedNodeKind.whileStatement);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get withClause_withKeyword {
-    assert(kind == idl.LinkedNodeKind.withClause);
-    return _variantField_15 ??= 0;
-  }
-
-  @override
-  int get yieldStatement_yieldKeyword {
-    assert(kind == idl.LinkedNodeKind.yieldStatement);
-    return _variantField_15 ??= 0;
-  }
-
-  set annotation_atSign(int value) {
-    assert(kind == idl.LinkedNodeKind.annotation);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set argumentList_leftParenthesis(int value) {
-    assert(kind == idl.LinkedNodeKind.argumentList);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set asExpression_asOperator(int value) {
-    assert(kind == idl.LinkedNodeKind.asExpression);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set assertInitializer_assertKeyword(int value) {
-    assert(kind == idl.LinkedNodeKind.assertInitializer);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set assertStatement_assertKeyword(int value) {
-    assert(kind == idl.LinkedNodeKind.assertStatement);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set assignmentExpression_element(int value) {
-    assert(kind == idl.LinkedNodeKind.assignmentExpression);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set awaitExpression_awaitKeyword(int value) {
-    assert(kind == idl.LinkedNodeKind.awaitExpression);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set binaryExpression_element(int value) {
-    assert(kind == idl.LinkedNodeKind.binaryExpression);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set block_leftBracket(int value) {
-    assert(kind == idl.LinkedNodeKind.block);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set blockFunctionBody_keyword(int value) {
-    assert(kind == idl.LinkedNodeKind.blockFunctionBody);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set booleanLiteral_literal(int value) {
-    assert(kind == idl.LinkedNodeKind.booleanLiteral);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set breakStatement_breakKeyword(int value) {
-    assert(kind == idl.LinkedNodeKind.breakStatement);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set catchClause_catchKeyword(int value) {
-    assert(kind == idl.LinkedNodeKind.catchClause);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set classDeclaration_abstractKeyword(int value) {
-    assert(kind == idl.LinkedNodeKind.classDeclaration);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set classTypeAlias_abstractKeyword(int value) {
-    assert(kind == idl.LinkedNodeKind.classTypeAlias);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set commentReference_newKeyword(int value) {
-    assert(kind == idl.LinkedNodeKind.commentReference);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set compilationUnit_beginToken(int value) {
-    assert(kind == idl.LinkedNodeKind.compilationUnit);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set conditionalExpression_colon(int value) {
-    assert(kind == idl.LinkedNodeKind.conditionalExpression);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set configuration_ifKeyword(int value) {
-    assert(kind == idl.LinkedNodeKind.configuration);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set constructorDeclaration_constKeyword(int value) {
-    assert(kind == idl.LinkedNodeKind.constructorDeclaration);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set constructorFieldInitializer_equals(int value) {
-    assert(kind == idl.LinkedNodeKind.constructorFieldInitializer);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set constructorName_element(int value) {
-    assert(kind == idl.LinkedNodeKind.constructorName);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set continueStatement_continueKeyword(int value) {
-    assert(kind == idl.LinkedNodeKind.continueStatement);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set declaredIdentifier_keyword(int value) {
-    assert(kind == idl.LinkedNodeKind.declaredIdentifier);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set defaultFormalParameter_separator(int value) {
-    assert(kind == idl.LinkedNodeKind.defaultFormalParameter);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set doStatement_leftParenthesis(int value) {
-    assert(kind == idl.LinkedNodeKind.doStatement);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set doubleLiteral_literal(int value) {
-    assert(kind == idl.LinkedNodeKind.doubleLiteral);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set emptyFunctionBody_semicolon(int value) {
-    assert(kind == idl.LinkedNodeKind.emptyFunctionBody);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set emptyStatement_semicolon(int value) {
-    assert(kind == idl.LinkedNodeKind.emptyStatement);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set enumDeclaration_enumKeyword(int value) {
-    assert(kind == idl.LinkedNodeKind.enumDeclaration);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set expressionFunctionBody_arrow(int value) {
-    assert(kind == idl.LinkedNodeKind.expressionFunctionBody);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set expressionStatement_semicolon(int value) {
-    assert(kind == idl.LinkedNodeKind.expressionStatement);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set extendsClause_extendsKeyword(int value) {
-    assert(kind == idl.LinkedNodeKind.extendsClause);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set fieldDeclaration_covariantKeyword(int value) {
-    assert(kind == idl.LinkedNodeKind.fieldDeclaration);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set fieldFormalParameter_keyword(int value) {
-    assert(kind == idl.LinkedNodeKind.fieldFormalParameter);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set forEachParts_inKeyword(int value) {
-    assert(kind == idl.LinkedNodeKind.forEachPartsWithDeclaration ||
-        kind == idl.LinkedNodeKind.forEachPartsWithIdentifier);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set formalParameterList_leftDelimiter(int value) {
-    assert(kind == idl.LinkedNodeKind.formalParameterList);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set forMixin_awaitKeyword(int value) {
-    assert(kind == idl.LinkedNodeKind.forElement ||
-        kind == idl.LinkedNodeKind.forStatement);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set forParts_leftSeparator(int value) {
-    assert(kind == idl.LinkedNodeKind.forPartsWithDeclarations ||
-        kind == idl.LinkedNodeKind.forPartsWithExpression);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set functionDeclaration_externalKeyword(int value) {
-    assert(kind == idl.LinkedNodeKind.functionDeclaration);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set genericFunctionType_functionKeyword(int value) {
-    assert(kind == idl.LinkedNodeKind.genericFunctionType);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set ifMixin_elseKeyword(int value) {
-    assert(kind == idl.LinkedNodeKind.ifElement ||
-        kind == idl.LinkedNodeKind.ifStatement);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set implementsClause_implementsKeyword(int value) {
-    assert(kind == idl.LinkedNodeKind.implementsClause);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set importDirective_asKeyword(int value) {
-    assert(kind == idl.LinkedNodeKind.importDirective);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set indexExpression_element(int value) {
-    assert(kind == idl.LinkedNodeKind.indexExpression);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set instanceCreationExpression_keyword(int value) {
-    assert(kind == idl.LinkedNodeKind.instanceCreationExpression);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set integerLiteral_literal(int value) {
-    assert(kind == idl.LinkedNodeKind.integerLiteral);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set interpolationExpression_leftBracket(int value) {
-    assert(kind == idl.LinkedNodeKind.interpolationExpression);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set interpolationString_token(int value) {
-    assert(kind == idl.LinkedNodeKind.interpolationString);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set isExpression_isOperator(int value) {
-    assert(kind == idl.LinkedNodeKind.isExpression);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set label_colon(int value) {
-    assert(kind == idl.LinkedNodeKind.label);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set listLiteral_leftBracket(int value) {
-    assert(kind == idl.LinkedNodeKind.listLiteral);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set mapLiteralEntry_separator(int value) {
-    assert(kind == idl.LinkedNodeKind.mapLiteralEntry);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set methodDeclaration_externalKeyword(int value) {
-    assert(kind == idl.LinkedNodeKind.methodDeclaration);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set methodInvocation_operator(int value) {
-    assert(kind == idl.LinkedNodeKind.methodInvocation);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set mixinDeclaration_mixinKeyword(int value) {
-    assert(kind == idl.LinkedNodeKind.mixinDeclaration);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set nativeClause_nativeKeyword(int value) {
-    assert(kind == idl.LinkedNodeKind.nativeClause);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set nativeFunctionBody_nativeKeyword(int value) {
-    assert(kind == idl.LinkedNodeKind.nativeFunctionBody);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set nullLiteral_literal(int value) {
-    assert(kind == idl.LinkedNodeKind.nullLiteral);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set onClause_onKeyword(int value) {
-    assert(kind == idl.LinkedNodeKind.onClause);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set parenthesizedExpression_leftParenthesis(int value) {
-    assert(kind == idl.LinkedNodeKind.parenthesizedExpression);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set postfixExpression_element(int value) {
-    assert(kind == idl.LinkedNodeKind.postfixExpression);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set prefixedIdentifier_period(int value) {
-    assert(kind == idl.LinkedNodeKind.prefixedIdentifier);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set prefixExpression_element(int value) {
-    assert(kind == idl.LinkedNodeKind.prefixExpression);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set propertyAccess_operator(int value) {
-    assert(kind == idl.LinkedNodeKind.propertyAccess);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set redirectingConstructorInvocation_element(int value) {
-    assert(kind == idl.LinkedNodeKind.redirectingConstructorInvocation);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set rethrowExpression_rethrowKeyword(int value) {
-    assert(kind == idl.LinkedNodeKind.rethrowExpression);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set returnStatement_returnKeyword(int value) {
-    assert(kind == idl.LinkedNodeKind.returnStatement);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set scriptTag_scriptTag(int value) {
-    assert(kind == idl.LinkedNodeKind.scriptTag);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set setOrMapLiteral_leftBracket(int value) {
-    assert(kind == idl.LinkedNodeKind.setOrMapLiteral);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set simpleFormalParameter_keyword(int value) {
-    assert(kind == idl.LinkedNodeKind.simpleFormalParameter);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set simpleIdentifier_element(int value) {
-    assert(kind == idl.LinkedNodeKind.simpleIdentifier);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set simpleStringLiteral_token(int value) {
-    assert(kind == idl.LinkedNodeKind.simpleStringLiteral);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set spreadElement_spreadOperator(int value) {
-    assert(kind == idl.LinkedNodeKind.spreadElement);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set superConstructorInvocation_element(int value) {
-    assert(kind == idl.LinkedNodeKind.superConstructorInvocation);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set superExpression_superKeyword(int value) {
-    assert(kind == idl.LinkedNodeKind.superExpression);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set switchMember_keyword(int value) {
-    assert(kind == idl.LinkedNodeKind.switchCase ||
-        kind == idl.LinkedNodeKind.switchDefault);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set switchStatement_leftParenthesis(int value) {
-    assert(kind == idl.LinkedNodeKind.switchStatement);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set symbolLiteral_poundSign(int value) {
-    assert(kind == idl.LinkedNodeKind.symbolLiteral);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set thisExpression_thisKeyword(int value) {
-    assert(kind == idl.LinkedNodeKind.thisExpression);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set throwExpression_throwKeyword(int value) {
-    assert(kind == idl.LinkedNodeKind.throwExpression);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set topLevelVariableDeclaration_semicolon(int value) {
-    assert(kind == idl.LinkedNodeKind.topLevelVariableDeclaration);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set tryStatement_finallyKeyword(int value) {
-    assert(kind == idl.LinkedNodeKind.tryStatement);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set typeArgumentList_leftBracket(int value) {
-    assert(kind == idl.LinkedNodeKind.typeArgumentList);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set typeName_question(int value) {
-    assert(kind == idl.LinkedNodeKind.typeName);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set typeParameter_extendsKeyword(int value) {
-    assert(kind == idl.LinkedNodeKind.typeParameter);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set typeParameterList_leftBracket(int value) {
-    assert(kind == idl.LinkedNodeKind.typeParameterList);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set variableDeclaration_equals(int value) {
-    assert(kind == idl.LinkedNodeKind.variableDeclaration);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set variableDeclarationList_keyword(int value) {
-    assert(kind == idl.LinkedNodeKind.variableDeclarationList);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set variableDeclarationStatement_semicolon(int value) {
-    assert(kind == idl.LinkedNodeKind.variableDeclarationStatement);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set whileStatement_leftParenthesis(int value) {
-    assert(kind == idl.LinkedNodeKind.whileStatement);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set withClause_withKeyword(int value) {
-    assert(kind == idl.LinkedNodeKind.withClause);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  set yieldStatement_yieldKeyword(int value) {
-    assert(kind == idl.LinkedNodeKind.yieldStatement);
-    assert(value == null || value >= 0);
-    _variantField_15 = value;
-  }
-
-  @override
   LinkedNodeBuilder get annotation_constructorName {
     assert(kind == idl.LinkedNodeKind.annotation);
     return _variantField_7;
@@ -7309,12 +6143,6 @@
   }
 
   @override
-  LinkedNodeBuilder get constructorDeclaration_name {
-    assert(kind == idl.LinkedNodeKind.constructorDeclaration);
-    return _variantField_7;
-  }
-
-  @override
   LinkedNodeBuilder get constructorFieldInitializer_fieldName {
     assert(kind == idl.LinkedNodeKind.constructorFieldInitializer);
     return _variantField_7;
@@ -7513,24 +6341,6 @@
   }
 
   @override
-  LinkedNodeBuilder get typeName_typeArguments {
-    assert(kind == idl.LinkedNodeKind.typeName);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get typeParameter_name {
-    assert(kind == idl.LinkedNodeKind.typeParameter);
-    return _variantField_7;
-  }
-
-  @override
-  LinkedNodeBuilder get variableDeclaration_name {
-    assert(kind == idl.LinkedNodeKind.variableDeclaration);
-    return _variantField_7;
-  }
-
-  @override
   LinkedNodeBuilder get whileStatement_condition {
     assert(kind == idl.LinkedNodeKind.whileStatement);
     return _variantField_7;
@@ -7591,11 +6401,6 @@
     _variantField_7 = value;
   }
 
-  set constructorDeclaration_name(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.constructorDeclaration);
-    _variantField_7 = value;
-  }
-
   set constructorFieldInitializer_fieldName(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.constructorFieldInitializer);
     _variantField_7 = value;
@@ -7762,21 +6567,6 @@
     _variantField_7 = value;
   }
 
-  set typeName_typeArguments(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.typeName);
-    _variantField_7 = value;
-  }
-
-  set typeParameter_name(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.typeParameter);
-    _variantField_7 = value;
-  }
-
-  set variableDeclaration_name(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.variableDeclaration);
-    _variantField_7 = value;
-  }
-
   set whileStatement_condition(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.whileStatement);
     _variantField_7 = value;
@@ -7789,279 +6579,23 @@
   }
 
   @override
-  int get assertInitializer_leftParenthesis {
-    assert(kind == idl.LinkedNodeKind.assertInitializer);
-    return _variantField_17 ??= 0;
-  }
-
-  @override
-  int get assertStatement_leftParenthesis {
-    assert(kind == idl.LinkedNodeKind.assertStatement);
-    return _variantField_17 ??= 0;
-  }
-
-  @override
-  int get catchClause_leftParenthesis {
-    assert(kind == idl.LinkedNodeKind.catchClause);
-    return _variantField_17 ??= 0;
-  }
-
-  @override
-  int get configuration_rightParenthesis {
-    assert(kind == idl.LinkedNodeKind.configuration);
-    return _variantField_17 ??= 0;
-  }
-
-  @override
-  int get constructorDeclaration_factoryKeyword {
-    assert(kind == idl.LinkedNodeKind.constructorDeclaration);
-    return _variantField_17 ??= 0;
-  }
-
-  @override
-  int get constructorFieldInitializer_thisKeyword {
-    assert(kind == idl.LinkedNodeKind.constructorFieldInitializer);
-    return _variantField_17 ??= 0;
-  }
-
-  @override
-  int get doStatement_doKeyword {
-    assert(kind == idl.LinkedNodeKind.doStatement);
-    return _variantField_17 ??= 0;
-  }
-
-  @override
-  int get enumDeclaration_rightBracket {
-    assert(kind == idl.LinkedNodeKind.enumDeclaration);
-    return _variantField_17 ??= 0;
-  }
-
-  @override
-  int get expressionFunctionBody_semicolon {
-    assert(kind == idl.LinkedNodeKind.expressionFunctionBody);
-    return _variantField_17 ??= 0;
-  }
-
-  @override
-  int get fieldDeclaration_staticKeyword {
-    assert(kind == idl.LinkedNodeKind.fieldDeclaration);
-    return _variantField_17 ??= 0;
-  }
-
-  @override
-  int get fieldFormalParameter_thisKeyword {
-    assert(kind == idl.LinkedNodeKind.fieldFormalParameter);
-    return _variantField_17 ??= 0;
-  }
-
-  @override
-  int get formalParameterList_rightDelimiter {
-    assert(kind == idl.LinkedNodeKind.formalParameterList);
-    return _variantField_17 ??= 0;
-  }
-
-  @override
-  int get forMixin_leftParenthesis {
-    assert(kind == idl.LinkedNodeKind.forElement ||
-        kind == idl.LinkedNodeKind.forStatement);
-    return _variantField_17 ??= 0;
-  }
-
-  @override
   int get genericFunctionType_id {
     assert(kind == idl.LinkedNodeKind.genericFunctionType);
     return _variantField_17 ??= 0;
   }
 
-  @override
-  int get ifMixin_leftParenthesis {
-    assert(kind == idl.LinkedNodeKind.ifElement ||
-        kind == idl.LinkedNodeKind.ifStatement);
-    return _variantField_17 ??= 0;
-  }
-
-  @override
-  int get indexExpression_leftBracket {
-    assert(kind == idl.LinkedNodeKind.indexExpression);
-    return _variantField_17 ??= 0;
-  }
-
-  @override
-  int get methodDeclaration_operatorKeyword {
-    assert(kind == idl.LinkedNodeKind.methodDeclaration);
-    return _variantField_17 ??= 0;
-  }
-
-  @override
-  int get redirectingConstructorInvocation_thisKeyword {
-    assert(kind == idl.LinkedNodeKind.redirectingConstructorInvocation);
-    return _variantField_17 ??= 0;
-  }
-
-  @override
-  int get superConstructorInvocation_superKeyword {
-    assert(kind == idl.LinkedNodeKind.superConstructorInvocation);
-    return _variantField_17 ??= 0;
-  }
-
-  @override
-  int get switchStatement_switchKeyword {
-    assert(kind == idl.LinkedNodeKind.switchStatement);
-    return _variantField_17 ??= 0;
-  }
-
-  @override
-  int get whileStatement_whileKeyword {
-    assert(kind == idl.LinkedNodeKind.whileStatement);
-    return _variantField_17 ??= 0;
-  }
-
-  @override
-  int get yieldStatement_semicolon {
-    assert(kind == idl.LinkedNodeKind.yieldStatement);
-    return _variantField_17 ??= 0;
-  }
-
   set annotation_element(int value) {
     assert(kind == idl.LinkedNodeKind.annotation);
     assert(value == null || value >= 0);
     _variantField_17 = value;
   }
 
-  set assertInitializer_leftParenthesis(int value) {
-    assert(kind == idl.LinkedNodeKind.assertInitializer);
-    assert(value == null || value >= 0);
-    _variantField_17 = value;
-  }
-
-  set assertStatement_leftParenthesis(int value) {
-    assert(kind == idl.LinkedNodeKind.assertStatement);
-    assert(value == null || value >= 0);
-    _variantField_17 = value;
-  }
-
-  set catchClause_leftParenthesis(int value) {
-    assert(kind == idl.LinkedNodeKind.catchClause);
-    assert(value == null || value >= 0);
-    _variantField_17 = value;
-  }
-
-  set configuration_rightParenthesis(int value) {
-    assert(kind == idl.LinkedNodeKind.configuration);
-    assert(value == null || value >= 0);
-    _variantField_17 = value;
-  }
-
-  set constructorDeclaration_factoryKeyword(int value) {
-    assert(kind == idl.LinkedNodeKind.constructorDeclaration);
-    assert(value == null || value >= 0);
-    _variantField_17 = value;
-  }
-
-  set constructorFieldInitializer_thisKeyword(int value) {
-    assert(kind == idl.LinkedNodeKind.constructorFieldInitializer);
-    assert(value == null || value >= 0);
-    _variantField_17 = value;
-  }
-
-  set doStatement_doKeyword(int value) {
-    assert(kind == idl.LinkedNodeKind.doStatement);
-    assert(value == null || value >= 0);
-    _variantField_17 = value;
-  }
-
-  set enumDeclaration_rightBracket(int value) {
-    assert(kind == idl.LinkedNodeKind.enumDeclaration);
-    assert(value == null || value >= 0);
-    _variantField_17 = value;
-  }
-
-  set expressionFunctionBody_semicolon(int value) {
-    assert(kind == idl.LinkedNodeKind.expressionFunctionBody);
-    assert(value == null || value >= 0);
-    _variantField_17 = value;
-  }
-
-  set fieldDeclaration_staticKeyword(int value) {
-    assert(kind == idl.LinkedNodeKind.fieldDeclaration);
-    assert(value == null || value >= 0);
-    _variantField_17 = value;
-  }
-
-  set fieldFormalParameter_thisKeyword(int value) {
-    assert(kind == idl.LinkedNodeKind.fieldFormalParameter);
-    assert(value == null || value >= 0);
-    _variantField_17 = value;
-  }
-
-  set formalParameterList_rightDelimiter(int value) {
-    assert(kind == idl.LinkedNodeKind.formalParameterList);
-    assert(value == null || value >= 0);
-    _variantField_17 = value;
-  }
-
-  set forMixin_leftParenthesis(int value) {
-    assert(kind == idl.LinkedNodeKind.forElement ||
-        kind == idl.LinkedNodeKind.forStatement);
-    assert(value == null || value >= 0);
-    _variantField_17 = value;
-  }
-
   set genericFunctionType_id(int value) {
     assert(kind == idl.LinkedNodeKind.genericFunctionType);
     assert(value == null || value >= 0);
     _variantField_17 = value;
   }
 
-  set ifMixin_leftParenthesis(int value) {
-    assert(kind == idl.LinkedNodeKind.ifElement ||
-        kind == idl.LinkedNodeKind.ifStatement);
-    assert(value == null || value >= 0);
-    _variantField_17 = value;
-  }
-
-  set indexExpression_leftBracket(int value) {
-    assert(kind == idl.LinkedNodeKind.indexExpression);
-    assert(value == null || value >= 0);
-    _variantField_17 = value;
-  }
-
-  set methodDeclaration_operatorKeyword(int value) {
-    assert(kind == idl.LinkedNodeKind.methodDeclaration);
-    assert(value == null || value >= 0);
-    _variantField_17 = value;
-  }
-
-  set redirectingConstructorInvocation_thisKeyword(int value) {
-    assert(kind == idl.LinkedNodeKind.redirectingConstructorInvocation);
-    assert(value == null || value >= 0);
-    _variantField_17 = value;
-  }
-
-  set superConstructorInvocation_superKeyword(int value) {
-    assert(kind == idl.LinkedNodeKind.superConstructorInvocation);
-    assert(value == null || value >= 0);
-    _variantField_17 = value;
-  }
-
-  set switchStatement_switchKeyword(int value) {
-    assert(kind == idl.LinkedNodeKind.switchStatement);
-    assert(value == null || value >= 0);
-    _variantField_17 = value;
-  }
-
-  set whileStatement_whileKeyword(int value) {
-    assert(kind == idl.LinkedNodeKind.whileStatement);
-    assert(value == null || value >= 0);
-    _variantField_17 = value;
-  }
-
-  set yieldStatement_semicolon(int value) {
-    assert(kind == idl.LinkedNodeKind.yieldStatement);
-    assert(value == null || value >= 0);
-    _variantField_17 = value;
-  }
-
   @override
   LinkedNodeTypeBuilder get annotation_elementType {
     assert(kind == idl.LinkedNodeKind.annotation);
@@ -8372,1059 +6906,214 @@
   }
 
   @override
-  int get annotation_period {
-    assert(kind == idl.LinkedNodeKind.annotation);
-    return _variantField_16 ??= 0;
-  }
-
-  @override
-  int get argumentList_rightParenthesis {
-    assert(kind == idl.LinkedNodeKind.argumentList);
-    return _variantField_16 ??= 0;
-  }
-
-  @override
-  int get assertInitializer_comma {
-    assert(kind == idl.LinkedNodeKind.assertInitializer);
-    return _variantField_16 ??= 0;
-  }
-
-  @override
-  int get assertStatement_comma {
-    assert(kind == idl.LinkedNodeKind.assertStatement);
-    return _variantField_16 ??= 0;
-  }
-
-  @override
-  int get assignmentExpression_operator {
+  int get assignmentExpression_element {
     assert(kind == idl.LinkedNodeKind.assignmentExpression);
-    return _variantField_16 ??= 0;
+    return _variantField_15 ??= 0;
   }
 
   @override
-  int get binaryExpression_operator {
+  int get binaryExpression_element {
     assert(kind == idl.LinkedNodeKind.binaryExpression);
-    return _variantField_16 ??= 0;
+    return _variantField_15 ??= 0;
   }
 
   @override
-  int get block_rightBracket {
-    assert(kind == idl.LinkedNodeKind.block);
-    return _variantField_16 ??= 0;
-  }
-
-  @override
-  int get blockFunctionBody_star {
-    assert(kind == idl.LinkedNodeKind.blockFunctionBody);
-    return _variantField_16 ??= 0;
-  }
-
-  @override
-  int get breakStatement_semicolon {
-    assert(kind == idl.LinkedNodeKind.breakStatement);
-    return _variantField_16 ??= 0;
-  }
-
-  @override
-  int get catchClause_comma {
-    assert(kind == idl.LinkedNodeKind.catchClause);
-    return _variantField_16 ??= 0;
-  }
-
-  @override
-  int get classDeclaration_classKeyword {
-    assert(kind == idl.LinkedNodeKind.classDeclaration);
-    return _variantField_16 ??= 0;
-  }
-
-  @override
-  int get classTypeAlias_equals {
-    assert(kind == idl.LinkedNodeKind.classTypeAlias);
-    return _variantField_16 ??= 0;
-  }
-
-  @override
-  int get compilationUnit_endToken {
-    assert(kind == idl.LinkedNodeKind.compilationUnit);
-    return _variantField_16 ??= 0;
-  }
-
-  @override
-  int get conditionalExpression_question {
-    assert(kind == idl.LinkedNodeKind.conditionalExpression);
-    return _variantField_16 ??= 0;
-  }
-
-  @override
-  int get configuration_leftParenthesis {
-    assert(kind == idl.LinkedNodeKind.configuration);
-    return _variantField_16 ??= 0;
-  }
-
-  @override
-  int get constructorDeclaration_externalKeyword {
-    assert(kind == idl.LinkedNodeKind.constructorDeclaration);
-    return _variantField_16 ??= 0;
-  }
-
-  @override
-  int get constructorFieldInitializer_period {
-    assert(kind == idl.LinkedNodeKind.constructorFieldInitializer);
-    return _variantField_16 ??= 0;
-  }
-
-  @override
-  int get constructorName_period {
+  int get constructorName_element {
     assert(kind == idl.LinkedNodeKind.constructorName);
-    return _variantField_16 ??= 0;
+    return _variantField_15 ??= 0;
   }
 
   @override
-  int get continueStatement_semicolon {
-    assert(kind == idl.LinkedNodeKind.continueStatement);
-    return _variantField_16 ??= 0;
+  int get emptyFunctionBody_fake {
+    assert(kind == idl.LinkedNodeKind.emptyFunctionBody);
+    return _variantField_15 ??= 0;
   }
 
   @override
-  int get doStatement_rightParenthesis {
-    assert(kind == idl.LinkedNodeKind.doStatement);
-    return _variantField_16 ??= 0;
+  int get emptyStatement_fake {
+    assert(kind == idl.LinkedNodeKind.emptyStatement);
+    return _variantField_15 ??= 0;
   }
 
   @override
-  int get enumDeclaration_leftBracket {
-    assert(kind == idl.LinkedNodeKind.enumDeclaration);
-    return _variantField_16 ??= 0;
-  }
-
-  @override
-  int get expressionFunctionBody_keyword {
-    assert(kind == idl.LinkedNodeKind.expressionFunctionBody);
-    return _variantField_16 ??= 0;
-  }
-
-  @override
-  int get fieldDeclaration_semicolon {
-    assert(kind == idl.LinkedNodeKind.fieldDeclaration);
-    return _variantField_16 ??= 0;
-  }
-
-  @override
-  int get fieldFormalParameter_period {
-    assert(kind == idl.LinkedNodeKind.fieldFormalParameter);
-    return _variantField_16 ??= 0;
-  }
-
-  @override
-  int get formalParameterList_leftParenthesis {
-    assert(kind == idl.LinkedNodeKind.formalParameterList);
-    return _variantField_16 ??= 0;
-  }
-
-  @override
-  int get forMixin_forKeyword {
-    assert(kind == idl.LinkedNodeKind.forElement ||
-        kind == idl.LinkedNodeKind.forStatement);
-    return _variantField_16 ??= 0;
-  }
-
-  @override
-  int get forParts_rightSeparator {
-    assert(kind == idl.LinkedNodeKind.forPartsWithDeclarations ||
-        kind == idl.LinkedNodeKind.forPartsWithExpression);
-    return _variantField_16 ??= 0;
-  }
-
-  @override
-  int get functionDeclaration_propertyKeyword {
-    assert(kind == idl.LinkedNodeKind.functionDeclaration);
-    return _variantField_16 ??= 0;
-  }
-
-  @override
-  int get genericFunctionType_question {
-    assert(kind == idl.LinkedNodeKind.genericFunctionType);
-    return _variantField_16 ??= 0;
-  }
-
-  @override
-  int get genericTypeAlias_equals {
-    assert(kind == idl.LinkedNodeKind.genericTypeAlias);
-    return _variantField_16 ??= 0;
-  }
-
-  @override
-  int get ifMixin_ifKeyword {
-    assert(kind == idl.LinkedNodeKind.ifElement ||
-        kind == idl.LinkedNodeKind.ifStatement);
-    return _variantField_16 ??= 0;
-  }
-
-  @override
-  int get importDirective_deferredKeyword {
+  int get importDirective_prefixOffset {
     assert(kind == idl.LinkedNodeKind.importDirective);
-    return _variantField_16 ??= 0;
+    return _variantField_15 ??= 0;
   }
 
   @override
-  int get indexExpression_period {
+  int get indexExpression_element {
     assert(kind == idl.LinkedNodeKind.indexExpression);
-    return _variantField_16 ??= 0;
+    return _variantField_15 ??= 0;
   }
 
   @override
-  int get integerLiteral_value {
-    assert(kind == idl.LinkedNodeKind.integerLiteral);
-    return _variantField_16 ??= 0;
+  int get nullLiteral_fake {
+    assert(kind == idl.LinkedNodeKind.nullLiteral);
+    return _variantField_15 ??= 0;
   }
 
   @override
-  int get interpolationExpression_rightBracket {
-    assert(kind == idl.LinkedNodeKind.interpolationExpression);
-    return _variantField_16 ??= 0;
-  }
-
-  @override
-  int get isExpression_notOperator {
-    assert(kind == idl.LinkedNodeKind.isExpression);
-    return _variantField_16 ??= 0;
-  }
-
-  @override
-  int get listLiteral_rightBracket {
-    assert(kind == idl.LinkedNodeKind.listLiteral);
-    return _variantField_16 ??= 0;
-  }
-
-  @override
-  int get methodDeclaration_modifierKeyword {
-    assert(kind == idl.LinkedNodeKind.methodDeclaration);
-    return _variantField_16 ??= 0;
-  }
-
-  @override
-  int get nativeFunctionBody_semicolon {
-    assert(kind == idl.LinkedNodeKind.nativeFunctionBody);
-    return _variantField_16 ??= 0;
-  }
-
-  @override
-  int get parenthesizedExpression_rightParenthesis {
-    assert(kind == idl.LinkedNodeKind.parenthesizedExpression);
-    return _variantField_16 ??= 0;
-  }
-
-  @override
-  int get partOfDirective_ofKeyword {
-    assert(kind == idl.LinkedNodeKind.partOfDirective);
-    return _variantField_16 ??= 0;
-  }
-
-  @override
-  int get postfixExpression_operator {
+  int get postfixExpression_element {
     assert(kind == idl.LinkedNodeKind.postfixExpression);
-    return _variantField_16 ??= 0;
+    return _variantField_15 ??= 0;
   }
 
   @override
-  int get prefixExpression_operator {
+  int get prefixExpression_element {
     assert(kind == idl.LinkedNodeKind.prefixExpression);
-    return _variantField_16 ??= 0;
+    return _variantField_15 ??= 0;
   }
 
   @override
-  int get redirectingConstructorInvocation_period {
+  int get redirectingConstructorInvocation_element {
     assert(kind == idl.LinkedNodeKind.redirectingConstructorInvocation);
-    return _variantField_16 ??= 0;
+    return _variantField_15 ??= 0;
   }
 
   @override
-  int get returnStatement_semicolon {
-    assert(kind == idl.LinkedNodeKind.returnStatement);
-    return _variantField_16 ??= 0;
-  }
-
-  @override
-  int get setOrMapLiteral_rightBracket {
-    assert(kind == idl.LinkedNodeKind.setOrMapLiteral);
-    return _variantField_16 ??= 0;
-  }
-
-  @override
-  int get simpleIdentifier_token {
+  int get simpleIdentifier_element {
     assert(kind == idl.LinkedNodeKind.simpleIdentifier);
-    return _variantField_16 ??= 0;
+    return _variantField_15 ??= 0;
   }
 
   @override
-  int get superConstructorInvocation_period {
+  int get superConstructorInvocation_element {
     assert(kind == idl.LinkedNodeKind.superConstructorInvocation);
-    return _variantField_16 ??= 0;
+    return _variantField_15 ??= 0;
   }
 
-  @override
-  int get switchMember_colon {
-    assert(kind == idl.LinkedNodeKind.switchCase ||
-        kind == idl.LinkedNodeKind.switchDefault);
-    return _variantField_16 ??= 0;
-  }
-
-  @override
-  int get switchStatement_rightParenthesis {
-    assert(kind == idl.LinkedNodeKind.switchStatement);
-    return _variantField_16 ??= 0;
-  }
-
-  @override
-  int get tryStatement_tryKeyword {
-    assert(kind == idl.LinkedNodeKind.tryStatement);
-    return _variantField_16 ??= 0;
-  }
-
-  @override
-  int get typeArgumentList_rightBracket {
-    assert(kind == idl.LinkedNodeKind.typeArgumentList);
-    return _variantField_16 ??= 0;
-  }
-
-  @override
-  int get typeParameterList_rightBracket {
-    assert(kind == idl.LinkedNodeKind.typeParameterList);
-    return _variantField_16 ??= 0;
-  }
-
-  @override
-  int get variableDeclarationList_lateKeyword {
-    assert(kind == idl.LinkedNodeKind.variableDeclarationList);
-    return _variantField_16 ??= 0;
-  }
-
-  @override
-  int get whileStatement_rightParenthesis {
-    assert(kind == idl.LinkedNodeKind.whileStatement);
-    return _variantField_16 ??= 0;
-  }
-
-  @override
-  int get yieldStatement_star {
-    assert(kind == idl.LinkedNodeKind.yieldStatement);
-    return _variantField_16 ??= 0;
-  }
-
-  set annotation_period(int value) {
-    assert(kind == idl.LinkedNodeKind.annotation);
-    assert(value == null || value >= 0);
-    _variantField_16 = value;
-  }
-
-  set argumentList_rightParenthesis(int value) {
-    assert(kind == idl.LinkedNodeKind.argumentList);
-    assert(value == null || value >= 0);
-    _variantField_16 = value;
-  }
-
-  set assertInitializer_comma(int value) {
-    assert(kind == idl.LinkedNodeKind.assertInitializer);
-    assert(value == null || value >= 0);
-    _variantField_16 = value;
-  }
-
-  set assertStatement_comma(int value) {
-    assert(kind == idl.LinkedNodeKind.assertStatement);
-    assert(value == null || value >= 0);
-    _variantField_16 = value;
-  }
-
-  set assignmentExpression_operator(int value) {
+  set assignmentExpression_element(int value) {
     assert(kind == idl.LinkedNodeKind.assignmentExpression);
     assert(value == null || value >= 0);
-    _variantField_16 = value;
+    _variantField_15 = value;
   }
 
-  set binaryExpression_operator(int value) {
+  set binaryExpression_element(int value) {
     assert(kind == idl.LinkedNodeKind.binaryExpression);
     assert(value == null || value >= 0);
-    _variantField_16 = value;
+    _variantField_15 = value;
   }
 
-  set block_rightBracket(int value) {
-    assert(kind == idl.LinkedNodeKind.block);
-    assert(value == null || value >= 0);
-    _variantField_16 = value;
-  }
-
-  set blockFunctionBody_star(int value) {
-    assert(kind == idl.LinkedNodeKind.blockFunctionBody);
-    assert(value == null || value >= 0);
-    _variantField_16 = value;
-  }
-
-  set breakStatement_semicolon(int value) {
-    assert(kind == idl.LinkedNodeKind.breakStatement);
-    assert(value == null || value >= 0);
-    _variantField_16 = value;
-  }
-
-  set catchClause_comma(int value) {
-    assert(kind == idl.LinkedNodeKind.catchClause);
-    assert(value == null || value >= 0);
-    _variantField_16 = value;
-  }
-
-  set classDeclaration_classKeyword(int value) {
-    assert(kind == idl.LinkedNodeKind.classDeclaration);
-    assert(value == null || value >= 0);
-    _variantField_16 = value;
-  }
-
-  set classTypeAlias_equals(int value) {
-    assert(kind == idl.LinkedNodeKind.classTypeAlias);
-    assert(value == null || value >= 0);
-    _variantField_16 = value;
-  }
-
-  set compilationUnit_endToken(int value) {
-    assert(kind == idl.LinkedNodeKind.compilationUnit);
-    assert(value == null || value >= 0);
-    _variantField_16 = value;
-  }
-
-  set conditionalExpression_question(int value) {
-    assert(kind == idl.LinkedNodeKind.conditionalExpression);
-    assert(value == null || value >= 0);
-    _variantField_16 = value;
-  }
-
-  set configuration_leftParenthesis(int value) {
-    assert(kind == idl.LinkedNodeKind.configuration);
-    assert(value == null || value >= 0);
-    _variantField_16 = value;
-  }
-
-  set constructorDeclaration_externalKeyword(int value) {
-    assert(kind == idl.LinkedNodeKind.constructorDeclaration);
-    assert(value == null || value >= 0);
-    _variantField_16 = value;
-  }
-
-  set constructorFieldInitializer_period(int value) {
-    assert(kind == idl.LinkedNodeKind.constructorFieldInitializer);
-    assert(value == null || value >= 0);
-    _variantField_16 = value;
-  }
-
-  set constructorName_period(int value) {
+  set constructorName_element(int value) {
     assert(kind == idl.LinkedNodeKind.constructorName);
     assert(value == null || value >= 0);
-    _variantField_16 = value;
+    _variantField_15 = value;
   }
 
-  set continueStatement_semicolon(int value) {
-    assert(kind == idl.LinkedNodeKind.continueStatement);
+  set emptyFunctionBody_fake(int value) {
+    assert(kind == idl.LinkedNodeKind.emptyFunctionBody);
     assert(value == null || value >= 0);
-    _variantField_16 = value;
+    _variantField_15 = value;
   }
 
-  set doStatement_rightParenthesis(int value) {
-    assert(kind == idl.LinkedNodeKind.doStatement);
+  set emptyStatement_fake(int value) {
+    assert(kind == idl.LinkedNodeKind.emptyStatement);
     assert(value == null || value >= 0);
-    _variantField_16 = value;
+    _variantField_15 = value;
   }
 
-  set enumDeclaration_leftBracket(int value) {
-    assert(kind == idl.LinkedNodeKind.enumDeclaration);
-    assert(value == null || value >= 0);
-    _variantField_16 = value;
-  }
-
-  set expressionFunctionBody_keyword(int value) {
-    assert(kind == idl.LinkedNodeKind.expressionFunctionBody);
-    assert(value == null || value >= 0);
-    _variantField_16 = value;
-  }
-
-  set fieldDeclaration_semicolon(int value) {
-    assert(kind == idl.LinkedNodeKind.fieldDeclaration);
-    assert(value == null || value >= 0);
-    _variantField_16 = value;
-  }
-
-  set fieldFormalParameter_period(int value) {
-    assert(kind == idl.LinkedNodeKind.fieldFormalParameter);
-    assert(value == null || value >= 0);
-    _variantField_16 = value;
-  }
-
-  set formalParameterList_leftParenthesis(int value) {
-    assert(kind == idl.LinkedNodeKind.formalParameterList);
-    assert(value == null || value >= 0);
-    _variantField_16 = value;
-  }
-
-  set forMixin_forKeyword(int value) {
-    assert(kind == idl.LinkedNodeKind.forElement ||
-        kind == idl.LinkedNodeKind.forStatement);
-    assert(value == null || value >= 0);
-    _variantField_16 = value;
-  }
-
-  set forParts_rightSeparator(int value) {
-    assert(kind == idl.LinkedNodeKind.forPartsWithDeclarations ||
-        kind == idl.LinkedNodeKind.forPartsWithExpression);
-    assert(value == null || value >= 0);
-    _variantField_16 = value;
-  }
-
-  set functionDeclaration_propertyKeyword(int value) {
-    assert(kind == idl.LinkedNodeKind.functionDeclaration);
-    assert(value == null || value >= 0);
-    _variantField_16 = value;
-  }
-
-  set genericFunctionType_question(int value) {
-    assert(kind == idl.LinkedNodeKind.genericFunctionType);
-    assert(value == null || value >= 0);
-    _variantField_16 = value;
-  }
-
-  set genericTypeAlias_equals(int value) {
-    assert(kind == idl.LinkedNodeKind.genericTypeAlias);
-    assert(value == null || value >= 0);
-    _variantField_16 = value;
-  }
-
-  set ifMixin_ifKeyword(int value) {
-    assert(kind == idl.LinkedNodeKind.ifElement ||
-        kind == idl.LinkedNodeKind.ifStatement);
-    assert(value == null || value >= 0);
-    _variantField_16 = value;
-  }
-
-  set importDirective_deferredKeyword(int value) {
+  set importDirective_prefixOffset(int value) {
     assert(kind == idl.LinkedNodeKind.importDirective);
     assert(value == null || value >= 0);
-    _variantField_16 = value;
+    _variantField_15 = value;
   }
 
-  set indexExpression_period(int value) {
+  set indexExpression_element(int value) {
     assert(kind == idl.LinkedNodeKind.indexExpression);
     assert(value == null || value >= 0);
-    _variantField_16 = value;
+    _variantField_15 = value;
   }
 
-  set integerLiteral_value(int value) {
-    assert(kind == idl.LinkedNodeKind.integerLiteral);
+  set nullLiteral_fake(int value) {
+    assert(kind == idl.LinkedNodeKind.nullLiteral);
     assert(value == null || value >= 0);
-    _variantField_16 = value;
+    _variantField_15 = value;
   }
 
-  set interpolationExpression_rightBracket(int value) {
-    assert(kind == idl.LinkedNodeKind.interpolationExpression);
-    assert(value == null || value >= 0);
-    _variantField_16 = value;
-  }
-
-  set isExpression_notOperator(int value) {
-    assert(kind == idl.LinkedNodeKind.isExpression);
-    assert(value == null || value >= 0);
-    _variantField_16 = value;
-  }
-
-  set listLiteral_rightBracket(int value) {
-    assert(kind == idl.LinkedNodeKind.listLiteral);
-    assert(value == null || value >= 0);
-    _variantField_16 = value;
-  }
-
-  set methodDeclaration_modifierKeyword(int value) {
-    assert(kind == idl.LinkedNodeKind.methodDeclaration);
-    assert(value == null || value >= 0);
-    _variantField_16 = value;
-  }
-
-  set nativeFunctionBody_semicolon(int value) {
-    assert(kind == idl.LinkedNodeKind.nativeFunctionBody);
-    assert(value == null || value >= 0);
-    _variantField_16 = value;
-  }
-
-  set parenthesizedExpression_rightParenthesis(int value) {
-    assert(kind == idl.LinkedNodeKind.parenthesizedExpression);
-    assert(value == null || value >= 0);
-    _variantField_16 = value;
-  }
-
-  set partOfDirective_ofKeyword(int value) {
-    assert(kind == idl.LinkedNodeKind.partOfDirective);
-    assert(value == null || value >= 0);
-    _variantField_16 = value;
-  }
-
-  set postfixExpression_operator(int value) {
+  set postfixExpression_element(int value) {
     assert(kind == idl.LinkedNodeKind.postfixExpression);
     assert(value == null || value >= 0);
-    _variantField_16 = value;
+    _variantField_15 = value;
   }
 
-  set prefixExpression_operator(int value) {
+  set prefixExpression_element(int value) {
     assert(kind == idl.LinkedNodeKind.prefixExpression);
     assert(value == null || value >= 0);
-    _variantField_16 = value;
+    _variantField_15 = value;
   }
 
-  set redirectingConstructorInvocation_period(int value) {
+  set redirectingConstructorInvocation_element(int value) {
     assert(kind == idl.LinkedNodeKind.redirectingConstructorInvocation);
     assert(value == null || value >= 0);
-    _variantField_16 = value;
+    _variantField_15 = value;
   }
 
-  set returnStatement_semicolon(int value) {
-    assert(kind == idl.LinkedNodeKind.returnStatement);
-    assert(value == null || value >= 0);
-    _variantField_16 = value;
-  }
-
-  set setOrMapLiteral_rightBracket(int value) {
-    assert(kind == idl.LinkedNodeKind.setOrMapLiteral);
-    assert(value == null || value >= 0);
-    _variantField_16 = value;
-  }
-
-  set simpleIdentifier_token(int value) {
+  set simpleIdentifier_element(int value) {
     assert(kind == idl.LinkedNodeKind.simpleIdentifier);
     assert(value == null || value >= 0);
-    _variantField_16 = value;
+    _variantField_15 = value;
   }
 
-  set superConstructorInvocation_period(int value) {
+  set superConstructorInvocation_element(int value) {
     assert(kind == idl.LinkedNodeKind.superConstructorInvocation);
     assert(value == null || value >= 0);
-    _variantField_16 = value;
-  }
-
-  set switchMember_colon(int value) {
-    assert(kind == idl.LinkedNodeKind.switchCase ||
-        kind == idl.LinkedNodeKind.switchDefault);
-    assert(value == null || value >= 0);
-    _variantField_16 = value;
-  }
-
-  set switchStatement_rightParenthesis(int value) {
-    assert(kind == idl.LinkedNodeKind.switchStatement);
-    assert(value == null || value >= 0);
-    _variantField_16 = value;
-  }
-
-  set tryStatement_tryKeyword(int value) {
-    assert(kind == idl.LinkedNodeKind.tryStatement);
-    assert(value == null || value >= 0);
-    _variantField_16 = value;
-  }
-
-  set typeArgumentList_rightBracket(int value) {
-    assert(kind == idl.LinkedNodeKind.typeArgumentList);
-    assert(value == null || value >= 0);
-    _variantField_16 = value;
-  }
-
-  set typeParameterList_rightBracket(int value) {
-    assert(kind == idl.LinkedNodeKind.typeParameterList);
-    assert(value == null || value >= 0);
-    _variantField_16 = value;
-  }
-
-  set variableDeclarationList_lateKeyword(int value) {
-    assert(kind == idl.LinkedNodeKind.variableDeclarationList);
-    assert(value == null || value >= 0);
-    _variantField_16 = value;
-  }
-
-  set whileStatement_rightParenthesis(int value) {
-    assert(kind == idl.LinkedNodeKind.whileStatement);
-    assert(value == null || value >= 0);
-    _variantField_16 = value;
-  }
-
-  set yieldStatement_star(int value) {
-    assert(kind == idl.LinkedNodeKind.yieldStatement);
-    assert(value == null || value >= 0);
-    _variantField_16 = value;
+    _variantField_15 = value;
   }
 
   @override
-  int get assertInitializer_rightParenthesis {
-    assert(kind == idl.LinkedNodeKind.assertInitializer);
-    return _variantField_18 ??= 0;
+  idl.UnlinkedTokenType get assignmentExpression_operator {
+    assert(kind == idl.LinkedNodeKind.assignmentExpression);
+    return _variantField_28 ??= idl.UnlinkedTokenType.NOTHING;
   }
 
   @override
-  int get assertStatement_rightParenthesis {
-    assert(kind == idl.LinkedNodeKind.assertStatement);
-    return _variantField_18 ??= 0;
+  idl.UnlinkedTokenType get binaryExpression_operator {
+    assert(kind == idl.LinkedNodeKind.binaryExpression);
+    return _variantField_28 ??= idl.UnlinkedTokenType.NOTHING;
   }
 
   @override
-  int get catchClause_onKeyword {
-    assert(kind == idl.LinkedNodeKind.catchClause);
-    return _variantField_18 ??= 0;
+  idl.UnlinkedTokenType get postfixExpression_operator {
+    assert(kind == idl.LinkedNodeKind.postfixExpression);
+    return _variantField_28 ??= idl.UnlinkedTokenType.NOTHING;
   }
 
   @override
-  int get classOrMixinDeclaration_rightBracket {
-    assert(kind == idl.LinkedNodeKind.classDeclaration ||
-        kind == idl.LinkedNodeKind.mixinDeclaration);
-    return _variantField_18 ??= 0;
+  idl.UnlinkedTokenType get prefixExpression_operator {
+    assert(kind == idl.LinkedNodeKind.prefixExpression);
+    return _variantField_28 ??= idl.UnlinkedTokenType.NOTHING;
   }
 
   @override
-  int get configuration_equalToken {
-    assert(kind == idl.LinkedNodeKind.configuration);
-    return _variantField_18 ??= 0;
+  idl.UnlinkedTokenType get propertyAccess_operator {
+    assert(kind == idl.LinkedNodeKind.propertyAccess);
+    return _variantField_28 ??= idl.UnlinkedTokenType.NOTHING;
   }
 
-  @override
-  int get constructorDeclaration_period {
-    assert(kind == idl.LinkedNodeKind.constructorDeclaration);
-    return _variantField_18 ??= 0;
+  set assignmentExpression_operator(idl.UnlinkedTokenType value) {
+    assert(kind == idl.LinkedNodeKind.assignmentExpression);
+    _variantField_28 = value;
   }
 
-  @override
-  int get directive_keyword {
-    assert(kind == idl.LinkedNodeKind.exportDirective ||
-        kind == idl.LinkedNodeKind.importDirective ||
-        kind == idl.LinkedNodeKind.libraryDirective ||
-        kind == idl.LinkedNodeKind.partDirective ||
-        kind == idl.LinkedNodeKind.partOfDirective);
-    return _variantField_18 ??= 0;
+  set binaryExpression_operator(idl.UnlinkedTokenType value) {
+    assert(kind == idl.LinkedNodeKind.binaryExpression);
+    _variantField_28 = value;
   }
 
-  @override
-  int get doStatement_semicolon {
-    assert(kind == idl.LinkedNodeKind.doStatement);
-    return _variantField_18 ??= 0;
+  set postfixExpression_operator(idl.UnlinkedTokenType value) {
+    assert(kind == idl.LinkedNodeKind.postfixExpression);
+    _variantField_28 = value;
   }
 
-  @override
-  int get formalParameterList_rightParenthesis {
-    assert(kind == idl.LinkedNodeKind.formalParameterList);
-    return _variantField_18 ??= 0;
+  set prefixExpression_operator(idl.UnlinkedTokenType value) {
+    assert(kind == idl.LinkedNodeKind.prefixExpression);
+    _variantField_28 = value;
   }
 
-  @override
-  int get ifMixin_rightParenthesis {
-    assert(kind == idl.LinkedNodeKind.ifElement ||
-        kind == idl.LinkedNodeKind.ifStatement);
-    return _variantField_18 ??= 0;
-  }
-
-  @override
-  int get indexExpression_rightBracket {
-    assert(kind == idl.LinkedNodeKind.indexExpression);
-    return _variantField_18 ??= 0;
-  }
-
-  @override
-  int get methodDeclaration_propertyKeyword {
-    assert(kind == idl.LinkedNodeKind.methodDeclaration);
-    return _variantField_18 ??= 0;
-  }
-
-  @override
-  int get normalFormalParameter_requiredKeyword {
-    assert(kind == idl.LinkedNodeKind.fieldFormalParameter ||
-        kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
-        kind == idl.LinkedNodeKind.simpleFormalParameter);
-    return _variantField_18 ??= 0;
-  }
-
-  @override
-  int get switchStatement_leftBracket {
-    assert(kind == idl.LinkedNodeKind.switchStatement);
-    return _variantField_18 ??= 0;
-  }
-
-  @override
-  int get typeAlias_typedefKeyword {
-    assert(kind == idl.LinkedNodeKind.classTypeAlias ||
-        kind == idl.LinkedNodeKind.functionTypeAlias ||
-        kind == idl.LinkedNodeKind.genericTypeAlias);
-    return _variantField_18 ??= 0;
-  }
-
-  set assertInitializer_rightParenthesis(int value) {
-    assert(kind == idl.LinkedNodeKind.assertInitializer);
-    assert(value == null || value >= 0);
-    _variantField_18 = value;
-  }
-
-  set assertStatement_rightParenthesis(int value) {
-    assert(kind == idl.LinkedNodeKind.assertStatement);
-    assert(value == null || value >= 0);
-    _variantField_18 = value;
-  }
-
-  set catchClause_onKeyword(int value) {
-    assert(kind == idl.LinkedNodeKind.catchClause);
-    assert(value == null || value >= 0);
-    _variantField_18 = value;
-  }
-
-  set classOrMixinDeclaration_rightBracket(int value) {
-    assert(kind == idl.LinkedNodeKind.classDeclaration ||
-        kind == idl.LinkedNodeKind.mixinDeclaration);
-    assert(value == null || value >= 0);
-    _variantField_18 = value;
-  }
-
-  set configuration_equalToken(int value) {
-    assert(kind == idl.LinkedNodeKind.configuration);
-    assert(value == null || value >= 0);
-    _variantField_18 = value;
-  }
-
-  set constructorDeclaration_period(int value) {
-    assert(kind == idl.LinkedNodeKind.constructorDeclaration);
-    assert(value == null || value >= 0);
-    _variantField_18 = value;
-  }
-
-  set directive_keyword(int value) {
-    assert(kind == idl.LinkedNodeKind.exportDirective ||
-        kind == idl.LinkedNodeKind.importDirective ||
-        kind == idl.LinkedNodeKind.libraryDirective ||
-        kind == idl.LinkedNodeKind.partDirective ||
-        kind == idl.LinkedNodeKind.partOfDirective);
-    assert(value == null || value >= 0);
-    _variantField_18 = value;
-  }
-
-  set doStatement_semicolon(int value) {
-    assert(kind == idl.LinkedNodeKind.doStatement);
-    assert(value == null || value >= 0);
-    _variantField_18 = value;
-  }
-
-  set formalParameterList_rightParenthesis(int value) {
-    assert(kind == idl.LinkedNodeKind.formalParameterList);
-    assert(value == null || value >= 0);
-    _variantField_18 = value;
-  }
-
-  set ifMixin_rightParenthesis(int value) {
-    assert(kind == idl.LinkedNodeKind.ifElement ||
-        kind == idl.LinkedNodeKind.ifStatement);
-    assert(value == null || value >= 0);
-    _variantField_18 = value;
-  }
-
-  set indexExpression_rightBracket(int value) {
-    assert(kind == idl.LinkedNodeKind.indexExpression);
-    assert(value == null || value >= 0);
-    _variantField_18 = value;
-  }
-
-  set methodDeclaration_propertyKeyword(int value) {
-    assert(kind == idl.LinkedNodeKind.methodDeclaration);
-    assert(value == null || value >= 0);
-    _variantField_18 = value;
-  }
-
-  set normalFormalParameter_requiredKeyword(int value) {
-    assert(kind == idl.LinkedNodeKind.fieldFormalParameter ||
-        kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
-        kind == idl.LinkedNodeKind.simpleFormalParameter);
-    assert(value == null || value >= 0);
-    _variantField_18 = value;
-  }
-
-  set switchStatement_leftBracket(int value) {
-    assert(kind == idl.LinkedNodeKind.switchStatement);
-    assert(value == null || value >= 0);
-    _variantField_18 = value;
-  }
-
-  set typeAlias_typedefKeyword(int value) {
-    assert(kind == idl.LinkedNodeKind.classTypeAlias ||
-        kind == idl.LinkedNodeKind.functionTypeAlias ||
-        kind == idl.LinkedNodeKind.genericTypeAlias);
-    assert(value == null || value >= 0);
-    _variantField_18 = value;
-  }
-
-  @override
-  int get assertStatement_semicolon {
-    assert(kind == idl.LinkedNodeKind.assertStatement);
-    return _variantField_19 ??= 0;
-  }
-
-  @override
-  int get catchClause_rightParenthesis {
-    assert(kind == idl.LinkedNodeKind.catchClause);
-    return _variantField_19 ??= 0;
-  }
-
-  @override
-  int get classOrMixinDeclaration_leftBracket {
-    assert(kind == idl.LinkedNodeKind.classDeclaration ||
-        kind == idl.LinkedNodeKind.mixinDeclaration);
-    return _variantField_19 ??= 0;
-  }
-
-  @override
-  int get combinator_keyword {
-    assert(kind == idl.LinkedNodeKind.hideCombinator ||
-        kind == idl.LinkedNodeKind.showCombinator);
-    return _variantField_19 ??= 0;
-  }
-
-  @override
-  int get constructorDeclaration_separator {
-    assert(kind == idl.LinkedNodeKind.constructorDeclaration);
-    return _variantField_19 ??= 0;
-  }
-
-  @override
-  int get doStatement_whileKeyword {
-    assert(kind == idl.LinkedNodeKind.doStatement);
-    return _variantField_19 ??= 0;
-  }
-
-  @override
-  int get forMixin_rightParenthesis {
-    assert(kind == idl.LinkedNodeKind.forElement ||
-        kind == idl.LinkedNodeKind.forStatement);
-    return _variantField_19 ??= 0;
-  }
-
-  @override
-  int get methodDeclaration_actualProperty {
-    assert(kind == idl.LinkedNodeKind.methodDeclaration);
-    return _variantField_19 ??= 0;
-  }
-
-  @override
-  int get normalFormalParameter_covariantKeyword {
-    assert(kind == idl.LinkedNodeKind.fieldFormalParameter ||
-        kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
-        kind == idl.LinkedNodeKind.simpleFormalParameter);
-    return _variantField_19 ??= 0;
-  }
-
-  @override
-  int get switchStatement_rightBracket {
-    assert(kind == idl.LinkedNodeKind.switchStatement);
-    return _variantField_19 ??= 0;
-  }
-
-  @override
-  int get typeAlias_semicolon {
-    assert(kind == idl.LinkedNodeKind.classTypeAlias ||
-        kind == idl.LinkedNodeKind.functionTypeAlias ||
-        kind == idl.LinkedNodeKind.genericTypeAlias);
-    return _variantField_19 ??= 0;
-  }
-
-  @override
-  int get typedLiteral_constKeyword {
-    assert(kind == idl.LinkedNodeKind.listLiteral ||
-        kind == idl.LinkedNodeKind.setOrMapLiteral);
-    return _variantField_19 ??= 0;
-  }
-
-  @override
-  int get uriBasedDirective_uriElement {
-    assert(kind == idl.LinkedNodeKind.exportDirective ||
-        kind == idl.LinkedNodeKind.importDirective ||
-        kind == idl.LinkedNodeKind.partDirective);
-    return _variantField_19 ??= 0;
-  }
-
-  set assertStatement_semicolon(int value) {
-    assert(kind == idl.LinkedNodeKind.assertStatement);
-    assert(value == null || value >= 0);
-    _variantField_19 = value;
-  }
-
-  set catchClause_rightParenthesis(int value) {
-    assert(kind == idl.LinkedNodeKind.catchClause);
-    assert(value == null || value >= 0);
-    _variantField_19 = value;
-  }
-
-  set classOrMixinDeclaration_leftBracket(int value) {
-    assert(kind == idl.LinkedNodeKind.classDeclaration ||
-        kind == idl.LinkedNodeKind.mixinDeclaration);
-    assert(value == null || value >= 0);
-    _variantField_19 = value;
-  }
-
-  set combinator_keyword(int value) {
-    assert(kind == idl.LinkedNodeKind.hideCombinator ||
-        kind == idl.LinkedNodeKind.showCombinator);
-    assert(value == null || value >= 0);
-    _variantField_19 = value;
-  }
-
-  set constructorDeclaration_separator(int value) {
-    assert(kind == idl.LinkedNodeKind.constructorDeclaration);
-    assert(value == null || value >= 0);
-    _variantField_19 = value;
-  }
-
-  set doStatement_whileKeyword(int value) {
-    assert(kind == idl.LinkedNodeKind.doStatement);
-    assert(value == null || value >= 0);
-    _variantField_19 = value;
-  }
-
-  set forMixin_rightParenthesis(int value) {
-    assert(kind == idl.LinkedNodeKind.forElement ||
-        kind == idl.LinkedNodeKind.forStatement);
-    assert(value == null || value >= 0);
-    _variantField_19 = value;
-  }
-
-  set methodDeclaration_actualProperty(int value) {
-    assert(kind == idl.LinkedNodeKind.methodDeclaration);
-    assert(value == null || value >= 0);
-    _variantField_19 = value;
-  }
-
-  set normalFormalParameter_covariantKeyword(int value) {
-    assert(kind == idl.LinkedNodeKind.fieldFormalParameter ||
-        kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
-        kind == idl.LinkedNodeKind.simpleFormalParameter);
-    assert(value == null || value >= 0);
-    _variantField_19 = value;
-  }
-
-  set switchStatement_rightBracket(int value) {
-    assert(kind == idl.LinkedNodeKind.switchStatement);
-    assert(value == null || value >= 0);
-    _variantField_19 = value;
-  }
-
-  set typeAlias_semicolon(int value) {
-    assert(kind == idl.LinkedNodeKind.classTypeAlias ||
-        kind == idl.LinkedNodeKind.functionTypeAlias ||
-        kind == idl.LinkedNodeKind.genericTypeAlias);
-    assert(value == null || value >= 0);
-    _variantField_19 = value;
-  }
-
-  set typedLiteral_constKeyword(int value) {
-    assert(kind == idl.LinkedNodeKind.listLiteral ||
-        kind == idl.LinkedNodeKind.setOrMapLiteral);
-    assert(value == null || value >= 0);
-    _variantField_19 = value;
-  }
-
-  set uriBasedDirective_uriElement(int value) {
-    assert(kind == idl.LinkedNodeKind.exportDirective ||
-        kind == idl.LinkedNodeKind.importDirective ||
-        kind == idl.LinkedNodeKind.partDirective);
-    assert(value == null || value >= 0);
-    _variantField_19 = value;
+  set propertyAccess_operator(idl.UnlinkedTokenType value) {
+    assert(kind == idl.LinkedNodeKind.propertyAccess);
+    _variantField_28 = value;
   }
 
   @override
@@ -9449,18 +7138,6 @@
   }
 
   @override
-  bool get setOrMapLiteral_isMap {
-    assert(kind == idl.LinkedNodeKind.setOrMapLiteral);
-    return _variantField_27 ??= false;
-  }
-
-  @override
-  bool get simpleIdentifier_isDeclaration {
-    assert(kind == idl.LinkedNodeKind.simpleIdentifier);
-    return _variantField_27 ??= false;
-  }
-
-  @override
   bool get typeAlias_hasSelfReference {
     assert(kind == idl.LinkedNodeKind.functionTypeAlias ||
         kind == idl.LinkedNodeKind.genericTypeAlias);
@@ -9485,16 +7162,6 @@
     _variantField_27 = value;
   }
 
-  set setOrMapLiteral_isMap(bool value) {
-    assert(kind == idl.LinkedNodeKind.setOrMapLiteral);
-    _variantField_27 = value;
-  }
-
-  set simpleIdentifier_isDeclaration(bool value) {
-    assert(kind == idl.LinkedNodeKind.simpleIdentifier);
-    _variantField_27 = value;
-  }
-
   set typeAlias_hasSelfReference(bool value) {
     assert(kind == idl.LinkedNodeKind.functionTypeAlias ||
         kind == idl.LinkedNodeKind.genericTypeAlias);
@@ -9570,14 +7237,6 @@
     return _variantField_12;
   }
 
-  @override
-  LinkedNodeBuilder get normalFormalParameter_identifier {
-    assert(kind == idl.LinkedNodeKind.fieldFormalParameter ||
-        kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
-        kind == idl.LinkedNodeKind.simpleFormalParameter);
-    return _variantField_12;
-  }
-
   set classOrMixinDeclaration_implementsClause(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.classDeclaration ||
         kind == idl.LinkedNodeKind.mixinDeclaration);
@@ -9590,13 +7249,6 @@
     _variantField_12 = value;
   }
 
-  set normalFormalParameter_identifier(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.fieldFormalParameter ||
-        kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
-        kind == idl.LinkedNodeKind.simpleFormalParameter);
-    _variantField_12 = value;
-  }
-
   @override
   List<LinkedNodeBuilder> get classOrMixinDeclaration_members {
     assert(kind == idl.LinkedNodeKind.classDeclaration ||
@@ -9699,16 +7351,6 @@
     return _variantField_33 ??= 0;
   }
 
-  @override
-  int get directive_semicolon {
-    assert(kind == idl.LinkedNodeKind.exportDirective ||
-        kind == idl.LinkedNodeKind.importDirective ||
-        kind == idl.LinkedNodeKind.libraryDirective ||
-        kind == idl.LinkedNodeKind.partDirective ||
-        kind == idl.LinkedNodeKind.partOfDirective);
-    return _variantField_33 ??= 0;
-  }
-
   set codeOffset(int value) {
     assert(kind == idl.LinkedNodeKind.classDeclaration ||
         kind == idl.LinkedNodeKind.classTypeAlias ||
@@ -9730,38 +7372,41 @@
     _variantField_33 = value;
   }
 
-  set directive_semicolon(int value) {
-    assert(kind == idl.LinkedNodeKind.exportDirective ||
-        kind == idl.LinkedNodeKind.importDirective ||
-        kind == idl.LinkedNodeKind.libraryDirective ||
-        kind == idl.LinkedNodeKind.partDirective ||
-        kind == idl.LinkedNodeKind.partOfDirective);
-    assert(value == null || value >= 0);
-    _variantField_33 = value;
+  @override
+  List<String> get comment_tokens {
+    assert(kind == idl.LinkedNodeKind.comment);
+    return _variantField_36 ??= <String>[];
   }
 
   @override
-  List<int> get comment_tokens {
-    assert(kind == idl.LinkedNodeKind.comment);
-    return _variantField_28 ??= <int>[];
+  List<String> get mixinDeclaration_superInvokedNames {
+    assert(kind == idl.LinkedNodeKind.mixinDeclaration);
+    return _variantField_36 ??= <String>[];
   }
 
   @override
-  List<int> get symbolLiteral_components {
-    assert(kind == idl.LinkedNodeKind.symbolLiteral);
-    return _variantField_28 ??= <int>[];
+  List<String> get names {
+    assert(kind == idl.LinkedNodeKind.hideCombinator ||
+        kind == idl.LinkedNodeKind.showCombinator ||
+        kind == idl.LinkedNodeKind.symbolLiteral);
+    return _variantField_36 ??= <String>[];
   }
 
-  set comment_tokens(List<int> value) {
+  set comment_tokens(List<String> value) {
     assert(kind == idl.LinkedNodeKind.comment);
-    assert(value == null || value.every((e) => e >= 0));
-    _variantField_28 = value;
+    _variantField_36 = value;
   }
 
-  set symbolLiteral_components(List<int> value) {
-    assert(kind == idl.LinkedNodeKind.symbolLiteral);
-    assert(value == null || value.every((e) => e >= 0));
-    _variantField_28 = value;
+  set mixinDeclaration_superInvokedNames(List<String> value) {
+    assert(kind == idl.LinkedNodeKind.mixinDeclaration);
+    _variantField_36 = value;
+  }
+
+  set names(List<String> value) {
+    assert(kind == idl.LinkedNodeKind.hideCombinator ||
+        kind == idl.LinkedNodeKind.showCombinator ||
+        kind == idl.LinkedNodeKind.symbolLiteral);
+    _variantField_36 = value;
   }
 
   @override
@@ -9782,6 +7427,12 @@
   }
 
   @override
+  List<LinkedNodeBuilder> get listLiteral_elements {
+    assert(kind == idl.LinkedNodeKind.listLiteral);
+    return _variantField_3 ??= <LinkedNodeBuilder>[];
+  }
+
+  @override
   List<LinkedNodeBuilder> get namespaceDirective_configurations {
     assert(kind == idl.LinkedNodeKind.exportDirective ||
         kind == idl.LinkedNodeKind.importDirective);
@@ -9789,6 +7440,12 @@
   }
 
   @override
+  List<LinkedNodeBuilder> get setOrMapLiteral_elements {
+    assert(kind == idl.LinkedNodeKind.setOrMapLiteral);
+    return _variantField_3 ??= <LinkedNodeBuilder>[];
+  }
+
+  @override
   List<LinkedNodeBuilder> get switchMember_labels {
     assert(kind == idl.LinkedNodeKind.switchCase ||
         kind == idl.LinkedNodeKind.switchDefault);
@@ -9800,12 +7457,22 @@
     _variantField_3 = value;
   }
 
+  set listLiteral_elements(List<LinkedNodeBuilder> value) {
+    assert(kind == idl.LinkedNodeKind.listLiteral);
+    _variantField_3 = value;
+  }
+
   set namespaceDirective_configurations(List<LinkedNodeBuilder> value) {
     assert(kind == idl.LinkedNodeKind.exportDirective ||
         kind == idl.LinkedNodeKind.importDirective);
     _variantField_3 = value;
   }
 
+  set setOrMapLiteral_elements(List<LinkedNodeBuilder> value) {
+    assert(kind == idl.LinkedNodeKind.setOrMapLiteral);
+    _variantField_3 = value;
+  }
+
   set switchMember_labels(List<LinkedNodeBuilder> value) {
     assert(kind == idl.LinkedNodeKind.switchCase ||
         kind == idl.LinkedNodeKind.switchDefault);
@@ -9818,22 +7485,11 @@
     return _variantField_10;
   }
 
-  @override
-  LinkedNodeBuilder get methodDeclaration_name {
-    assert(kind == idl.LinkedNodeKind.methodDeclaration);
-    return _variantField_10;
-  }
-
   set constructorDeclaration_returnType(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.constructorDeclaration);
     _variantField_10 = value;
   }
 
-  set methodDeclaration_name(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.methodDeclaration);
-    _variantField_10 = value;
-  }
-
   @override
   idl.LinkedNodeFormalParameterKind get defaultFormalParameter_kind {
     assert(kind == idl.LinkedNodeKind.defaultFormalParameter);
@@ -9859,23 +7515,17 @@
 
   @override
   LinkedNodeTypeBuilder get expression_type {
-    assert(kind == idl.LinkedNodeKind.adjacentStrings ||
-        kind == idl.LinkedNodeKind.assignmentExpression ||
+    assert(kind == idl.LinkedNodeKind.assignmentExpression ||
         kind == idl.LinkedNodeKind.asExpression ||
         kind == idl.LinkedNodeKind.awaitExpression ||
         kind == idl.LinkedNodeKind.binaryExpression ||
-        kind == idl.LinkedNodeKind.booleanLiteral ||
         kind == idl.LinkedNodeKind.cascadeExpression ||
         kind == idl.LinkedNodeKind.conditionalExpression ||
-        kind == idl.LinkedNodeKind.doubleLiteral ||
         kind == idl.LinkedNodeKind.functionExpressionInvocation ||
         kind == idl.LinkedNodeKind.indexExpression ||
         kind == idl.LinkedNodeKind.instanceCreationExpression ||
-        kind == idl.LinkedNodeKind.integerLiteral ||
-        kind == idl.LinkedNodeKind.isExpression ||
         kind == idl.LinkedNodeKind.listLiteral ||
         kind == idl.LinkedNodeKind.methodInvocation ||
-        kind == idl.LinkedNodeKind.namedExpression ||
         kind == idl.LinkedNodeKind.nullLiteral ||
         kind == idl.LinkedNodeKind.parenthesizedExpression ||
         kind == idl.LinkedNodeKind.prefixExpression ||
@@ -9885,8 +7535,6 @@
         kind == idl.LinkedNodeKind.rethrowExpression ||
         kind == idl.LinkedNodeKind.setOrMapLiteral ||
         kind == idl.LinkedNodeKind.simpleIdentifier ||
-        kind == idl.LinkedNodeKind.simpleStringLiteral ||
-        kind == idl.LinkedNodeKind.stringInterpolation ||
         kind == idl.LinkedNodeKind.superExpression ||
         kind == idl.LinkedNodeKind.symbolLiteral ||
         kind == idl.LinkedNodeKind.thisExpression ||
@@ -9901,23 +7549,17 @@
   }
 
   set expression_type(LinkedNodeTypeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.adjacentStrings ||
-        kind == idl.LinkedNodeKind.assignmentExpression ||
+    assert(kind == idl.LinkedNodeKind.assignmentExpression ||
         kind == idl.LinkedNodeKind.asExpression ||
         kind == idl.LinkedNodeKind.awaitExpression ||
         kind == idl.LinkedNodeKind.binaryExpression ||
-        kind == idl.LinkedNodeKind.booleanLiteral ||
         kind == idl.LinkedNodeKind.cascadeExpression ||
         kind == idl.LinkedNodeKind.conditionalExpression ||
-        kind == idl.LinkedNodeKind.doubleLiteral ||
         kind == idl.LinkedNodeKind.functionExpressionInvocation ||
         kind == idl.LinkedNodeKind.indexExpression ||
         kind == idl.LinkedNodeKind.instanceCreationExpression ||
-        kind == idl.LinkedNodeKind.integerLiteral ||
-        kind == idl.LinkedNodeKind.isExpression ||
         kind == idl.LinkedNodeKind.listLiteral ||
         kind == idl.LinkedNodeKind.methodInvocation ||
-        kind == idl.LinkedNodeKind.namedExpression ||
         kind == idl.LinkedNodeKind.nullLiteral ||
         kind == idl.LinkedNodeKind.parenthesizedExpression ||
         kind == idl.LinkedNodeKind.prefixExpression ||
@@ -9927,8 +7569,6 @@
         kind == idl.LinkedNodeKind.rethrowExpression ||
         kind == idl.LinkedNodeKind.setOrMapLiteral ||
         kind == idl.LinkedNodeKind.simpleIdentifier ||
-        kind == idl.LinkedNodeKind.simpleStringLiteral ||
-        kind == idl.LinkedNodeKind.stringInterpolation ||
         kind == idl.LinkedNodeKind.superExpression ||
         kind == idl.LinkedNodeKind.symbolLiteral ||
         kind == idl.LinkedNodeKind.thisExpression ||
@@ -9942,6 +7582,83 @@
   }
 
   @override
+  int get flags => _flags ??= 0;
+
+  set flags(int value) {
+    assert(value == null || value >= 0);
+    this._flags = value;
+  }
+
+  @override
+  String get importDirective_prefix {
+    assert(kind == idl.LinkedNodeKind.importDirective);
+    return _variantField_1 ??= '';
+  }
+
+  set importDirective_prefix(String value) {
+    assert(kind == idl.LinkedNodeKind.importDirective);
+    _variantField_1 = value;
+  }
+
+  @override
+  int get integerLiteral_value {
+    assert(kind == idl.LinkedNodeKind.integerLiteral);
+    return _variantField_16 ??= 0;
+  }
+
+  @override
+  int get nameOffset {
+    assert(kind == idl.LinkedNodeKind.classDeclaration ||
+        kind == idl.LinkedNodeKind.classTypeAlias ||
+        kind == idl.LinkedNodeKind.constructorDeclaration ||
+        kind == idl.LinkedNodeKind.enumConstantDeclaration ||
+        kind == idl.LinkedNodeKind.enumDeclaration ||
+        kind == idl.LinkedNodeKind.exportDirective ||
+        kind == idl.LinkedNodeKind.fieldFormalParameter ||
+        kind == idl.LinkedNodeKind.functionDeclaration ||
+        kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
+        kind == idl.LinkedNodeKind.functionTypeAlias ||
+        kind == idl.LinkedNodeKind.genericTypeAlias ||
+        kind == idl.LinkedNodeKind.importDirective ||
+        kind == idl.LinkedNodeKind.methodDeclaration ||
+        kind == idl.LinkedNodeKind.mixinDeclaration ||
+        kind == idl.LinkedNodeKind.partDirective ||
+        kind == idl.LinkedNodeKind.simpleFormalParameter ||
+        kind == idl.LinkedNodeKind.typeParameter ||
+        kind == idl.LinkedNodeKind.variableDeclaration);
+    return _variantField_16 ??= 0;
+  }
+
+  set integerLiteral_value(int value) {
+    assert(kind == idl.LinkedNodeKind.integerLiteral);
+    assert(value == null || value >= 0);
+    _variantField_16 = value;
+  }
+
+  set nameOffset(int value) {
+    assert(kind == idl.LinkedNodeKind.classDeclaration ||
+        kind == idl.LinkedNodeKind.classTypeAlias ||
+        kind == idl.LinkedNodeKind.constructorDeclaration ||
+        kind == idl.LinkedNodeKind.enumConstantDeclaration ||
+        kind == idl.LinkedNodeKind.enumDeclaration ||
+        kind == idl.LinkedNodeKind.exportDirective ||
+        kind == idl.LinkedNodeKind.fieldFormalParameter ||
+        kind == idl.LinkedNodeKind.functionDeclaration ||
+        kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
+        kind == idl.LinkedNodeKind.functionTypeAlias ||
+        kind == idl.LinkedNodeKind.genericTypeAlias ||
+        kind == idl.LinkedNodeKind.importDirective ||
+        kind == idl.LinkedNodeKind.methodDeclaration ||
+        kind == idl.LinkedNodeKind.mixinDeclaration ||
+        kind == idl.LinkedNodeKind.partDirective ||
+        kind == idl.LinkedNodeKind.simpleFormalParameter ||
+        kind == idl.LinkedNodeKind.typeParameter ||
+        kind == idl.LinkedNodeKind.variableDeclaration);
+    assert(value == null || value >= 0);
+    _variantField_16 = value;
+  }
+
+  @override
   String get interpolationString_value {
     assert(kind == idl.LinkedNodeKind.interpolationString);
     return _variantField_30 ??= '';
@@ -9960,18 +7677,6 @@
   }
 
   @override
-  LinkedNodeBuilder get namedCompilationUnitMember_name {
-    assert(kind == idl.LinkedNodeKind.classDeclaration ||
-        kind == idl.LinkedNodeKind.classTypeAlias ||
-        kind == idl.LinkedNodeKind.enumDeclaration ||
-        kind == idl.LinkedNodeKind.functionDeclaration ||
-        kind == idl.LinkedNodeKind.functionTypeAlias ||
-        kind == idl.LinkedNodeKind.genericTypeAlias ||
-        kind == idl.LinkedNodeKind.mixinDeclaration);
-    return _variantField_14;
-  }
-
-  @override
   LinkedNodeBuilder get normalFormalParameter_comment {
     assert(kind == idl.LinkedNodeKind.fieldFormalParameter ||
         kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
@@ -9980,13 +7685,6 @@
   }
 
   @override
-  LinkedNodeBuilder get typedLiteral_typeArguments {
-    assert(kind == idl.LinkedNodeKind.listLiteral ||
-        kind == idl.LinkedNodeKind.setOrMapLiteral);
-    return _variantField_14;
-  }
-
-  @override
   LinkedNodeBuilder get uriBasedDirective_uri {
     assert(kind == idl.LinkedNodeKind.exportDirective ||
         kind == idl.LinkedNodeKind.importDirective ||
@@ -10000,17 +7698,6 @@
     _variantField_14 = value;
   }
 
-  set namedCompilationUnitMember_name(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.classDeclaration ||
-        kind == idl.LinkedNodeKind.classTypeAlias ||
-        kind == idl.LinkedNodeKind.enumDeclaration ||
-        kind == idl.LinkedNodeKind.functionDeclaration ||
-        kind == idl.LinkedNodeKind.functionTypeAlias ||
-        kind == idl.LinkedNodeKind.genericTypeAlias ||
-        kind == idl.LinkedNodeKind.mixinDeclaration);
-    _variantField_14 = value;
-  }
-
   set normalFormalParameter_comment(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.fieldFormalParameter ||
         kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
@@ -10018,12 +7705,6 @@
     _variantField_14 = value;
   }
 
-  set typedLiteral_typeArguments(LinkedNodeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.listLiteral ||
-        kind == idl.LinkedNodeKind.setOrMapLiteral);
-    _variantField_14 = value;
-  }
-
   set uriBasedDirective_uri(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.exportDirective ||
         kind == idl.LinkedNodeKind.importDirective ||
@@ -10032,13 +7713,6 @@
   }
 
   @override
-  bool get isSynthetic => _isSynthetic ??= false;
-
-  set isSynthetic(bool value) {
-    this._isSynthetic = value;
-  }
-
-  @override
   idl.LinkedNodeKind get kind => _kind ??= idl.LinkedNodeKind.adjacentStrings;
 
   set kind(idl.LinkedNodeKind value) {
@@ -10046,14 +7720,10 @@
   }
 
   @override
-  List<String> get mixinDeclaration_superInvokedNames {
-    assert(kind == idl.LinkedNodeKind.mixinDeclaration);
-    return _variantField_36 ??= <String>[];
-  }
+  String get name => _name ??= '';
 
-  set mixinDeclaration_superInvokedNames(List<String> value) {
-    assert(kind == idl.LinkedNodeKind.mixinDeclaration);
-    _variantField_36 = value;
+  set name(String value) {
+    this._name = value;
   }
 
   @override
@@ -10081,12 +7751,6 @@
   }
 
   @override
-  bool get setOrMapLiteral_isSet {
-    assert(kind == idl.LinkedNodeKind.setOrMapLiteral);
-    return _variantField_31 ??= false;
-  }
-
-  @override
   bool get simplyBoundable_isSimplyBounded {
     assert(kind == idl.LinkedNodeKind.classDeclaration ||
         kind == idl.LinkedNodeKind.classTypeAlias ||
@@ -10096,11 +7760,6 @@
     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 ||
@@ -10111,6 +7770,17 @@
   }
 
   @override
+  idl.UnlinkedTokenType get spreadElement_spreadOperator {
+    assert(kind == idl.LinkedNodeKind.spreadElement);
+    return _variantField_38 ??= idl.UnlinkedTokenType.NOTHING;
+  }
+
+  set spreadElement_spreadOperator(idl.UnlinkedTokenType value) {
+    assert(kind == idl.LinkedNodeKind.spreadElement);
+    _variantField_38 = value;
+  }
+
+  @override
   TopLevelInferenceErrorBuilder get topLevelTypeInferenceError {
     assert(kind == idl.LinkedNodeKind.simpleFormalParameter ||
         kind == idl.LinkedNodeKind.variableDeclaration);
@@ -10139,6 +7809,22 @@
   }
 
   @override
+  int get uriBasedDirective_uriElement {
+    assert(kind == idl.LinkedNodeKind.exportDirective ||
+        kind == idl.LinkedNodeKind.importDirective ||
+        kind == idl.LinkedNodeKind.partDirective);
+    return _variantField_19 ??= 0;
+  }
+
+  set uriBasedDirective_uriElement(int value) {
+    assert(kind == idl.LinkedNodeKind.exportDirective ||
+        kind == idl.LinkedNodeKind.importDirective ||
+        kind == idl.LinkedNodeKind.partDirective);
+    assert(value == null || value >= 0);
+    _variantField_19 = value;
+  }
+
+  @override
   LinkedNodeVariablesDeclarationBuilder get variableDeclaration_declaration {
     assert(kind == idl.LinkedNodeKind.variableDeclaration);
     return _variantField_32;
@@ -10155,23 +7841,19 @@
     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,
+    int nameOffset,
   })  : _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;
+        _variantField_16 = nameOffset;
 
   LinkedNodeBuilder.functionExpression({
     LinkedNodeTypeBuilder actualReturnType,
@@ -10191,12 +7873,10 @@
     LinkedNodeBuilder functionTypeAlias_formalParameters,
     LinkedNodeBuilder functionTypeAlias_returnType,
     LinkedNodeBuilder functionTypeAlias_typeParameters,
-    int typeAlias_typedefKeyword,
-    int typeAlias_semicolon,
     bool typeAlias_hasSelfReference,
     int codeLength,
     int codeOffset,
-    LinkedNodeBuilder namedCompilationUnitMember_name,
+    int nameOffset,
     bool simplyBoundable_isSimplyBounded,
   })  : _kind = idl.LinkedNodeKind.functionTypeAlias,
         _variantField_24 = actualReturnType,
@@ -10205,31 +7885,25 @@
         _variantField_6 = functionTypeAlias_formalParameters,
         _variantField_7 = functionTypeAlias_returnType,
         _variantField_8 = functionTypeAlias_typeParameters,
-        _variantField_18 = typeAlias_typedefKeyword,
-        _variantField_19 = typeAlias_semicolon,
         _variantField_27 = typeAlias_hasSelfReference,
         _variantField_34 = codeLength,
         _variantField_33 = codeOffset,
-        _variantField_14 = namedCompilationUnitMember_name,
+        _variantField_16 = nameOffset,
         _variantField_31 = simplyBoundable_isSimplyBounded;
 
   LinkedNodeBuilder.genericFunctionType({
     LinkedNodeTypeBuilder actualReturnType,
     LinkedNodeBuilder genericFunctionType_typeParameters,
-    int genericFunctionType_functionKeyword,
     LinkedNodeBuilder genericFunctionType_returnType,
     int genericFunctionType_id,
     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_17 = genericFunctionType_id,
         _variantField_8 = genericFunctionType_formalParameters,
-        _variantField_16 = genericFunctionType_question,
         _variantField_25 = genericFunctionType_type;
 
   LinkedNodeBuilder.methodDeclaration({
@@ -10237,65 +7911,45 @@
     LinkedNodeBuilder annotatedNode_comment,
     List<LinkedNodeBuilder> annotatedNode_metadata,
     LinkedNodeBuilder methodDeclaration_body,
-    int methodDeclaration_externalKeyword,
     LinkedNodeBuilder methodDeclaration_formalParameters,
-    int methodDeclaration_operatorKeyword,
     LinkedNodeBuilder methodDeclaration_returnType,
-    int methodDeclaration_modifierKeyword,
-    int methodDeclaration_propertyKeyword,
-    int methodDeclaration_actualProperty,
     LinkedNodeBuilder methodDeclaration_typeParameters,
     int codeLength,
     int codeOffset,
-    LinkedNodeBuilder methodDeclaration_name,
+    int nameOffset,
   })  : _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_17 = methodDeclaration_operatorKeyword,
         _variantField_8 = methodDeclaration_returnType,
-        _variantField_16 = methodDeclaration_modifierKeyword,
-        _variantField_18 = methodDeclaration_propertyKeyword,
-        _variantField_19 = methodDeclaration_actualProperty,
         _variantField_9 = methodDeclaration_typeParameters,
         _variantField_34 = codeLength,
         _variantField_33 = codeOffset,
-        _variantField_10 = methodDeclaration_name;
+        _variantField_16 = nameOffset;
 
   LinkedNodeBuilder.fieldFormalParameter({
     LinkedNodeTypeBuilder actualType,
     List<LinkedNodeBuilder> normalFormalParameter_metadata,
     LinkedNodeBuilder fieldFormalParameter_type,
-    int fieldFormalParameter_keyword,
     LinkedNodeBuilder fieldFormalParameter_typeParameters,
-    int fieldFormalParameter_thisKeyword,
     LinkedNodeBuilder fieldFormalParameter_formalParameters,
-    int fieldFormalParameter_period,
-    int normalFormalParameter_requiredKeyword,
-    int normalFormalParameter_covariantKeyword,
     bool inheritsCovariant,
-    LinkedNodeBuilder normalFormalParameter_identifier,
     int codeLength,
     int codeOffset,
+    int nameOffset,
     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_17 = fieldFormalParameter_thisKeyword,
         _variantField_8 = fieldFormalParameter_formalParameters,
-        _variantField_16 = fieldFormalParameter_period,
-        _variantField_18 = normalFormalParameter_requiredKeyword,
-        _variantField_19 = normalFormalParameter_covariantKeyword,
         _variantField_27 = inheritsCovariant,
-        _variantField_12 = normalFormalParameter_identifier,
         _variantField_34 = codeLength,
         _variantField_33 = codeOffset,
+        _variantField_16 = nameOffset,
         _variantField_14 = normalFormalParameter_comment;
 
   LinkedNodeBuilder.functionTypedFormalParameter({
@@ -10304,12 +7958,10 @@
     LinkedNodeBuilder functionTypedFormalParameter_formalParameters,
     LinkedNodeBuilder functionTypedFormalParameter_returnType,
     LinkedNodeBuilder functionTypedFormalParameter_typeParameters,
-    int normalFormalParameter_requiredKeyword,
-    int normalFormalParameter_covariantKeyword,
     bool inheritsCovariant,
-    LinkedNodeBuilder normalFormalParameter_identifier,
     int codeLength,
     int codeOffset,
+    int nameOffset,
     LinkedNodeBuilder normalFormalParameter_comment,
   })  : _kind = idl.LinkedNodeKind.functionTypedFormalParameter,
         _variantField_24 = actualType,
@@ -10317,38 +7969,30 @@
         _variantField_6 = functionTypedFormalParameter_formalParameters,
         _variantField_7 = functionTypedFormalParameter_returnType,
         _variantField_8 = functionTypedFormalParameter_typeParameters,
-        _variantField_18 = normalFormalParameter_requiredKeyword,
-        _variantField_19 = normalFormalParameter_covariantKeyword,
         _variantField_27 = inheritsCovariant,
-        _variantField_12 = normalFormalParameter_identifier,
         _variantField_34 = codeLength,
         _variantField_33 = codeOffset,
+        _variantField_16 = nameOffset,
         _variantField_14 = normalFormalParameter_comment;
 
   LinkedNodeBuilder.simpleFormalParameter({
     LinkedNodeTypeBuilder actualType,
     List<LinkedNodeBuilder> normalFormalParameter_metadata,
     LinkedNodeBuilder simpleFormalParameter_type,
-    int simpleFormalParameter_keyword,
-    int normalFormalParameter_requiredKeyword,
-    int normalFormalParameter_covariantKeyword,
     bool inheritsCovariant,
-    LinkedNodeBuilder normalFormalParameter_identifier,
     int codeLength,
     int codeOffset,
+    int nameOffset,
     LinkedNodeBuilder normalFormalParameter_comment,
     TopLevelInferenceErrorBuilder topLevelTypeInferenceError,
   })  : _kind = idl.LinkedNodeKind.simpleFormalParameter,
         _variantField_24 = actualType,
         _variantField_4 = normalFormalParameter_metadata,
         _variantField_6 = simpleFormalParameter_type,
-        _variantField_15 = simpleFormalParameter_keyword,
-        _variantField_18 = normalFormalParameter_requiredKeyword,
-        _variantField_19 = normalFormalParameter_covariantKeyword,
         _variantField_27 = inheritsCovariant,
-        _variantField_12 = normalFormalParameter_identifier,
         _variantField_34 = codeLength,
         _variantField_33 = codeOffset,
+        _variantField_16 = nameOffset,
         _variantField_14 = normalFormalParameter_comment,
         _variantField_35 = topLevelTypeInferenceError;
 
@@ -10357,11 +8001,10 @@
     LinkedNodeBuilder annotatedNode_comment,
     List<LinkedNodeBuilder> annotatedNode_metadata,
     LinkedNodeBuilder variableDeclaration_initializer,
-    int variableDeclaration_equals,
-    LinkedNodeBuilder variableDeclaration_name,
     bool inheritsCovariant,
     int codeLength,
     int codeOffset,
+    int nameOffset,
     TopLevelInferenceErrorBuilder topLevelTypeInferenceError,
     LinkedNodeVariablesDeclarationBuilder variableDeclaration_declaration,
   })  : _kind = idl.LinkedNodeKind.variableDeclaration,
@@ -10369,29 +8012,28 @@
         _variantField_11 = annotatedNode_comment,
         _variantField_4 = annotatedNode_metadata,
         _variantField_6 = variableDeclaration_initializer,
-        _variantField_15 = variableDeclaration_equals,
-        _variantField_7 = variableDeclaration_name,
         _variantField_27 = inheritsCovariant,
         _variantField_34 = codeLength,
         _variantField_33 = codeOffset,
+        _variantField_16 = nameOffset,
         _variantField_35 = topLevelTypeInferenceError,
         _variantField_32 = variableDeclaration_declaration;
 
   LinkedNodeBuilder.binaryExpression({
     LinkedNodeTypeBuilder binaryExpression_invokeType,
     LinkedNodeBuilder binaryExpression_leftOperand,
-    int binaryExpression_element,
     LinkedNodeBuilder binaryExpression_rightOperand,
     LinkedNodeTypeBuilder binaryExpression_elementType,
-    int binaryExpression_operator,
+    int binaryExpression_element,
+    idl.UnlinkedTokenType 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_23 = binaryExpression_elementType,
-        _variantField_16 = binaryExpression_operator,
+        _variantField_15 = binaryExpression_element,
+        _variantField_28 = binaryExpression_operator,
         _variantField_25 = expression_type;
 
   LinkedNodeBuilder.functionExpressionInvocation({
@@ -10410,7 +8052,6 @@
   LinkedNodeBuilder.methodInvocation({
     LinkedNodeTypeBuilder invocationExpression_invokeType,
     LinkedNodeBuilder methodInvocation_methodName,
-    int methodInvocation_operator,
     LinkedNodeBuilder methodInvocation_target,
     LinkedNodeBuilder invocationExpression_typeArguments,
     LinkedNodeTypeBuilder expression_type,
@@ -10418,7 +8059,6 @@
   })  : _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,
@@ -10426,28 +8066,18 @@
 
   LinkedNodeBuilder.adjacentStrings({
     List<LinkedNodeBuilder> adjacentStrings_strings,
-    LinkedNodeTypeBuilder expression_type,
   })  : _kind = idl.LinkedNodeKind.adjacentStrings,
-        _variantField_2 = adjacentStrings_strings,
-        _variantField_25 = expression_type;
+        _variantField_2 = adjacentStrings_strings;
 
   LinkedNodeBuilder.argumentList({
     List<LinkedNodeBuilder> argumentList_arguments,
-    int argumentList_leftParenthesis,
-    int argumentList_rightParenthesis,
   })  : _kind = idl.LinkedNodeKind.argumentList,
-        _variantField_2 = argumentList_arguments,
-        _variantField_15 = argumentList_leftParenthesis,
-        _variantField_16 = argumentList_rightParenthesis;
+        _variantField_2 = argumentList_arguments;
 
   LinkedNodeBuilder.block({
     List<LinkedNodeBuilder> block_statements,
-    int block_leftBracket,
-    int block_rightBracket,
   })  : _kind = idl.LinkedNodeKind.block,
-        _variantField_2 = block_statements,
-        _variantField_15 = block_leftBracket,
-        _variantField_16 = block_rightBracket;
+        _variantField_2 = block_statements;
 
   LinkedNodeBuilder.cascadeExpression({
     List<LinkedNodeBuilder> cascadeExpression_sections,
@@ -10460,26 +8090,22 @@
 
   LinkedNodeBuilder.comment({
     List<LinkedNodeBuilder> comment_references,
-    List<int> comment_tokens,
+    List<String> comment_tokens,
     idl.LinkedNodeCommentType comment_type,
   })  : _kind = idl.LinkedNodeKind.comment,
         _variantField_2 = comment_references,
-        _variantField_28 = comment_tokens,
+        _variantField_36 = comment_tokens,
         _variantField_29 = comment_type;
 
   LinkedNodeBuilder.compilationUnit({
     List<LinkedNodeBuilder> compilationUnit_declarations,
     LinkedNodeBuilder compilationUnit_scriptTag,
-    int compilationUnit_beginToken,
-    int compilationUnit_endToken,
     int codeLength,
     int codeOffset,
     List<LinkedNodeBuilder> compilationUnit_directives,
   })  : _kind = idl.LinkedNodeKind.compilationUnit,
         _variantField_2 = compilationUnit_declarations,
         _variantField_6 = compilationUnit_scriptTag,
-        _variantField_15 = compilationUnit_beginToken,
-        _variantField_16 = compilationUnit_endToken,
         _variantField_34 = codeLength,
         _variantField_33 = codeOffset,
         _variantField_3 = compilationUnit_directives;
@@ -10489,33 +8115,23 @@
     LinkedNodeBuilder annotatedNode_comment,
     List<LinkedNodeBuilder> annotatedNode_metadata,
     LinkedNodeBuilder constructorDeclaration_body,
-    int constructorDeclaration_constKeyword,
-    LinkedNodeBuilder constructorDeclaration_name,
-    int constructorDeclaration_factoryKeyword,
     LinkedNodeBuilder constructorDeclaration_parameters,
-    int constructorDeclaration_externalKeyword,
-    int constructorDeclaration_period,
-    int constructorDeclaration_separator,
     LinkedNodeBuilder constructorDeclaration_redirectedConstructor,
     int codeLength,
     int codeOffset,
     LinkedNodeBuilder constructorDeclaration_returnType,
+    int nameOffset,
   })  : _kind = idl.LinkedNodeKind.constructorDeclaration,
         _variantField_2 = constructorDeclaration_initializers,
         _variantField_11 = annotatedNode_comment,
         _variantField_4 = annotatedNode_metadata,
         _variantField_6 = constructorDeclaration_body,
-        _variantField_15 = constructorDeclaration_constKeyword,
-        _variantField_7 = constructorDeclaration_name,
-        _variantField_17 = constructorDeclaration_factoryKeyword,
         _variantField_8 = constructorDeclaration_parameters,
-        _variantField_16 = constructorDeclaration_externalKeyword,
-        _variantField_18 = constructorDeclaration_period,
-        _variantField_19 = constructorDeclaration_separator,
         _variantField_9 = constructorDeclaration_redirectedConstructor,
         _variantField_34 = codeLength,
         _variantField_33 = codeOffset,
-        _variantField_10 = constructorDeclaration_returnType;
+        _variantField_10 = constructorDeclaration_returnType,
+        _variantField_16 = nameOffset;
 
   LinkedNodeBuilder.dottedName({
     List<LinkedNodeBuilder> dottedName_components,
@@ -10526,49 +8142,37 @@
     List<LinkedNodeBuilder> enumDeclaration_constants,
     LinkedNodeBuilder annotatedNode_comment,
     List<LinkedNodeBuilder> annotatedNode_metadata,
-    int enumDeclaration_enumKeyword,
-    int enumDeclaration_rightBracket,
-    int enumDeclaration_leftBracket,
     int codeLength,
     int codeOffset,
-    LinkedNodeBuilder namedCompilationUnitMember_name,
+    int nameOffset,
   })  : _kind = idl.LinkedNodeKind.enumDeclaration,
         _variantField_2 = enumDeclaration_constants,
         _variantField_11 = annotatedNode_comment,
         _variantField_4 = annotatedNode_metadata,
-        _variantField_15 = enumDeclaration_enumKeyword,
-        _variantField_17 = enumDeclaration_rightBracket,
-        _variantField_16 = enumDeclaration_leftBracket,
         _variantField_34 = codeLength,
         _variantField_33 = codeOffset,
-        _variantField_14 = namedCompilationUnitMember_name;
+        _variantField_16 = nameOffset;
 
   LinkedNodeBuilder.formalParameterList({
     List<LinkedNodeBuilder> formalParameterList_parameters,
-    int formalParameterList_leftDelimiter,
-    int formalParameterList_rightDelimiter,
-    int formalParameterList_leftParenthesis,
-    int formalParameterList_rightParenthesis,
   })  : _kind = idl.LinkedNodeKind.formalParameterList,
-        _variantField_2 = formalParameterList_parameters,
-        _variantField_15 = formalParameterList_leftDelimiter,
-        _variantField_17 = formalParameterList_rightDelimiter,
-        _variantField_16 = formalParameterList_leftParenthesis,
-        _variantField_18 = formalParameterList_rightParenthesis;
-
-  LinkedNodeBuilder.hideCombinator({
-    List<LinkedNodeBuilder> hideCombinator_hiddenNames,
-    int combinator_keyword,
-  })  : _kind = idl.LinkedNodeKind.hideCombinator,
-        _variantField_2 = hideCombinator_hiddenNames,
-        _variantField_19 = combinator_keyword;
+        _variantField_2 = formalParameterList_parameters;
 
   LinkedNodeBuilder.implementsClause({
     List<LinkedNodeBuilder> implementsClause_interfaces,
-    int implementsClause_implementsKeyword,
   })  : _kind = idl.LinkedNodeKind.implementsClause,
-        _variantField_2 = implementsClause_interfaces,
-        _variantField_15 = implementsClause_implementsKeyword;
+        _variantField_2 = implementsClause_interfaces;
+
+  LinkedNodeBuilder.instanceCreationExpression({
+    List<LinkedNodeBuilder> instanceCreationExpression_arguments,
+    LinkedNodeBuilder instanceCreationExpression_constructorName,
+    LinkedNodeBuilder instanceCreationExpression_typeArguments,
+    LinkedNodeTypeBuilder expression_type,
+  })  : _kind = idl.LinkedNodeKind.instanceCreationExpression,
+        _variantField_2 = instanceCreationExpression_arguments,
+        _variantField_7 = instanceCreationExpression_constructorName,
+        _variantField_8 = instanceCreationExpression_typeArguments,
+        _variantField_25 = expression_type;
 
   LinkedNodeBuilder.labeledStatement({
     List<LinkedNodeBuilder> labeledStatement_labels,
@@ -10582,654 +8186,470 @@
   })  : _kind = idl.LinkedNodeKind.libraryIdentifier,
         _variantField_2 = libraryIdentifier_components;
 
-  LinkedNodeBuilder.listLiteral({
-    List<LinkedNodeBuilder> listLiteral_elements,
-    int listLiteral_leftBracket,
-    int listLiteral_rightBracket,
-    int typedLiteral_constKeyword,
-    LinkedNodeTypeBuilder expression_type,
-    LinkedNodeBuilder typedLiteral_typeArguments,
-  })  : _kind = idl.LinkedNodeKind.listLiteral,
-        _variantField_2 = listLiteral_elements,
-        _variantField_15 = listLiteral_leftBracket,
-        _variantField_16 = listLiteral_rightBracket,
-        _variantField_19 = typedLiteral_constKeyword,
-        _variantField_25 = expression_type,
-        _variantField_14 = typedLiteral_typeArguments;
-
   LinkedNodeBuilder.exportDirective({
     List<LinkedNodeBuilder> namespaceDirective_combinators,
     LinkedNodeBuilder annotatedNode_comment,
     List<LinkedNodeBuilder> annotatedNode_metadata,
-    int directive_keyword,
-    int uriBasedDirective_uriElement,
-    int directive_semicolon,
     List<LinkedNodeBuilder> namespaceDirective_configurations,
+    int nameOffset,
     LinkedNodeBuilder uriBasedDirective_uri,
     String namespaceDirective_selectedUri,
     String uriBasedDirective_uriContent,
+    int uriBasedDirective_uriElement,
   })  : _kind = idl.LinkedNodeKind.exportDirective,
         _variantField_2 = namespaceDirective_combinators,
         _variantField_11 = annotatedNode_comment,
         _variantField_4 = annotatedNode_metadata,
-        _variantField_18 = directive_keyword,
-        _variantField_19 = uriBasedDirective_uriElement,
-        _variantField_33 = directive_semicolon,
         _variantField_3 = namespaceDirective_configurations,
+        _variantField_16 = nameOffset,
         _variantField_14 = uriBasedDirective_uri,
         _variantField_20 = namespaceDirective_selectedUri,
-        _variantField_22 = uriBasedDirective_uriContent;
+        _variantField_22 = uriBasedDirective_uriContent,
+        _variantField_19 = uriBasedDirective_uriElement;
 
   LinkedNodeBuilder.importDirective({
     List<LinkedNodeBuilder> namespaceDirective_combinators,
     LinkedNodeBuilder annotatedNode_comment,
     List<LinkedNodeBuilder> annotatedNode_metadata,
-    LinkedNodeBuilder importDirective_prefix,
-    int importDirective_asKeyword,
-    int importDirective_deferredKeyword,
-    int directive_keyword,
-    int uriBasedDirective_uriElement,
-    int directive_semicolon,
+    int importDirective_prefixOffset,
     List<LinkedNodeBuilder> namespaceDirective_configurations,
+    String importDirective_prefix,
+    int nameOffset,
     LinkedNodeBuilder uriBasedDirective_uri,
     String namespaceDirective_selectedUri,
     String uriBasedDirective_uriContent,
+    int uriBasedDirective_uriElement,
   })  : _kind = idl.LinkedNodeKind.importDirective,
         _variantField_2 = namespaceDirective_combinators,
         _variantField_11 = annotatedNode_comment,
         _variantField_4 = annotatedNode_metadata,
-        _variantField_6 = importDirective_prefix,
-        _variantField_15 = importDirective_asKeyword,
-        _variantField_16 = importDirective_deferredKeyword,
-        _variantField_18 = directive_keyword,
-        _variantField_19 = uriBasedDirective_uriElement,
-        _variantField_33 = directive_semicolon,
+        _variantField_15 = importDirective_prefixOffset,
         _variantField_3 = namespaceDirective_configurations,
+        _variantField_1 = importDirective_prefix,
+        _variantField_16 = nameOffset,
         _variantField_14 = uriBasedDirective_uri,
         _variantField_20 = namespaceDirective_selectedUri,
-        _variantField_22 = uriBasedDirective_uriContent;
+        _variantField_22 = uriBasedDirective_uriContent,
+        _variantField_19 = uriBasedDirective_uriElement;
 
   LinkedNodeBuilder.onClause({
     List<LinkedNodeBuilder> onClause_superclassConstraints,
-    int onClause_onKeyword,
   })  : _kind = idl.LinkedNodeKind.onClause,
-        _variantField_2 = onClause_superclassConstraints,
-        _variantField_15 = onClause_onKeyword;
-
-  LinkedNodeBuilder.setOrMapLiteral({
-    List<LinkedNodeBuilder> setOrMapLiteral_elements,
-    int setOrMapLiteral_leftBracket,
-    int setOrMapLiteral_rightBracket,
-    int typedLiteral_constKeyword,
-    bool setOrMapLiteral_isMap,
-    LinkedNodeTypeBuilder expression_type,
-    LinkedNodeBuilder typedLiteral_typeArguments,
-    bool setOrMapLiteral_isSet,
-  })  : _kind = idl.LinkedNodeKind.setOrMapLiteral,
-        _variantField_2 = setOrMapLiteral_elements,
-        _variantField_15 = setOrMapLiteral_leftBracket,
-        _variantField_16 = setOrMapLiteral_rightBracket,
-        _variantField_19 = typedLiteral_constKeyword,
-        _variantField_27 = setOrMapLiteral_isMap,
-        _variantField_25 = expression_type,
-        _variantField_14 = typedLiteral_typeArguments,
-        _variantField_31 = setOrMapLiteral_isSet;
-
-  LinkedNodeBuilder.showCombinator({
-    List<LinkedNodeBuilder> showCombinator_shownNames,
-    int combinator_keyword,
-  })  : _kind = idl.LinkedNodeKind.showCombinator,
-        _variantField_2 = showCombinator_shownNames,
-        _variantField_19 = combinator_keyword;
+        _variantField_2 = onClause_superclassConstraints;
 
   LinkedNodeBuilder.stringInterpolation({
     List<LinkedNodeBuilder> stringInterpolation_elements,
-    LinkedNodeTypeBuilder expression_type,
   })  : _kind = idl.LinkedNodeKind.stringInterpolation,
-        _variantField_2 = stringInterpolation_elements,
-        _variantField_25 = expression_type;
+        _variantField_2 = stringInterpolation_elements;
 
   LinkedNodeBuilder.switchStatement({
     List<LinkedNodeBuilder> switchStatement_members,
-    int switchStatement_leftParenthesis,
     LinkedNodeBuilder switchStatement_expression,
-    int switchStatement_switchKeyword,
-    int switchStatement_rightParenthesis,
-    int switchStatement_leftBracket,
-    int switchStatement_rightBracket,
   })  : _kind = idl.LinkedNodeKind.switchStatement,
         _variantField_2 = switchStatement_members,
-        _variantField_15 = switchStatement_leftParenthesis,
-        _variantField_7 = switchStatement_expression,
-        _variantField_17 = switchStatement_switchKeyword,
-        _variantField_16 = switchStatement_rightParenthesis,
-        _variantField_18 = switchStatement_leftBracket,
-        _variantField_19 = switchStatement_rightBracket;
+        _variantField_7 = switchStatement_expression;
 
   LinkedNodeBuilder.tryStatement({
     List<LinkedNodeBuilder> tryStatement_catchClauses,
     LinkedNodeBuilder tryStatement_body,
-    int tryStatement_finallyKeyword,
     LinkedNodeBuilder tryStatement_finallyBlock,
-    int tryStatement_tryKeyword,
   })  : _kind = idl.LinkedNodeKind.tryStatement,
         _variantField_2 = tryStatement_catchClauses,
         _variantField_6 = tryStatement_body,
-        _variantField_15 = tryStatement_finallyKeyword,
-        _variantField_7 = tryStatement_finallyBlock,
-        _variantField_16 = tryStatement_tryKeyword;
+        _variantField_7 = tryStatement_finallyBlock;
 
   LinkedNodeBuilder.typeArgumentList({
     List<LinkedNodeBuilder> typeArgumentList_arguments,
-    int typeArgumentList_leftBracket,
-    int typeArgumentList_rightBracket,
   })  : _kind = idl.LinkedNodeKind.typeArgumentList,
-        _variantField_2 = typeArgumentList_arguments,
-        _variantField_15 = typeArgumentList_leftBracket,
-        _variantField_16 = typeArgumentList_rightBracket;
+        _variantField_2 = typeArgumentList_arguments;
+
+  LinkedNodeBuilder.listLiteral({
+    List<LinkedNodeBuilder> typedLiteral_typeArguments,
+    List<LinkedNodeBuilder> listLiteral_elements,
+    LinkedNodeTypeBuilder expression_type,
+  })  : _kind = idl.LinkedNodeKind.listLiteral,
+        _variantField_2 = typedLiteral_typeArguments,
+        _variantField_3 = listLiteral_elements,
+        _variantField_25 = expression_type;
+
+  LinkedNodeBuilder.setOrMapLiteral({
+    List<LinkedNodeBuilder> typedLiteral_typeArguments,
+    List<LinkedNodeBuilder> setOrMapLiteral_elements,
+    LinkedNodeTypeBuilder expression_type,
+  })  : _kind = idl.LinkedNodeKind.setOrMapLiteral,
+        _variantField_2 = typedLiteral_typeArguments,
+        _variantField_3 = setOrMapLiteral_elements,
+        _variantField_25 = expression_type;
+
+  LinkedNodeBuilder.typeName({
+    List<LinkedNodeBuilder> typeName_typeArguments,
+    LinkedNodeBuilder typeName_name,
+    LinkedNodeTypeBuilder typeName_type,
+  })  : _kind = idl.LinkedNodeKind.typeName,
+        _variantField_2 = typeName_typeArguments,
+        _variantField_6 = typeName_name,
+        _variantField_23 = typeName_type;
 
   LinkedNodeBuilder.typeParameterList({
     List<LinkedNodeBuilder> typeParameterList_typeParameters,
-    int typeParameterList_leftBracket,
-    int typeParameterList_rightBracket,
   })  : _kind = idl.LinkedNodeKind.typeParameterList,
-        _variantField_2 = typeParameterList_typeParameters,
-        _variantField_15 = typeParameterList_leftBracket,
-        _variantField_16 = typeParameterList_rightBracket;
+        _variantField_2 = typeParameterList_typeParameters;
 
   LinkedNodeBuilder.variableDeclarationList({
     List<LinkedNodeBuilder> variableDeclarationList_variables,
     LinkedNodeBuilder annotatedNode_comment,
     List<LinkedNodeBuilder> annotatedNode_metadata,
     LinkedNodeBuilder variableDeclarationList_type,
-    int variableDeclarationList_keyword,
-    int variableDeclarationList_lateKeyword,
   })  : _kind = idl.LinkedNodeKind.variableDeclarationList,
         _variantField_2 = variableDeclarationList_variables,
         _variantField_11 = annotatedNode_comment,
         _variantField_4 = annotatedNode_metadata,
-        _variantField_6 = variableDeclarationList_type,
-        _variantField_15 = variableDeclarationList_keyword,
-        _variantField_16 = variableDeclarationList_lateKeyword;
+        _variantField_6 = variableDeclarationList_type;
 
   LinkedNodeBuilder.withClause({
     List<LinkedNodeBuilder> withClause_mixinTypes,
-    int withClause_withKeyword,
   })  : _kind = idl.LinkedNodeKind.withClause,
-        _variantField_2 = withClause_mixinTypes,
-        _variantField_15 = withClause_withKeyword;
+        _variantField_2 = withClause_mixinTypes;
 
   LinkedNodeBuilder.classDeclaration({
     LinkedNodeBuilder annotatedNode_comment,
     List<LinkedNodeBuilder> annotatedNode_metadata,
     LinkedNodeBuilder classDeclaration_extendsClause,
-    int classDeclaration_abstractKeyword,
     LinkedNodeBuilder classDeclaration_withClause,
     LinkedNodeBuilder classDeclaration_nativeClause,
-    int classDeclaration_classKeyword,
-    int classOrMixinDeclaration_rightBracket,
-    int classOrMixinDeclaration_leftBracket,
     bool classDeclaration_isDartObject,
     LinkedNodeBuilder classOrMixinDeclaration_implementsClause,
     List<LinkedNodeBuilder> classOrMixinDeclaration_members,
     LinkedNodeBuilder classOrMixinDeclaration_typeParameters,
     int codeLength,
     int codeOffset,
-    LinkedNodeBuilder namedCompilationUnitMember_name,
+    int nameOffset,
     bool simplyBoundable_isSimplyBounded,
   })  : _kind = idl.LinkedNodeKind.classDeclaration,
         _variantField_11 = annotatedNode_comment,
         _variantField_4 = annotatedNode_metadata,
         _variantField_6 = classDeclaration_extendsClause,
-        _variantField_15 = classDeclaration_abstractKeyword,
         _variantField_7 = classDeclaration_withClause,
         _variantField_8 = classDeclaration_nativeClause,
-        _variantField_16 = classDeclaration_classKeyword,
-        _variantField_18 = classOrMixinDeclaration_rightBracket,
-        _variantField_19 = classOrMixinDeclaration_leftBracket,
         _variantField_27 = classDeclaration_isDartObject,
         _variantField_12 = classOrMixinDeclaration_implementsClause,
         _variantField_5 = classOrMixinDeclaration_members,
         _variantField_13 = classOrMixinDeclaration_typeParameters,
         _variantField_34 = codeLength,
         _variantField_33 = codeOffset,
-        _variantField_14 = namedCompilationUnitMember_name,
+        _variantField_16 = nameOffset,
         _variantField_31 = simplyBoundable_isSimplyBounded;
 
   LinkedNodeBuilder.classTypeAlias({
     LinkedNodeBuilder annotatedNode_comment,
     List<LinkedNodeBuilder> annotatedNode_metadata,
     LinkedNodeBuilder classTypeAlias_typeParameters,
-    int classTypeAlias_abstractKeyword,
     LinkedNodeBuilder classTypeAlias_superclass,
     LinkedNodeBuilder classTypeAlias_withClause,
-    int classTypeAlias_equals,
-    int typeAlias_typedefKeyword,
-    int typeAlias_semicolon,
     LinkedNodeBuilder classTypeAlias_implementsClause,
     int codeLength,
     int codeOffset,
-    LinkedNodeBuilder namedCompilationUnitMember_name,
+    int nameOffset,
     bool simplyBoundable_isSimplyBounded,
   })  : _kind = idl.LinkedNodeKind.classTypeAlias,
         _variantField_11 = annotatedNode_comment,
         _variantField_4 = annotatedNode_metadata,
         _variantField_6 = classTypeAlias_typeParameters,
-        _variantField_15 = classTypeAlias_abstractKeyword,
         _variantField_7 = classTypeAlias_superclass,
         _variantField_8 = classTypeAlias_withClause,
-        _variantField_16 = classTypeAlias_equals,
-        _variantField_18 = typeAlias_typedefKeyword,
-        _variantField_19 = typeAlias_semicolon,
         _variantField_9 = classTypeAlias_implementsClause,
         _variantField_34 = codeLength,
         _variantField_33 = codeOffset,
-        _variantField_14 = namedCompilationUnitMember_name,
+        _variantField_16 = nameOffset,
         _variantField_31 = simplyBoundable_isSimplyBounded;
 
   LinkedNodeBuilder.declaredIdentifier({
     LinkedNodeBuilder annotatedNode_comment,
     List<LinkedNodeBuilder> annotatedNode_metadata,
     LinkedNodeBuilder declaredIdentifier_identifier,
-    int declaredIdentifier_keyword,
     LinkedNodeBuilder declaredIdentifier_type,
   })  : _kind = idl.LinkedNodeKind.declaredIdentifier,
         _variantField_11 = annotatedNode_comment,
         _variantField_4 = annotatedNode_metadata,
         _variantField_6 = declaredIdentifier_identifier,
-        _variantField_15 = declaredIdentifier_keyword,
         _variantField_7 = declaredIdentifier_type;
 
   LinkedNodeBuilder.enumConstantDeclaration({
     LinkedNodeBuilder annotatedNode_comment,
     List<LinkedNodeBuilder> annotatedNode_metadata,
-    LinkedNodeBuilder enumConstantDeclaration_name,
+    int nameOffset,
   })  : _kind = idl.LinkedNodeKind.enumConstantDeclaration,
         _variantField_11 = annotatedNode_comment,
         _variantField_4 = annotatedNode_metadata,
-        _variantField_6 = enumConstantDeclaration_name;
+        _variantField_16 = nameOffset;
 
   LinkedNodeBuilder.fieldDeclaration({
     LinkedNodeBuilder annotatedNode_comment,
     List<LinkedNodeBuilder> annotatedNode_metadata,
     LinkedNodeBuilder fieldDeclaration_fields,
-    int fieldDeclaration_covariantKeyword,
-    int fieldDeclaration_staticKeyword,
-    int fieldDeclaration_semicolon,
   })  : _kind = idl.LinkedNodeKind.fieldDeclaration,
         _variantField_11 = annotatedNode_comment,
         _variantField_4 = annotatedNode_metadata,
-        _variantField_6 = fieldDeclaration_fields,
-        _variantField_15 = fieldDeclaration_covariantKeyword,
-        _variantField_17 = fieldDeclaration_staticKeyword,
-        _variantField_16 = fieldDeclaration_semicolon;
+        _variantField_6 = fieldDeclaration_fields;
 
   LinkedNodeBuilder.genericTypeAlias({
     LinkedNodeBuilder annotatedNode_comment,
     List<LinkedNodeBuilder> annotatedNode_metadata,
     LinkedNodeBuilder genericTypeAlias_typeParameters,
     LinkedNodeBuilder genericTypeAlias_functionType,
-    int genericTypeAlias_equals,
-    int typeAlias_typedefKeyword,
-    int typeAlias_semicolon,
     bool typeAlias_hasSelfReference,
     int codeLength,
     int codeOffset,
-    LinkedNodeBuilder namedCompilationUnitMember_name,
+    int nameOffset,
     bool simplyBoundable_isSimplyBounded,
   })  : _kind = idl.LinkedNodeKind.genericTypeAlias,
         _variantField_11 = annotatedNode_comment,
         _variantField_4 = annotatedNode_metadata,
         _variantField_6 = genericTypeAlias_typeParameters,
         _variantField_7 = genericTypeAlias_functionType,
-        _variantField_16 = genericTypeAlias_equals,
-        _variantField_18 = typeAlias_typedefKeyword,
-        _variantField_19 = typeAlias_semicolon,
         _variantField_27 = typeAlias_hasSelfReference,
         _variantField_34 = codeLength,
         _variantField_33 = codeOffset,
-        _variantField_14 = namedCompilationUnitMember_name,
+        _variantField_16 = nameOffset,
         _variantField_31 = simplyBoundable_isSimplyBounded;
 
   LinkedNodeBuilder.libraryDirective({
     LinkedNodeBuilder annotatedNode_comment,
     List<LinkedNodeBuilder> annotatedNode_metadata,
     LinkedNodeBuilder libraryDirective_name,
-    int directive_keyword,
-    int directive_semicolon,
   })  : _kind = idl.LinkedNodeKind.libraryDirective,
         _variantField_11 = annotatedNode_comment,
         _variantField_4 = annotatedNode_metadata,
-        _variantField_6 = libraryDirective_name,
-        _variantField_18 = directive_keyword,
-        _variantField_33 = directive_semicolon;
+        _variantField_6 = libraryDirective_name;
 
   LinkedNodeBuilder.mixinDeclaration({
     LinkedNodeBuilder annotatedNode_comment,
     List<LinkedNodeBuilder> annotatedNode_metadata,
     LinkedNodeBuilder mixinDeclaration_onClause,
-    int mixinDeclaration_mixinKeyword,
-    int classOrMixinDeclaration_rightBracket,
-    int classOrMixinDeclaration_leftBracket,
     LinkedNodeBuilder classOrMixinDeclaration_implementsClause,
     List<LinkedNodeBuilder> classOrMixinDeclaration_members,
     LinkedNodeBuilder classOrMixinDeclaration_typeParameters,
     int codeLength,
     int codeOffset,
-    LinkedNodeBuilder namedCompilationUnitMember_name,
     List<String> mixinDeclaration_superInvokedNames,
+    int nameOffset,
     bool simplyBoundable_isSimplyBounded,
   })  : _kind = idl.LinkedNodeKind.mixinDeclaration,
         _variantField_11 = annotatedNode_comment,
         _variantField_4 = annotatedNode_metadata,
         _variantField_6 = mixinDeclaration_onClause,
-        _variantField_15 = mixinDeclaration_mixinKeyword,
-        _variantField_18 = classOrMixinDeclaration_rightBracket,
-        _variantField_19 = classOrMixinDeclaration_leftBracket,
         _variantField_12 = classOrMixinDeclaration_implementsClause,
         _variantField_5 = classOrMixinDeclaration_members,
         _variantField_13 = classOrMixinDeclaration_typeParameters,
         _variantField_34 = codeLength,
         _variantField_33 = codeOffset,
-        _variantField_14 = namedCompilationUnitMember_name,
         _variantField_36 = mixinDeclaration_superInvokedNames,
+        _variantField_16 = nameOffset,
         _variantField_31 = simplyBoundable_isSimplyBounded;
 
   LinkedNodeBuilder.partDirective({
     LinkedNodeBuilder annotatedNode_comment,
     List<LinkedNodeBuilder> annotatedNode_metadata,
-    int directive_keyword,
-    int uriBasedDirective_uriElement,
-    int directive_semicolon,
+    int nameOffset,
     LinkedNodeBuilder uriBasedDirective_uri,
     String uriBasedDirective_uriContent,
+    int uriBasedDirective_uriElement,
   })  : _kind = idl.LinkedNodeKind.partDirective,
         _variantField_11 = annotatedNode_comment,
         _variantField_4 = annotatedNode_metadata,
-        _variantField_18 = directive_keyword,
-        _variantField_19 = uriBasedDirective_uriElement,
-        _variantField_33 = directive_semicolon,
+        _variantField_16 = nameOffset,
         _variantField_14 = uriBasedDirective_uri,
-        _variantField_22 = uriBasedDirective_uriContent;
+        _variantField_22 = uriBasedDirective_uriContent,
+        _variantField_19 = uriBasedDirective_uriElement;
 
   LinkedNodeBuilder.partOfDirective({
     LinkedNodeBuilder annotatedNode_comment,
     List<LinkedNodeBuilder> annotatedNode_metadata,
     LinkedNodeBuilder partOfDirective_libraryName,
     LinkedNodeBuilder partOfDirective_uri,
-    int partOfDirective_ofKeyword,
-    int directive_keyword,
-    int directive_semicolon,
   })  : _kind = idl.LinkedNodeKind.partOfDirective,
         _variantField_11 = annotatedNode_comment,
         _variantField_4 = annotatedNode_metadata,
         _variantField_6 = partOfDirective_libraryName,
-        _variantField_7 = partOfDirective_uri,
-        _variantField_16 = partOfDirective_ofKeyword,
-        _variantField_18 = directive_keyword,
-        _variantField_33 = directive_semicolon;
+        _variantField_7 = partOfDirective_uri;
 
   LinkedNodeBuilder.topLevelVariableDeclaration({
     LinkedNodeBuilder annotatedNode_comment,
     List<LinkedNodeBuilder> annotatedNode_metadata,
     LinkedNodeBuilder topLevelVariableDeclaration_variableList,
-    int topLevelVariableDeclaration_semicolon,
   })  : _kind = idl.LinkedNodeKind.topLevelVariableDeclaration,
         _variantField_11 = annotatedNode_comment,
         _variantField_4 = annotatedNode_metadata,
-        _variantField_6 = topLevelVariableDeclaration_variableList,
-        _variantField_15 = topLevelVariableDeclaration_semicolon;
+        _variantField_6 = topLevelVariableDeclaration_variableList;
 
   LinkedNodeBuilder.typeParameter({
     LinkedNodeBuilder annotatedNode_comment,
     List<LinkedNodeBuilder> annotatedNode_metadata,
     LinkedNodeBuilder typeParameter_bound,
-    int typeParameter_extendsKeyword,
-    LinkedNodeBuilder typeParameter_name,
     LinkedNodeTypeBuilder typeParameter_defaultType,
     int codeLength,
     int codeOffset,
+    int nameOffset,
   })  : _kind = idl.LinkedNodeKind.typeParameter,
         _variantField_11 = annotatedNode_comment,
         _variantField_4 = annotatedNode_metadata,
         _variantField_6 = typeParameter_bound,
-        _variantField_15 = typeParameter_extendsKeyword,
-        _variantField_7 = typeParameter_name,
         _variantField_23 = typeParameter_defaultType,
         _variantField_34 = codeLength,
-        _variantField_33 = codeOffset;
+        _variantField_33 = codeOffset,
+        _variantField_16 = nameOffset;
 
   LinkedNodeBuilder.switchCase({
     List<LinkedNodeBuilder> switchMember_statements,
     LinkedNodeBuilder switchCase_expression,
-    int switchMember_keyword,
-    int switchMember_colon,
     List<LinkedNodeBuilder> switchMember_labels,
   })  : _kind = idl.LinkedNodeKind.switchCase,
         _variantField_4 = switchMember_statements,
         _variantField_6 = switchCase_expression,
-        _variantField_15 = switchMember_keyword,
-        _variantField_16 = switchMember_colon,
         _variantField_3 = switchMember_labels;
 
   LinkedNodeBuilder.switchDefault({
     List<LinkedNodeBuilder> switchMember_statements,
-    int switchMember_keyword,
-    int switchMember_colon,
     List<LinkedNodeBuilder> switchMember_labels,
   })  : _kind = idl.LinkedNodeKind.switchDefault,
         _variantField_4 = switchMember_statements,
-        _variantField_15 = switchMember_keyword,
-        _variantField_16 = switchMember_colon,
         _variantField_3 = switchMember_labels;
 
   LinkedNodeBuilder.annotation({
     LinkedNodeBuilder annotation_arguments,
-    int annotation_atSign,
     LinkedNodeBuilder annotation_constructorName,
     int annotation_element,
     LinkedNodeTypeBuilder annotation_elementType,
     LinkedNodeBuilder annotation_name,
-    int annotation_period,
   })  : _kind = idl.LinkedNodeKind.annotation,
         _variantField_6 = annotation_arguments,
-        _variantField_15 = annotation_atSign,
         _variantField_7 = annotation_constructorName,
         _variantField_17 = annotation_element,
         _variantField_23 = annotation_elementType,
-        _variantField_8 = annotation_name,
-        _variantField_16 = annotation_period;
+        _variantField_8 = annotation_name;
 
   LinkedNodeBuilder.asExpression({
     LinkedNodeBuilder asExpression_expression,
-    int asExpression_asOperator,
     LinkedNodeBuilder asExpression_type,
     LinkedNodeTypeBuilder expression_type,
   })  : _kind = idl.LinkedNodeKind.asExpression,
         _variantField_6 = asExpression_expression,
-        _variantField_15 = asExpression_asOperator,
         _variantField_7 = asExpression_type,
         _variantField_25 = expression_type;
 
   LinkedNodeBuilder.assertInitializer({
     LinkedNodeBuilder assertInitializer_condition,
-    int assertInitializer_assertKeyword,
     LinkedNodeBuilder assertInitializer_message,
-    int assertInitializer_leftParenthesis,
-    int assertInitializer_comma,
-    int assertInitializer_rightParenthesis,
   })  : _kind = idl.LinkedNodeKind.assertInitializer,
         _variantField_6 = assertInitializer_condition,
-        _variantField_15 = assertInitializer_assertKeyword,
-        _variantField_7 = assertInitializer_message,
-        _variantField_17 = assertInitializer_leftParenthesis,
-        _variantField_16 = assertInitializer_comma,
-        _variantField_18 = assertInitializer_rightParenthesis;
+        _variantField_7 = assertInitializer_message;
 
   LinkedNodeBuilder.assertStatement({
     LinkedNodeBuilder assertStatement_condition,
-    int assertStatement_assertKeyword,
     LinkedNodeBuilder assertStatement_message,
-    int assertStatement_leftParenthesis,
-    int assertStatement_comma,
-    int assertStatement_rightParenthesis,
-    int assertStatement_semicolon,
   })  : _kind = idl.LinkedNodeKind.assertStatement,
         _variantField_6 = assertStatement_condition,
-        _variantField_15 = assertStatement_assertKeyword,
-        _variantField_7 = assertStatement_message,
-        _variantField_17 = assertStatement_leftParenthesis,
-        _variantField_16 = assertStatement_comma,
-        _variantField_18 = assertStatement_rightParenthesis,
-        _variantField_19 = assertStatement_semicolon;
+        _variantField_7 = assertStatement_message;
 
   LinkedNodeBuilder.assignmentExpression({
     LinkedNodeBuilder assignmentExpression_leftHandSide,
-    int assignmentExpression_element,
     LinkedNodeBuilder assignmentExpression_rightHandSide,
     LinkedNodeTypeBuilder assignmentExpression_elementType,
-    int assignmentExpression_operator,
+    int assignmentExpression_element,
+    idl.UnlinkedTokenType assignmentExpression_operator,
     LinkedNodeTypeBuilder expression_type,
   })  : _kind = idl.LinkedNodeKind.assignmentExpression,
         _variantField_6 = assignmentExpression_leftHandSide,
-        _variantField_15 = assignmentExpression_element,
         _variantField_7 = assignmentExpression_rightHandSide,
         _variantField_23 = assignmentExpression_elementType,
-        _variantField_16 = assignmentExpression_operator,
+        _variantField_15 = assignmentExpression_element,
+        _variantField_28 = assignmentExpression_operator,
         _variantField_25 = expression_type;
 
   LinkedNodeBuilder.awaitExpression({
     LinkedNodeBuilder awaitExpression_expression,
-    int awaitExpression_awaitKeyword,
     LinkedNodeTypeBuilder expression_type,
   })  : _kind = idl.LinkedNodeKind.awaitExpression,
         _variantField_6 = awaitExpression_expression,
-        _variantField_15 = awaitExpression_awaitKeyword,
         _variantField_25 = expression_type;
 
   LinkedNodeBuilder.blockFunctionBody({
     LinkedNodeBuilder blockFunctionBody_block,
-    int blockFunctionBody_keyword,
-    int blockFunctionBody_star,
   })  : _kind = idl.LinkedNodeKind.blockFunctionBody,
-        _variantField_6 = blockFunctionBody_block,
-        _variantField_15 = blockFunctionBody_keyword,
-        _variantField_16 = blockFunctionBody_star;
+        _variantField_6 = blockFunctionBody_block;
 
   LinkedNodeBuilder.breakStatement({
     LinkedNodeBuilder breakStatement_label,
-    int breakStatement_breakKeyword,
-    int breakStatement_semicolon,
   })  : _kind = idl.LinkedNodeKind.breakStatement,
-        _variantField_6 = breakStatement_label,
-        _variantField_15 = breakStatement_breakKeyword,
-        _variantField_16 = breakStatement_semicolon;
+        _variantField_6 = breakStatement_label;
 
   LinkedNodeBuilder.catchClause({
     LinkedNodeBuilder catchClause_body,
-    int catchClause_catchKeyword,
     LinkedNodeBuilder catchClause_exceptionParameter,
-    int catchClause_leftParenthesis,
     LinkedNodeBuilder catchClause_exceptionType,
-    int catchClause_comma,
-    int catchClause_onKeyword,
-    int catchClause_rightParenthesis,
     LinkedNodeBuilder catchClause_stackTraceParameter,
   })  : _kind = idl.LinkedNodeKind.catchClause,
         _variantField_6 = catchClause_body,
-        _variantField_15 = catchClause_catchKeyword,
         _variantField_7 = catchClause_exceptionParameter,
-        _variantField_17 = catchClause_leftParenthesis,
         _variantField_8 = catchClause_exceptionType,
-        _variantField_16 = catchClause_comma,
-        _variantField_18 = catchClause_onKeyword,
-        _variantField_19 = catchClause_rightParenthesis,
         _variantField_9 = catchClause_stackTraceParameter;
 
   LinkedNodeBuilder.commentReference({
     LinkedNodeBuilder commentReference_identifier,
-    int commentReference_newKeyword,
   })  : _kind = idl.LinkedNodeKind.commentReference,
-        _variantField_6 = commentReference_identifier,
-        _variantField_15 = commentReference_newKeyword;
+        _variantField_6 = commentReference_identifier;
 
   LinkedNodeBuilder.conditionalExpression({
     LinkedNodeBuilder conditionalExpression_condition,
-    int conditionalExpression_colon,
     LinkedNodeBuilder conditionalExpression_elseExpression,
     LinkedNodeBuilder conditionalExpression_thenExpression,
-    int conditionalExpression_question,
     LinkedNodeTypeBuilder expression_type,
   })  : _kind = idl.LinkedNodeKind.conditionalExpression,
         _variantField_6 = conditionalExpression_condition,
-        _variantField_15 = conditionalExpression_colon,
         _variantField_7 = conditionalExpression_elseExpression,
         _variantField_8 = conditionalExpression_thenExpression,
-        _variantField_16 = conditionalExpression_question,
         _variantField_25 = expression_type;
 
   LinkedNodeBuilder.configuration({
     LinkedNodeBuilder configuration_name,
-    int configuration_ifKeyword,
     LinkedNodeBuilder configuration_value,
-    int configuration_rightParenthesis,
     LinkedNodeBuilder configuration_uri,
-    int configuration_leftParenthesis,
-    int configuration_equalToken,
   })  : _kind = idl.LinkedNodeKind.configuration,
         _variantField_6 = configuration_name,
-        _variantField_15 = configuration_ifKeyword,
         _variantField_7 = configuration_value,
-        _variantField_17 = configuration_rightParenthesis,
-        _variantField_8 = configuration_uri,
-        _variantField_16 = configuration_leftParenthesis,
-        _variantField_18 = configuration_equalToken;
+        _variantField_8 = configuration_uri;
 
   LinkedNodeBuilder.constructorFieldInitializer({
     LinkedNodeBuilder constructorFieldInitializer_expression,
-    int constructorFieldInitializer_equals,
     LinkedNodeBuilder constructorFieldInitializer_fieldName,
-    int constructorFieldInitializer_thisKeyword,
-    int constructorFieldInitializer_period,
   })  : _kind = idl.LinkedNodeKind.constructorFieldInitializer,
         _variantField_6 = constructorFieldInitializer_expression,
-        _variantField_15 = constructorFieldInitializer_equals,
-        _variantField_7 = constructorFieldInitializer_fieldName,
-        _variantField_17 = constructorFieldInitializer_thisKeyword,
-        _variantField_16 = constructorFieldInitializer_period;
+        _variantField_7 = constructorFieldInitializer_fieldName;
 
   LinkedNodeBuilder.constructorName({
     LinkedNodeBuilder constructorName_name,
-    int constructorName_element,
     LinkedNodeBuilder constructorName_type,
     LinkedNodeTypeBuilder constructorName_elementType,
-    int constructorName_period,
+    int constructorName_element,
   })  : _kind = idl.LinkedNodeKind.constructorName,
         _variantField_6 = constructorName_name,
-        _variantField_15 = constructorName_element,
         _variantField_7 = constructorName_type,
         _variantField_23 = constructorName_elementType,
-        _variantField_16 = constructorName_period;
+        _variantField_15 = constructorName_element;
 
   LinkedNodeBuilder.continueStatement({
     LinkedNodeBuilder continueStatement_label,
-    int continueStatement_continueKeyword,
-    int continueStatement_semicolon,
   })  : _kind = idl.LinkedNodeKind.continueStatement,
-        _variantField_6 = continueStatement_label,
-        _variantField_15 = continueStatement_continueKeyword,
-        _variantField_16 = continueStatement_semicolon;
+        _variantField_6 = continueStatement_label;
 
   LinkedNodeBuilder.defaultFormalParameter({
     LinkedNodeBuilder defaultFormalParameter_defaultValue,
-    int defaultFormalParameter_separator,
     LinkedNodeBuilder defaultFormalParameter_parameter,
     int codeLength,
     int codeOffset,
     idl.LinkedNodeFormalParameterKind defaultFormalParameter_kind,
   })  : _kind = idl.LinkedNodeKind.defaultFormalParameter,
         _variantField_6 = defaultFormalParameter_defaultValue,
-        _variantField_15 = defaultFormalParameter_separator,
         _variantField_7 = defaultFormalParameter_parameter,
         _variantField_34 = codeLength,
         _variantField_33 = codeOffset,
@@ -11237,118 +8657,70 @@
 
   LinkedNodeBuilder.doStatement({
     LinkedNodeBuilder doStatement_body,
-    int doStatement_leftParenthesis,
     LinkedNodeBuilder doStatement_condition,
-    int doStatement_doKeyword,
-    int doStatement_rightParenthesis,
-    int doStatement_semicolon,
-    int doStatement_whileKeyword,
   })  : _kind = idl.LinkedNodeKind.doStatement,
         _variantField_6 = doStatement_body,
-        _variantField_15 = doStatement_leftParenthesis,
-        _variantField_7 = doStatement_condition,
-        _variantField_17 = doStatement_doKeyword,
-        _variantField_16 = doStatement_rightParenthesis,
-        _variantField_18 = doStatement_semicolon,
-        _variantField_19 = doStatement_whileKeyword;
+        _variantField_7 = doStatement_condition;
 
   LinkedNodeBuilder.expressionFunctionBody({
     LinkedNodeBuilder expressionFunctionBody_expression,
-    int expressionFunctionBody_arrow,
-    int expressionFunctionBody_semicolon,
-    int expressionFunctionBody_keyword,
   })  : _kind = idl.LinkedNodeKind.expressionFunctionBody,
-        _variantField_6 = expressionFunctionBody_expression,
-        _variantField_15 = expressionFunctionBody_arrow,
-        _variantField_17 = expressionFunctionBody_semicolon,
-        _variantField_16 = expressionFunctionBody_keyword;
+        _variantField_6 = expressionFunctionBody_expression;
 
   LinkedNodeBuilder.expressionStatement({
     LinkedNodeBuilder expressionStatement_expression,
-    int expressionStatement_semicolon,
   })  : _kind = idl.LinkedNodeKind.expressionStatement,
-        _variantField_6 = expressionStatement_expression,
-        _variantField_15 = expressionStatement_semicolon;
+        _variantField_6 = expressionStatement_expression;
 
   LinkedNodeBuilder.extendsClause({
     LinkedNodeBuilder extendsClause_superclass,
-    int extendsClause_extendsKeyword,
   })  : _kind = idl.LinkedNodeKind.extendsClause,
-        _variantField_6 = extendsClause_superclass,
-        _variantField_15 = extendsClause_extendsKeyword;
+        _variantField_6 = extendsClause_superclass;
 
   LinkedNodeBuilder.forEachPartsWithDeclaration({
     LinkedNodeBuilder forEachParts_iterable,
-    int forEachParts_inKeyword,
     LinkedNodeBuilder forEachPartsWithDeclaration_loopVariable,
   })  : _kind = idl.LinkedNodeKind.forEachPartsWithDeclaration,
         _variantField_6 = forEachParts_iterable,
-        _variantField_15 = forEachParts_inKeyword,
         _variantField_7 = forEachPartsWithDeclaration_loopVariable;
 
   LinkedNodeBuilder.forEachPartsWithIdentifier({
     LinkedNodeBuilder forEachParts_iterable,
-    int forEachParts_inKeyword,
     LinkedNodeBuilder forEachPartsWithIdentifier_identifier,
   })  : _kind = idl.LinkedNodeKind.forEachPartsWithIdentifier,
         _variantField_6 = forEachParts_iterable,
-        _variantField_15 = forEachParts_inKeyword,
         _variantField_7 = forEachPartsWithIdentifier_identifier;
 
   LinkedNodeBuilder.forElement({
     LinkedNodeBuilder forMixin_forLoopParts,
-    int forMixin_awaitKeyword,
     LinkedNodeBuilder forElement_body,
-    int forMixin_leftParenthesis,
-    int forMixin_forKeyword,
-    int forMixin_rightParenthesis,
   })  : _kind = idl.LinkedNodeKind.forElement,
         _variantField_6 = forMixin_forLoopParts,
-        _variantField_15 = forMixin_awaitKeyword,
-        _variantField_7 = forElement_body,
-        _variantField_17 = forMixin_leftParenthesis,
-        _variantField_16 = forMixin_forKeyword,
-        _variantField_19 = forMixin_rightParenthesis;
+        _variantField_7 = forElement_body;
 
   LinkedNodeBuilder.forStatement({
     LinkedNodeBuilder forMixin_forLoopParts,
-    int forMixin_awaitKeyword,
     LinkedNodeBuilder forStatement_body,
-    int forMixin_leftParenthesis,
-    int forMixin_forKeyword,
-    int forMixin_rightParenthesis,
   })  : _kind = idl.LinkedNodeKind.forStatement,
         _variantField_6 = forMixin_forLoopParts,
-        _variantField_15 = forMixin_awaitKeyword,
-        _variantField_7 = forStatement_body,
-        _variantField_17 = forMixin_leftParenthesis,
-        _variantField_16 = forMixin_forKeyword,
-        _variantField_19 = forMixin_rightParenthesis;
+        _variantField_7 = forStatement_body;
 
   LinkedNodeBuilder.forPartsWithDeclarations({
     LinkedNodeBuilder forParts_condition,
-    int forParts_leftSeparator,
     LinkedNodeBuilder forPartsWithDeclarations_variables,
-    int forParts_rightSeparator,
     List<LinkedNodeBuilder> forParts_updaters,
   })  : _kind = idl.LinkedNodeKind.forPartsWithDeclarations,
         _variantField_6 = forParts_condition,
-        _variantField_15 = forParts_leftSeparator,
         _variantField_7 = forPartsWithDeclarations_variables,
-        _variantField_16 = forParts_rightSeparator,
         _variantField_5 = forParts_updaters;
 
   LinkedNodeBuilder.forPartsWithExpression({
     LinkedNodeBuilder forParts_condition,
-    int forParts_leftSeparator,
     LinkedNodeBuilder forPartsWithExpression_initialization,
-    int forParts_rightSeparator,
     List<LinkedNodeBuilder> forParts_updaters,
   })  : _kind = idl.LinkedNodeKind.forPartsWithExpression,
         _variantField_6 = forParts_condition,
-        _variantField_15 = forParts_leftSeparator,
         _variantField_7 = forPartsWithExpression_initialization,
-        _variantField_16 = forParts_rightSeparator,
         _variantField_5 = forParts_updaters;
 
   LinkedNodeBuilder.functionDeclarationStatement({
@@ -11358,397 +8730,270 @@
 
   LinkedNodeBuilder.ifElement({
     LinkedNodeBuilder ifMixin_condition,
-    int ifMixin_elseKeyword,
-    int ifMixin_leftParenthesis,
     LinkedNodeBuilder ifElement_thenElement,
-    int ifMixin_ifKeyword,
-    int ifMixin_rightParenthesis,
     LinkedNodeBuilder ifElement_elseElement,
   })  : _kind = idl.LinkedNodeKind.ifElement,
         _variantField_6 = ifMixin_condition,
-        _variantField_15 = ifMixin_elseKeyword,
-        _variantField_17 = ifMixin_leftParenthesis,
         _variantField_8 = ifElement_thenElement,
-        _variantField_16 = ifMixin_ifKeyword,
-        _variantField_18 = ifMixin_rightParenthesis,
         _variantField_9 = ifElement_elseElement;
 
   LinkedNodeBuilder.ifStatement({
     LinkedNodeBuilder ifMixin_condition,
-    int ifMixin_elseKeyword,
     LinkedNodeBuilder ifStatement_elseStatement,
-    int ifMixin_leftParenthesis,
     LinkedNodeBuilder ifStatement_thenStatement,
-    int ifMixin_ifKeyword,
-    int ifMixin_rightParenthesis,
   })  : _kind = idl.LinkedNodeKind.ifStatement,
         _variantField_6 = ifMixin_condition,
-        _variantField_15 = ifMixin_elseKeyword,
         _variantField_7 = ifStatement_elseStatement,
-        _variantField_17 = ifMixin_leftParenthesis,
-        _variantField_8 = ifStatement_thenStatement,
-        _variantField_16 = ifMixin_ifKeyword,
-        _variantField_18 = ifMixin_rightParenthesis;
+        _variantField_8 = ifStatement_thenStatement;
 
   LinkedNodeBuilder.indexExpression({
     LinkedNodeBuilder indexExpression_index,
-    int indexExpression_element,
     LinkedNodeBuilder indexExpression_target,
-    int indexExpression_leftBracket,
     LinkedNodeTypeBuilder indexExpression_elementType,
-    int indexExpression_period,
-    int indexExpression_rightBracket,
+    int indexExpression_element,
     LinkedNodeTypeBuilder expression_type,
   })  : _kind = idl.LinkedNodeKind.indexExpression,
         _variantField_6 = indexExpression_index,
-        _variantField_15 = indexExpression_element,
         _variantField_7 = indexExpression_target,
-        _variantField_17 = indexExpression_leftBracket,
         _variantField_23 = indexExpression_elementType,
-        _variantField_16 = indexExpression_period,
-        _variantField_18 = indexExpression_rightBracket,
-        _variantField_25 = expression_type;
-
-  LinkedNodeBuilder.instanceCreationExpression({
-    LinkedNodeBuilder instanceCreationExpression_arguments,
-    int instanceCreationExpression_keyword,
-    LinkedNodeBuilder instanceCreationExpression_constructorName,
-    LinkedNodeBuilder instanceCreationExpression_typeArguments,
-    LinkedNodeTypeBuilder expression_type,
-  })  : _kind = idl.LinkedNodeKind.instanceCreationExpression,
-        _variantField_6 = instanceCreationExpression_arguments,
-        _variantField_15 = instanceCreationExpression_keyword,
-        _variantField_7 = instanceCreationExpression_constructorName,
-        _variantField_8 = instanceCreationExpression_typeArguments,
+        _variantField_15 = indexExpression_element,
         _variantField_25 = expression_type;
 
   LinkedNodeBuilder.interpolationExpression({
     LinkedNodeBuilder interpolationExpression_expression,
-    int interpolationExpression_leftBracket,
-    int interpolationExpression_rightBracket,
   })  : _kind = idl.LinkedNodeKind.interpolationExpression,
-        _variantField_6 = interpolationExpression_expression,
-        _variantField_15 = interpolationExpression_leftBracket,
-        _variantField_16 = interpolationExpression_rightBracket;
+        _variantField_6 = interpolationExpression_expression;
 
   LinkedNodeBuilder.isExpression({
     LinkedNodeBuilder isExpression_expression,
-    int isExpression_isOperator,
     LinkedNodeBuilder isExpression_type,
-    int isExpression_notOperator,
-    LinkedNodeTypeBuilder expression_type,
   })  : _kind = idl.LinkedNodeKind.isExpression,
         _variantField_6 = isExpression_expression,
-        _variantField_15 = isExpression_isOperator,
-        _variantField_7 = isExpression_type,
-        _variantField_16 = isExpression_notOperator,
-        _variantField_25 = expression_type;
+        _variantField_7 = isExpression_type;
 
   LinkedNodeBuilder.label({
     LinkedNodeBuilder label_label,
-    int label_colon,
   })  : _kind = idl.LinkedNodeKind.label,
-        _variantField_6 = label_label,
-        _variantField_15 = label_colon;
+        _variantField_6 = label_label;
 
   LinkedNodeBuilder.mapLiteralEntry({
     LinkedNodeBuilder mapLiteralEntry_key,
-    int mapLiteralEntry_separator,
     LinkedNodeBuilder mapLiteralEntry_value,
   })  : _kind = idl.LinkedNodeKind.mapLiteralEntry,
         _variantField_6 = mapLiteralEntry_key,
-        _variantField_15 = mapLiteralEntry_separator,
         _variantField_7 = mapLiteralEntry_value;
 
   LinkedNodeBuilder.namedExpression({
     LinkedNodeBuilder namedExpression_expression,
     LinkedNodeBuilder namedExpression_name,
-    LinkedNodeTypeBuilder expression_type,
   })  : _kind = idl.LinkedNodeKind.namedExpression,
         _variantField_6 = namedExpression_expression,
-        _variantField_7 = namedExpression_name,
-        _variantField_25 = expression_type;
+        _variantField_7 = namedExpression_name;
 
   LinkedNodeBuilder.nativeClause({
     LinkedNodeBuilder nativeClause_name,
-    int nativeClause_nativeKeyword,
   })  : _kind = idl.LinkedNodeKind.nativeClause,
-        _variantField_6 = nativeClause_name,
-        _variantField_15 = nativeClause_nativeKeyword;
+        _variantField_6 = nativeClause_name;
 
   LinkedNodeBuilder.nativeFunctionBody({
     LinkedNodeBuilder nativeFunctionBody_stringLiteral,
-    int nativeFunctionBody_nativeKeyword,
-    int nativeFunctionBody_semicolon,
   })  : _kind = idl.LinkedNodeKind.nativeFunctionBody,
-        _variantField_6 = nativeFunctionBody_stringLiteral,
-        _variantField_15 = nativeFunctionBody_nativeKeyword,
-        _variantField_16 = nativeFunctionBody_semicolon;
+        _variantField_6 = nativeFunctionBody_stringLiteral;
 
   LinkedNodeBuilder.parenthesizedExpression({
     LinkedNodeBuilder parenthesizedExpression_expression,
-    int parenthesizedExpression_leftParenthesis,
-    int parenthesizedExpression_rightParenthesis,
     LinkedNodeTypeBuilder expression_type,
   })  : _kind = idl.LinkedNodeKind.parenthesizedExpression,
         _variantField_6 = parenthesizedExpression_expression,
-        _variantField_15 = parenthesizedExpression_leftParenthesis,
-        _variantField_16 = parenthesizedExpression_rightParenthesis,
         _variantField_25 = expression_type;
 
   LinkedNodeBuilder.postfixExpression({
     LinkedNodeBuilder postfixExpression_operand,
-    int postfixExpression_element,
     LinkedNodeTypeBuilder postfixExpression_elementType,
-    int postfixExpression_operator,
+    int postfixExpression_element,
+    idl.UnlinkedTokenType postfixExpression_operator,
     LinkedNodeTypeBuilder expression_type,
   })  : _kind = idl.LinkedNodeKind.postfixExpression,
         _variantField_6 = postfixExpression_operand,
-        _variantField_15 = postfixExpression_element,
         _variantField_23 = postfixExpression_elementType,
-        _variantField_16 = postfixExpression_operator,
+        _variantField_15 = postfixExpression_element,
+        _variantField_28 = postfixExpression_operator,
         _variantField_25 = expression_type;
 
   LinkedNodeBuilder.prefixedIdentifier({
     LinkedNodeBuilder prefixedIdentifier_identifier,
-    int prefixedIdentifier_period,
     LinkedNodeBuilder prefixedIdentifier_prefix,
     LinkedNodeTypeBuilder expression_type,
   })  : _kind = idl.LinkedNodeKind.prefixedIdentifier,
         _variantField_6 = prefixedIdentifier_identifier,
-        _variantField_15 = prefixedIdentifier_period,
         _variantField_7 = prefixedIdentifier_prefix,
         _variantField_25 = expression_type;
 
   LinkedNodeBuilder.prefixExpression({
     LinkedNodeBuilder prefixExpression_operand,
-    int prefixExpression_element,
     LinkedNodeTypeBuilder prefixExpression_elementType,
-    int prefixExpression_operator,
+    int prefixExpression_element,
+    idl.UnlinkedTokenType prefixExpression_operator,
     LinkedNodeTypeBuilder expression_type,
   })  : _kind = idl.LinkedNodeKind.prefixExpression,
         _variantField_6 = prefixExpression_operand,
-        _variantField_15 = prefixExpression_element,
         _variantField_23 = prefixExpression_elementType,
-        _variantField_16 = prefixExpression_operator,
+        _variantField_15 = prefixExpression_element,
+        _variantField_28 = prefixExpression_operator,
         _variantField_25 = expression_type;
 
   LinkedNodeBuilder.propertyAccess({
     LinkedNodeBuilder propertyAccess_propertyName,
-    int propertyAccess_operator,
     LinkedNodeBuilder propertyAccess_target,
+    idl.UnlinkedTokenType propertyAccess_operator,
     LinkedNodeTypeBuilder expression_type,
   })  : _kind = idl.LinkedNodeKind.propertyAccess,
         _variantField_6 = propertyAccess_propertyName,
-        _variantField_15 = propertyAccess_operator,
         _variantField_7 = propertyAccess_target,
+        _variantField_28 = propertyAccess_operator,
         _variantField_25 = expression_type;
 
   LinkedNodeBuilder.redirectingConstructorInvocation({
     LinkedNodeBuilder redirectingConstructorInvocation_arguments,
-    int redirectingConstructorInvocation_element,
     LinkedNodeBuilder redirectingConstructorInvocation_constructorName,
-    int redirectingConstructorInvocation_thisKeyword,
     LinkedNodeTypeBuilder redirectingConstructorInvocation_elementType,
-    int redirectingConstructorInvocation_period,
+    int redirectingConstructorInvocation_element,
   })  : _kind = idl.LinkedNodeKind.redirectingConstructorInvocation,
         _variantField_6 = redirectingConstructorInvocation_arguments,
-        _variantField_15 = redirectingConstructorInvocation_element,
         _variantField_7 = redirectingConstructorInvocation_constructorName,
-        _variantField_17 = redirectingConstructorInvocation_thisKeyword,
         _variantField_23 = redirectingConstructorInvocation_elementType,
-        _variantField_16 = redirectingConstructorInvocation_period;
+        _variantField_15 = redirectingConstructorInvocation_element;
 
   LinkedNodeBuilder.returnStatement({
     LinkedNodeBuilder returnStatement_expression,
-    int returnStatement_returnKeyword,
-    int returnStatement_semicolon,
   })  : _kind = idl.LinkedNodeKind.returnStatement,
-        _variantField_6 = returnStatement_expression,
-        _variantField_15 = returnStatement_returnKeyword,
-        _variantField_16 = returnStatement_semicolon;
+        _variantField_6 = returnStatement_expression;
 
   LinkedNodeBuilder.spreadElement({
     LinkedNodeBuilder spreadElement_expression,
-    int spreadElement_spreadOperator,
+    idl.UnlinkedTokenType spreadElement_spreadOperator,
   })  : _kind = idl.LinkedNodeKind.spreadElement,
         _variantField_6 = spreadElement_expression,
-        _variantField_15 = spreadElement_spreadOperator;
+        _variantField_38 = spreadElement_spreadOperator;
 
   LinkedNodeBuilder.superConstructorInvocation({
     LinkedNodeBuilder superConstructorInvocation_arguments,
-    int superConstructorInvocation_element,
     LinkedNodeBuilder superConstructorInvocation_constructorName,
-    int superConstructorInvocation_superKeyword,
     LinkedNodeTypeBuilder superConstructorInvocation_elementType,
-    int superConstructorInvocation_period,
+    int superConstructorInvocation_element,
   })  : _kind = idl.LinkedNodeKind.superConstructorInvocation,
         _variantField_6 = superConstructorInvocation_arguments,
-        _variantField_15 = superConstructorInvocation_element,
         _variantField_7 = superConstructorInvocation_constructorName,
-        _variantField_17 = superConstructorInvocation_superKeyword,
         _variantField_23 = superConstructorInvocation_elementType,
-        _variantField_16 = superConstructorInvocation_period;
+        _variantField_15 = superConstructorInvocation_element;
 
   LinkedNodeBuilder.throwExpression({
     LinkedNodeBuilder throwExpression_expression,
-    int throwExpression_throwKeyword,
     LinkedNodeTypeBuilder expression_type,
   })  : _kind = idl.LinkedNodeKind.throwExpression,
         _variantField_6 = throwExpression_expression,
-        _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_23 = typeName_type;
-
   LinkedNodeBuilder.variableDeclarationStatement({
     LinkedNodeBuilder variableDeclarationStatement_variables,
-    int variableDeclarationStatement_semicolon,
   })  : _kind = idl.LinkedNodeKind.variableDeclarationStatement,
-        _variantField_6 = variableDeclarationStatement_variables,
-        _variantField_15 = variableDeclarationStatement_semicolon;
+        _variantField_6 = variableDeclarationStatement_variables;
 
   LinkedNodeBuilder.whileStatement({
     LinkedNodeBuilder whileStatement_body,
-    int whileStatement_leftParenthesis,
     LinkedNodeBuilder whileStatement_condition,
-    int whileStatement_whileKeyword,
-    int whileStatement_rightParenthesis,
   })  : _kind = idl.LinkedNodeKind.whileStatement,
         _variantField_6 = whileStatement_body,
-        _variantField_15 = whileStatement_leftParenthesis,
-        _variantField_7 = whileStatement_condition,
-        _variantField_17 = whileStatement_whileKeyword,
-        _variantField_16 = whileStatement_rightParenthesis;
+        _variantField_7 = whileStatement_condition;
 
   LinkedNodeBuilder.yieldStatement({
     LinkedNodeBuilder yieldStatement_expression,
-    int yieldStatement_yieldKeyword,
-    int yieldStatement_semicolon,
-    int yieldStatement_star,
   })  : _kind = idl.LinkedNodeKind.yieldStatement,
-        _variantField_6 = yieldStatement_expression,
-        _variantField_15 = yieldStatement_yieldKeyword,
-        _variantField_17 = yieldStatement_semicolon,
-        _variantField_16 = yieldStatement_star;
+        _variantField_6 = yieldStatement_expression;
 
-  LinkedNodeBuilder.booleanLiteral({
-    int booleanLiteral_literal,
-    bool booleanLiteral_value,
+  LinkedNodeBuilder.simpleIdentifier({
+    LinkedNodeTypeBuilder simpleIdentifier_elementType,
+    int simpleIdentifier_element,
     LinkedNodeTypeBuilder expression_type,
-  })  : _kind = idl.LinkedNodeKind.booleanLiteral,
-        _variantField_15 = booleanLiteral_literal,
-        _variantField_27 = booleanLiteral_value,
-        _variantField_25 = expression_type;
-
-  LinkedNodeBuilder.doubleLiteral({
-    int doubleLiteral_literal,
-    double doubleLiteral_value,
-    LinkedNodeTypeBuilder expression_type,
-  })  : _kind = idl.LinkedNodeKind.doubleLiteral,
-        _variantField_15 = doubleLiteral_literal,
-        _variantField_21 = doubleLiteral_value,
+  })  : _kind = idl.LinkedNodeKind.simpleIdentifier,
+        _variantField_23 = simpleIdentifier_elementType,
+        _variantField_15 = simpleIdentifier_element,
         _variantField_25 = expression_type;
 
   LinkedNodeBuilder.emptyFunctionBody({
-    int emptyFunctionBody_semicolon,
+    int emptyFunctionBody_fake,
   })  : _kind = idl.LinkedNodeKind.emptyFunctionBody,
-        _variantField_15 = emptyFunctionBody_semicolon;
+        _variantField_15 = emptyFunctionBody_fake;
 
   LinkedNodeBuilder.emptyStatement({
-    int emptyStatement_semicolon,
+    int emptyStatement_fake,
   })  : _kind = idl.LinkedNodeKind.emptyStatement,
-        _variantField_15 = emptyStatement_semicolon;
-
-  LinkedNodeBuilder.integerLiteral({
-    int integerLiteral_literal,
-    int integerLiteral_value,
-    LinkedNodeTypeBuilder expression_type,
-  })  : _kind = idl.LinkedNodeKind.integerLiteral,
-        _variantField_15 = integerLiteral_literal,
-        _variantField_16 = integerLiteral_value,
-        _variantField_25 = expression_type;
-
-  LinkedNodeBuilder.interpolationString({
-    int interpolationString_token,
-    String interpolationString_value,
-  })  : _kind = idl.LinkedNodeKind.interpolationString,
-        _variantField_15 = interpolationString_token,
-        _variantField_30 = interpolationString_value;
+        _variantField_15 = emptyStatement_fake;
 
   LinkedNodeBuilder.nullLiteral({
-    int nullLiteral_literal,
+    int nullLiteral_fake,
     LinkedNodeTypeBuilder expression_type,
   })  : _kind = idl.LinkedNodeKind.nullLiteral,
-        _variantField_15 = nullLiteral_literal,
+        _variantField_15 = nullLiteral_fake,
         _variantField_25 = expression_type;
 
-  LinkedNodeBuilder.rethrowExpression({
-    int rethrowExpression_rethrowKeyword,
-    LinkedNodeTypeBuilder expression_type,
-  })  : _kind = idl.LinkedNodeKind.rethrowExpression,
-        _variantField_15 = rethrowExpression_rethrowKeyword,
-        _variantField_25 = expression_type;
+  LinkedNodeBuilder.booleanLiteral({
+    bool booleanLiteral_value,
+  })  : _kind = idl.LinkedNodeKind.booleanLiteral,
+        _variantField_27 = booleanLiteral_value;
 
-  LinkedNodeBuilder.scriptTag({
-    int scriptTag_scriptTag,
-  })  : _kind = idl.LinkedNodeKind.scriptTag,
-        _variantField_15 = scriptTag_scriptTag;
+  LinkedNodeBuilder.hideCombinator({
+    List<String> names,
+  })  : _kind = idl.LinkedNodeKind.hideCombinator,
+        _variantField_36 = names;
 
-  LinkedNodeBuilder.simpleIdentifier({
-    int simpleIdentifier_element,
-    LinkedNodeTypeBuilder simpleIdentifier_elementType,
-    int simpleIdentifier_token,
-    bool simpleIdentifier_isDeclaration,
-    LinkedNodeTypeBuilder expression_type,
-  })  : _kind = idl.LinkedNodeKind.simpleIdentifier,
-        _variantField_15 = simpleIdentifier_element,
-        _variantField_23 = simpleIdentifier_elementType,
-        _variantField_16 = simpleIdentifier_token,
-        _variantField_27 = simpleIdentifier_isDeclaration,
-        _variantField_25 = expression_type;
-
-  LinkedNodeBuilder.simpleStringLiteral({
-    int simpleStringLiteral_token,
-    LinkedNodeTypeBuilder expression_type,
-    String simpleStringLiteral_value,
-  })  : _kind = idl.LinkedNodeKind.simpleStringLiteral,
-        _variantField_15 = simpleStringLiteral_token,
-        _variantField_25 = expression_type,
-        _variantField_20 = simpleStringLiteral_value;
-
-  LinkedNodeBuilder.superExpression({
-    int superExpression_superKeyword,
-    LinkedNodeTypeBuilder expression_type,
-  })  : _kind = idl.LinkedNodeKind.superExpression,
-        _variantField_15 = superExpression_superKeyword,
-        _variantField_25 = expression_type;
+  LinkedNodeBuilder.showCombinator({
+    List<String> names,
+  })  : _kind = idl.LinkedNodeKind.showCombinator,
+        _variantField_36 = names;
 
   LinkedNodeBuilder.symbolLiteral({
-    int symbolLiteral_poundSign,
-    List<int> symbolLiteral_components,
+    List<String> names,
     LinkedNodeTypeBuilder expression_type,
   })  : _kind = idl.LinkedNodeKind.symbolLiteral,
-        _variantField_15 = symbolLiteral_poundSign,
-        _variantField_28 = symbolLiteral_components,
+        _variantField_36 = names,
+        _variantField_25 = expression_type;
+
+  LinkedNodeBuilder.doubleLiteral({
+    double doubleLiteral_value,
+  })  : _kind = idl.LinkedNodeKind.doubleLiteral,
+        _variantField_21 = doubleLiteral_value;
+
+  LinkedNodeBuilder.rethrowExpression({
+    LinkedNodeTypeBuilder expression_type,
+  })  : _kind = idl.LinkedNodeKind.rethrowExpression,
+        _variantField_25 = expression_type;
+
+  LinkedNodeBuilder.superExpression({
+    LinkedNodeTypeBuilder expression_type,
+  })  : _kind = idl.LinkedNodeKind.superExpression,
         _variantField_25 = expression_type;
 
   LinkedNodeBuilder.thisExpression({
-    int thisExpression_thisKeyword,
     LinkedNodeTypeBuilder expression_type,
   })  : _kind = idl.LinkedNodeKind.thisExpression,
-        _variantField_15 = thisExpression_thisKeyword,
         _variantField_25 = expression_type;
 
+  LinkedNodeBuilder.integerLiteral({
+    int integerLiteral_value,
+  })  : _kind = idl.LinkedNodeKind.integerLiteral,
+        _variantField_16 = integerLiteral_value;
+
+  LinkedNodeBuilder.interpolationString({
+    String interpolationString_value,
+  })  : _kind = idl.LinkedNodeKind.interpolationString,
+        _variantField_30 = interpolationString_value;
+
+  LinkedNodeBuilder.simpleStringLiteral({
+    String simpleStringLiteral_value,
+  })  : _kind = idl.LinkedNodeKind.simpleStringLiteral,
+        _variantField_20 = simpleStringLiteral_value;
+
   /// Flush [informative] data recursively.
   void flushInformative() {
     _variantField_24?.flushInformative();
@@ -11774,7 +9019,7 @@
   /// 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);
+    signature.addString(this._variantField_1 ?? '');
     if (this._variantField_2 == null) {
       signature.addInt(0);
     } else {
@@ -11828,7 +9073,7 @@
     signature.addInt(this._variantField_15 ?? 0);
     signature.addInt(this._variantField_16 ?? 0);
     signature.addInt(this._variantField_17 ?? 0);
-    signature.addInt(this._variantField_18 ?? 0);
+    signature.addInt(this._flags ?? 0);
     signature.addInt(this._variantField_19 ?? 0);
     signature.addString(this._variantField_20 ?? '');
     signature.addDouble(this._variantField_21 ?? 0.0);
@@ -11842,14 +9087,8 @@
     signature.addInt(
         this._variantField_26 == null ? 0 : this._variantField_26.index);
     signature.addBool(this._variantField_27 == true);
-    if (this._variantField_28 == null) {
-      signature.addInt(0);
-    } else {
-      signature.addInt(this._variantField_28.length);
-      for (var x in this._variantField_28) {
-        signature.addInt(x);
-      }
-    }
+    signature.addInt(
+        this._variantField_28 == null ? 0 : this._variantField_28.index);
     signature.addInt(
         this._variantField_29 == null ? 0 : this._variantField_29.index);
     signature.addString(this._variantField_30 ?? '');
@@ -11868,6 +9107,9 @@
         signature.addString(x);
       }
     }
+    signature.addString(this._name ?? '');
+    signature.addInt(
+        this._variantField_38 == null ? 0 : this._variantField_38.index);
   }
 
   fb.Offset finish(fb.Builder fbBuilder) {
@@ -11883,13 +9125,14 @@
     fb.Offset offset_variantField_12;
     fb.Offset offset_variantField_5;
     fb.Offset offset_variantField_13;
-    fb.Offset offset_variantField_28;
+    fb.Offset offset_variantField_36;
     fb.Offset offset_variantField_3;
     fb.Offset offset_variantField_10;
     fb.Offset offset_variantField_25;
+    fb.Offset offset_variantField_1;
     fb.Offset offset_variantField_30;
     fb.Offset offset_variantField_14;
-    fb.Offset offset_variantField_36;
+    fb.Offset offset_name;
     fb.Offset offset_variantField_20;
     fb.Offset offset_variantField_35;
     fb.Offset offset_variantField_22;
@@ -11933,8 +9176,9 @@
     if (_variantField_13 != null) {
       offset_variantField_13 = _variantField_13.finish(fbBuilder);
     }
-    if (!(_variantField_28 == null || _variantField_28.isEmpty)) {
-      offset_variantField_28 = fbBuilder.writeListUint32(_variantField_28);
+    if (!(_variantField_36 == null || _variantField_36.isEmpty)) {
+      offset_variantField_36 = fbBuilder.writeList(
+          _variantField_36.map((b) => fbBuilder.writeString(b)).toList());
     }
     if (!(_variantField_3 == null || _variantField_3.isEmpty)) {
       offset_variantField_3 = fbBuilder
@@ -11946,15 +9190,17 @@
     if (_variantField_25 != null) {
       offset_variantField_25 = _variantField_25.finish(fbBuilder);
     }
+    if (_variantField_1 != null) {
+      offset_variantField_1 = fbBuilder.writeString(_variantField_1);
+    }
     if (_variantField_30 != null) {
       offset_variantField_30 = fbBuilder.writeString(_variantField_30);
     }
     if (_variantField_14 != null) {
       offset_variantField_14 = _variantField_14.finish(fbBuilder);
     }
-    if (!(_variantField_36 == null || _variantField_36.isEmpty)) {
-      offset_variantField_36 = fbBuilder.writeList(
-          _variantField_36.map((b) => fbBuilder.writeString(b)).toList());
+    if (_name != null) {
+      offset_name = fbBuilder.writeString(_name);
     }
     if (_variantField_20 != null) {
       offset_variantField_20 = fbBuilder.writeString(_variantField_20);
@@ -11984,9 +9230,6 @@
     if (offset_variantField_6 != null) {
       fbBuilder.addOffset(6, offset_variantField_6);
     }
-    if (_variantField_15 != null && _variantField_15 != 0) {
-      fbBuilder.addUint32(15, _variantField_15);
-    }
     if (offset_variantField_7 != null) {
       fbBuilder.addOffset(7, offset_variantField_7);
     }
@@ -11999,14 +9242,12 @@
     if (offset_variantField_8 != null) {
       fbBuilder.addOffset(8, offset_variantField_8);
     }
-    if (_variantField_16 != null && _variantField_16 != 0) {
-      fbBuilder.addUint32(16, _variantField_16);
+    if (_variantField_15 != null && _variantField_15 != 0) {
+      fbBuilder.addUint32(15, _variantField_15);
     }
-    if (_variantField_18 != null && _variantField_18 != 0) {
-      fbBuilder.addUint32(18, _variantField_18);
-    }
-    if (_variantField_19 != null && _variantField_19 != 0) {
-      fbBuilder.addUint32(19, _variantField_19);
+    if (_variantField_28 != null &&
+        _variantField_28 != idl.UnlinkedTokenType.NOTHING) {
+      fbBuilder.addUint8(28, _variantField_28.index);
     }
     if (_variantField_27 == true) {
       fbBuilder.addBool(27, true);
@@ -12029,8 +9270,8 @@
     if (_variantField_33 != null && _variantField_33 != 0) {
       fbBuilder.addUint32(33, _variantField_33);
     }
-    if (offset_variantField_28 != null) {
-      fbBuilder.addOffset(28, offset_variantField_28);
+    if (offset_variantField_36 != null) {
+      fbBuilder.addOffset(36, offset_variantField_36);
     }
     if (_variantField_29 != null &&
         _variantField_29 != idl.LinkedNodeCommentType.block) {
@@ -12053,20 +9294,26 @@
     if (offset_variantField_25 != null) {
       fbBuilder.addOffset(25, offset_variantField_25);
     }
+    if (_flags != null && _flags != 0) {
+      fbBuilder.addUint32(18, _flags);
+    }
+    if (offset_variantField_1 != null) {
+      fbBuilder.addOffset(1, offset_variantField_1);
+    }
+    if (_variantField_16 != null && _variantField_16 != 0) {
+      fbBuilder.addUint32(16, _variantField_16);
+    }
     if (offset_variantField_30 != null) {
       fbBuilder.addOffset(30, offset_variantField_30);
     }
     if (offset_variantField_14 != null) {
       fbBuilder.addOffset(14, offset_variantField_14);
     }
-    if (_isSynthetic == true) {
-      fbBuilder.addBool(1, true);
-    }
     if (_kind != null && _kind != idl.LinkedNodeKind.adjacentStrings) {
       fbBuilder.addUint8(0, _kind.index);
     }
-    if (offset_variantField_36 != null) {
-      fbBuilder.addOffset(36, offset_variantField_36);
+    if (offset_name != null) {
+      fbBuilder.addOffset(37, offset_name);
     }
     if (offset_variantField_20 != null) {
       fbBuilder.addOffset(20, offset_variantField_20);
@@ -12074,12 +9321,19 @@
     if (_variantField_31 == true) {
       fbBuilder.addBool(31, true);
     }
+    if (_variantField_38 != null &&
+        _variantField_38 != idl.UnlinkedTokenType.NOTHING) {
+      fbBuilder.addUint8(38, _variantField_38.index);
+    }
     if (offset_variantField_35 != null) {
       fbBuilder.addOffset(35, offset_variantField_35);
     }
     if (offset_variantField_22 != null) {
       fbBuilder.addOffset(22, offset_variantField_22);
     }
+    if (_variantField_19 != null && _variantField_19 != 0) {
+      fbBuilder.addUint32(19, _variantField_19);
+    }
     if (offset_variantField_32 != null) {
       fbBuilder.addOffset(32, offset_variantField_32);
     }
@@ -12108,14 +9362,12 @@
   idl.LinkedNode _variantField_11;
   List<idl.LinkedNode> _variantField_4;
   idl.LinkedNode _variantField_6;
-  int _variantField_15;
   idl.LinkedNode _variantField_7;
   int _variantField_17;
   idl.LinkedNodeType _variantField_23;
   idl.LinkedNode _variantField_8;
-  int _variantField_16;
-  int _variantField_18;
-  int _variantField_19;
+  int _variantField_15;
+  idl.UnlinkedTokenType _variantField_28;
   bool _variantField_27;
   idl.LinkedNode _variantField_9;
   idl.LinkedNode _variantField_12;
@@ -12123,22 +9375,26 @@
   idl.LinkedNode _variantField_13;
   int _variantField_34;
   int _variantField_33;
-  List<int> _variantField_28;
+  List<String> _variantField_36;
   idl.LinkedNodeCommentType _variantField_29;
   List<idl.LinkedNode> _variantField_3;
   idl.LinkedNode _variantField_10;
   idl.LinkedNodeFormalParameterKind _variantField_26;
   double _variantField_21;
   idl.LinkedNodeType _variantField_25;
+  int _flags;
+  String _variantField_1;
+  int _variantField_16;
   String _variantField_30;
   idl.LinkedNode _variantField_14;
-  bool _isSynthetic;
   idl.LinkedNodeKind _kind;
-  List<String> _variantField_36;
+  String _name;
   String _variantField_20;
   bool _variantField_31;
+  idl.UnlinkedTokenType _variantField_38;
   idl.TopLevelInferenceError _variantField_35;
   String _variantField_22;
+  int _variantField_19;
   idl.LinkedNodeVariablesDeclaration _variantField_32;
 
   @override
@@ -12272,8 +9528,8 @@
   }
 
   @override
-  List<idl.LinkedNode> get hideCombinator_hiddenNames {
-    assert(kind == idl.LinkedNodeKind.hideCombinator);
+  List<idl.LinkedNode> get implementsClause_interfaces {
+    assert(kind == idl.LinkedNodeKind.implementsClause);
     _variantField_2 ??=
         const fb.ListReader<idl.LinkedNode>(const _LinkedNodeReader())
             .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
@@ -12281,8 +9537,8 @@
   }
 
   @override
-  List<idl.LinkedNode> get implementsClause_interfaces {
-    assert(kind == idl.LinkedNodeKind.implementsClause);
+  List<idl.LinkedNode> get instanceCreationExpression_arguments {
+    assert(kind == idl.LinkedNodeKind.instanceCreationExpression);
     _variantField_2 ??=
         const fb.ListReader<idl.LinkedNode>(const _LinkedNodeReader())
             .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
@@ -12308,15 +9564,6 @@
   }
 
   @override
-  List<idl.LinkedNode> get listLiteral_elements {
-    assert(kind == idl.LinkedNodeKind.listLiteral);
-    _variantField_2 ??=
-        const fb.ListReader<idl.LinkedNode>(const _LinkedNodeReader())
-            .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
-    return _variantField_2;
-  }
-
-  @override
   List<idl.LinkedNode> get namespaceDirective_combinators {
     assert(kind == idl.LinkedNodeKind.exportDirective ||
         kind == idl.LinkedNodeKind.importDirective);
@@ -12336,24 +9583,6 @@
   }
 
   @override
-  List<idl.LinkedNode> get setOrMapLiteral_elements {
-    assert(kind == idl.LinkedNodeKind.setOrMapLiteral);
-    _variantField_2 ??=
-        const fb.ListReader<idl.LinkedNode>(const _LinkedNodeReader())
-            .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
-    return _variantField_2;
-  }
-
-  @override
-  List<idl.LinkedNode> get showCombinator_shownNames {
-    assert(kind == idl.LinkedNodeKind.showCombinator);
-    _variantField_2 ??=
-        const fb.ListReader<idl.LinkedNode>(const _LinkedNodeReader())
-            .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
-    return _variantField_2;
-  }
-
-  @override
   List<idl.LinkedNode> get stringInterpolation_elements {
     assert(kind == idl.LinkedNodeKind.stringInterpolation);
     _variantField_2 ??=
@@ -12390,6 +9619,25 @@
   }
 
   @override
+  List<idl.LinkedNode> get typedLiteral_typeArguments {
+    assert(kind == idl.LinkedNodeKind.listLiteral ||
+        kind == idl.LinkedNodeKind.setOrMapLiteral);
+    _variantField_2 ??=
+        const fb.ListReader<idl.LinkedNode>(const _LinkedNodeReader())
+            .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
+    return _variantField_2;
+  }
+
+  @override
+  List<idl.LinkedNode> get typeName_typeArguments {
+    assert(kind == idl.LinkedNodeKind.typeName);
+    _variantField_2 ??=
+        const fb.ListReader<idl.LinkedNode>(const _LinkedNodeReader())
+            .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
+    return _variantField_2;
+  }
+
+  @override
   List<idl.LinkedNode> get typeParameterList_typeParameters {
     assert(kind == idl.LinkedNodeKind.typeParameterList);
     _variantField_2 ??=
@@ -12687,14 +9935,6 @@
   }
 
   @override
-  idl.LinkedNode get enumConstantDeclaration_name {
-    assert(kind == idl.LinkedNodeKind.enumConstantDeclaration);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
   idl.LinkedNode get expressionFunctionBody_expression {
     assert(kind == idl.LinkedNodeKind.expressionFunctionBody);
     _variantField_6 ??=
@@ -12835,14 +10075,6 @@
   }
 
   @override
-  idl.LinkedNode get importDirective_prefix {
-    assert(kind == idl.LinkedNodeKind.importDirective);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
   idl.LinkedNode get indexExpression_index {
     assert(kind == idl.LinkedNodeKind.indexExpression);
     _variantField_6 ??=
@@ -12851,14 +10083,6 @@
   }
 
   @override
-  idl.LinkedNode get instanceCreationExpression_arguments {
-    assert(kind == idl.LinkedNodeKind.instanceCreationExpression);
-    _variantField_6 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
-    return _variantField_6;
-  }
-
-  @override
   idl.LinkedNode get interpolationExpression_expression {
     assert(kind == idl.LinkedNodeKind.interpolationExpression);
     _variantField_6 ??=
@@ -13131,755 +10355,6 @@
   }
 
   @override
-  int get annotation_atSign {
-    assert(kind == idl.LinkedNodeKind.annotation);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get argumentList_leftParenthesis {
-    assert(kind == idl.LinkedNodeKind.argumentList);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get asExpression_asOperator {
-    assert(kind == idl.LinkedNodeKind.asExpression);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get assertInitializer_assertKeyword {
-    assert(kind == idl.LinkedNodeKind.assertInitializer);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get assertStatement_assertKeyword {
-    assert(kind == idl.LinkedNodeKind.assertStatement);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get assignmentExpression_element {
-    assert(kind == idl.LinkedNodeKind.assignmentExpression);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get awaitExpression_awaitKeyword {
-    assert(kind == idl.LinkedNodeKind.awaitExpression);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get binaryExpression_element {
-    assert(kind == idl.LinkedNodeKind.binaryExpression);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get block_leftBracket {
-    assert(kind == idl.LinkedNodeKind.block);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get blockFunctionBody_keyword {
-    assert(kind == idl.LinkedNodeKind.blockFunctionBody);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get booleanLiteral_literal {
-    assert(kind == idl.LinkedNodeKind.booleanLiteral);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get breakStatement_breakKeyword {
-    assert(kind == idl.LinkedNodeKind.breakStatement);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get catchClause_catchKeyword {
-    assert(kind == idl.LinkedNodeKind.catchClause);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get classDeclaration_abstractKeyword {
-    assert(kind == idl.LinkedNodeKind.classDeclaration);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get classTypeAlias_abstractKeyword {
-    assert(kind == idl.LinkedNodeKind.classTypeAlias);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get commentReference_newKeyword {
-    assert(kind == idl.LinkedNodeKind.commentReference);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get compilationUnit_beginToken {
-    assert(kind == idl.LinkedNodeKind.compilationUnit);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get conditionalExpression_colon {
-    assert(kind == idl.LinkedNodeKind.conditionalExpression);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get configuration_ifKeyword {
-    assert(kind == idl.LinkedNodeKind.configuration);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get constructorDeclaration_constKeyword {
-    assert(kind == idl.LinkedNodeKind.constructorDeclaration);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get constructorFieldInitializer_equals {
-    assert(kind == idl.LinkedNodeKind.constructorFieldInitializer);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get constructorName_element {
-    assert(kind == idl.LinkedNodeKind.constructorName);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get continueStatement_continueKeyword {
-    assert(kind == idl.LinkedNodeKind.continueStatement);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get declaredIdentifier_keyword {
-    assert(kind == idl.LinkedNodeKind.declaredIdentifier);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get defaultFormalParameter_separator {
-    assert(kind == idl.LinkedNodeKind.defaultFormalParameter);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get doStatement_leftParenthesis {
-    assert(kind == idl.LinkedNodeKind.doStatement);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get doubleLiteral_literal {
-    assert(kind == idl.LinkedNodeKind.doubleLiteral);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get emptyFunctionBody_semicolon {
-    assert(kind == idl.LinkedNodeKind.emptyFunctionBody);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get emptyStatement_semicolon {
-    assert(kind == idl.LinkedNodeKind.emptyStatement);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get enumDeclaration_enumKeyword {
-    assert(kind == idl.LinkedNodeKind.enumDeclaration);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get expressionFunctionBody_arrow {
-    assert(kind == idl.LinkedNodeKind.expressionFunctionBody);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get expressionStatement_semicolon {
-    assert(kind == idl.LinkedNodeKind.expressionStatement);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get extendsClause_extendsKeyword {
-    assert(kind == idl.LinkedNodeKind.extendsClause);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get fieldDeclaration_covariantKeyword {
-    assert(kind == idl.LinkedNodeKind.fieldDeclaration);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get fieldFormalParameter_keyword {
-    assert(kind == idl.LinkedNodeKind.fieldFormalParameter);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get forEachParts_inKeyword {
-    assert(kind == idl.LinkedNodeKind.forEachPartsWithDeclaration ||
-        kind == idl.LinkedNodeKind.forEachPartsWithIdentifier);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get formalParameterList_leftDelimiter {
-    assert(kind == idl.LinkedNodeKind.formalParameterList);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get forMixin_awaitKeyword {
-    assert(kind == idl.LinkedNodeKind.forElement ||
-        kind == idl.LinkedNodeKind.forStatement);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get forParts_leftSeparator {
-    assert(kind == idl.LinkedNodeKind.forPartsWithDeclarations ||
-        kind == idl.LinkedNodeKind.forPartsWithExpression);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get functionDeclaration_externalKeyword {
-    assert(kind == idl.LinkedNodeKind.functionDeclaration);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get genericFunctionType_functionKeyword {
-    assert(kind == idl.LinkedNodeKind.genericFunctionType);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get ifMixin_elseKeyword {
-    assert(kind == idl.LinkedNodeKind.ifElement ||
-        kind == idl.LinkedNodeKind.ifStatement);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get implementsClause_implementsKeyword {
-    assert(kind == idl.LinkedNodeKind.implementsClause);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get importDirective_asKeyword {
-    assert(kind == idl.LinkedNodeKind.importDirective);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get indexExpression_element {
-    assert(kind == idl.LinkedNodeKind.indexExpression);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get instanceCreationExpression_keyword {
-    assert(kind == idl.LinkedNodeKind.instanceCreationExpression);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get integerLiteral_literal {
-    assert(kind == idl.LinkedNodeKind.integerLiteral);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get interpolationExpression_leftBracket {
-    assert(kind == idl.LinkedNodeKind.interpolationExpression);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get interpolationString_token {
-    assert(kind == idl.LinkedNodeKind.interpolationString);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get isExpression_isOperator {
-    assert(kind == idl.LinkedNodeKind.isExpression);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get label_colon {
-    assert(kind == idl.LinkedNodeKind.label);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get listLiteral_leftBracket {
-    assert(kind == idl.LinkedNodeKind.listLiteral);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get mapLiteralEntry_separator {
-    assert(kind == idl.LinkedNodeKind.mapLiteralEntry);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get methodDeclaration_externalKeyword {
-    assert(kind == idl.LinkedNodeKind.methodDeclaration);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get methodInvocation_operator {
-    assert(kind == idl.LinkedNodeKind.methodInvocation);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get mixinDeclaration_mixinKeyword {
-    assert(kind == idl.LinkedNodeKind.mixinDeclaration);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get nativeClause_nativeKeyword {
-    assert(kind == idl.LinkedNodeKind.nativeClause);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get nativeFunctionBody_nativeKeyword {
-    assert(kind == idl.LinkedNodeKind.nativeFunctionBody);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get nullLiteral_literal {
-    assert(kind == idl.LinkedNodeKind.nullLiteral);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get onClause_onKeyword {
-    assert(kind == idl.LinkedNodeKind.onClause);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get parenthesizedExpression_leftParenthesis {
-    assert(kind == idl.LinkedNodeKind.parenthesizedExpression);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get postfixExpression_element {
-    assert(kind == idl.LinkedNodeKind.postfixExpression);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get prefixedIdentifier_period {
-    assert(kind == idl.LinkedNodeKind.prefixedIdentifier);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get prefixExpression_element {
-    assert(kind == idl.LinkedNodeKind.prefixExpression);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get propertyAccess_operator {
-    assert(kind == idl.LinkedNodeKind.propertyAccess);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get redirectingConstructorInvocation_element {
-    assert(kind == idl.LinkedNodeKind.redirectingConstructorInvocation);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get rethrowExpression_rethrowKeyword {
-    assert(kind == idl.LinkedNodeKind.rethrowExpression);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get returnStatement_returnKeyword {
-    assert(kind == idl.LinkedNodeKind.returnStatement);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get scriptTag_scriptTag {
-    assert(kind == idl.LinkedNodeKind.scriptTag);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get setOrMapLiteral_leftBracket {
-    assert(kind == idl.LinkedNodeKind.setOrMapLiteral);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get simpleFormalParameter_keyword {
-    assert(kind == idl.LinkedNodeKind.simpleFormalParameter);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get simpleIdentifier_element {
-    assert(kind == idl.LinkedNodeKind.simpleIdentifier);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get simpleStringLiteral_token {
-    assert(kind == idl.LinkedNodeKind.simpleStringLiteral);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get spreadElement_spreadOperator {
-    assert(kind == idl.LinkedNodeKind.spreadElement);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get superConstructorInvocation_element {
-    assert(kind == idl.LinkedNodeKind.superConstructorInvocation);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get superExpression_superKeyword {
-    assert(kind == idl.LinkedNodeKind.superExpression);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get switchMember_keyword {
-    assert(kind == idl.LinkedNodeKind.switchCase ||
-        kind == idl.LinkedNodeKind.switchDefault);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get switchStatement_leftParenthesis {
-    assert(kind == idl.LinkedNodeKind.switchStatement);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get symbolLiteral_poundSign {
-    assert(kind == idl.LinkedNodeKind.symbolLiteral);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get thisExpression_thisKeyword {
-    assert(kind == idl.LinkedNodeKind.thisExpression);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get throwExpression_throwKeyword {
-    assert(kind == idl.LinkedNodeKind.throwExpression);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get topLevelVariableDeclaration_semicolon {
-    assert(kind == idl.LinkedNodeKind.topLevelVariableDeclaration);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get tryStatement_finallyKeyword {
-    assert(kind == idl.LinkedNodeKind.tryStatement);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get typeArgumentList_leftBracket {
-    assert(kind == idl.LinkedNodeKind.typeArgumentList);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get typeName_question {
-    assert(kind == idl.LinkedNodeKind.typeName);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get typeParameter_extendsKeyword {
-    assert(kind == idl.LinkedNodeKind.typeParameter);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get typeParameterList_leftBracket {
-    assert(kind == idl.LinkedNodeKind.typeParameterList);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get variableDeclaration_equals {
-    assert(kind == idl.LinkedNodeKind.variableDeclaration);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get variableDeclarationList_keyword {
-    assert(kind == idl.LinkedNodeKind.variableDeclarationList);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get variableDeclarationStatement_semicolon {
-    assert(kind == idl.LinkedNodeKind.variableDeclarationStatement);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get whileStatement_leftParenthesis {
-    assert(kind == idl.LinkedNodeKind.whileStatement);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get withClause_withKeyword {
-    assert(kind == idl.LinkedNodeKind.withClause);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
-  int get yieldStatement_yieldKeyword {
-    assert(kind == idl.LinkedNodeKind.yieldStatement);
-    _variantField_15 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
-    return _variantField_15;
-  }
-
-  @override
   idl.LinkedNode get annotation_constructorName {
     assert(kind == idl.LinkedNodeKind.annotation);
     _variantField_7 ??=
@@ -13968,14 +10443,6 @@
   }
 
   @override
-  idl.LinkedNode get constructorDeclaration_name {
-    assert(kind == idl.LinkedNodeKind.constructorDeclaration);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
   idl.LinkedNode get constructorFieldInitializer_fieldName {
     assert(kind == idl.LinkedNodeKind.constructorFieldInitializer);
     _variantField_7 ??=
@@ -14240,30 +10707,6 @@
   }
 
   @override
-  idl.LinkedNode get typeName_typeArguments {
-    assert(kind == idl.LinkedNodeKind.typeName);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get typeParameter_name {
-    assert(kind == idl.LinkedNodeKind.typeParameter);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
-  idl.LinkedNode get variableDeclaration_name {
-    assert(kind == idl.LinkedNodeKind.variableDeclaration);
-    _variantField_7 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
-    return _variantField_7;
-  }
-
-  @override
   idl.LinkedNode get whileStatement_condition {
     assert(kind == idl.LinkedNodeKind.whileStatement);
     _variantField_7 ??=
@@ -14280,111 +10723,6 @@
   }
 
   @override
-  int get assertInitializer_leftParenthesis {
-    assert(kind == idl.LinkedNodeKind.assertInitializer);
-    _variantField_17 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 17, 0);
-    return _variantField_17;
-  }
-
-  @override
-  int get assertStatement_leftParenthesis {
-    assert(kind == idl.LinkedNodeKind.assertStatement);
-    _variantField_17 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 17, 0);
-    return _variantField_17;
-  }
-
-  @override
-  int get catchClause_leftParenthesis {
-    assert(kind == idl.LinkedNodeKind.catchClause);
-    _variantField_17 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 17, 0);
-    return _variantField_17;
-  }
-
-  @override
-  int get configuration_rightParenthesis {
-    assert(kind == idl.LinkedNodeKind.configuration);
-    _variantField_17 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 17, 0);
-    return _variantField_17;
-  }
-
-  @override
-  int get constructorDeclaration_factoryKeyword {
-    assert(kind == idl.LinkedNodeKind.constructorDeclaration);
-    _variantField_17 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 17, 0);
-    return _variantField_17;
-  }
-
-  @override
-  int get constructorFieldInitializer_thisKeyword {
-    assert(kind == idl.LinkedNodeKind.constructorFieldInitializer);
-    _variantField_17 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 17, 0);
-    return _variantField_17;
-  }
-
-  @override
-  int get doStatement_doKeyword {
-    assert(kind == idl.LinkedNodeKind.doStatement);
-    _variantField_17 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 17, 0);
-    return _variantField_17;
-  }
-
-  @override
-  int get enumDeclaration_rightBracket {
-    assert(kind == idl.LinkedNodeKind.enumDeclaration);
-    _variantField_17 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 17, 0);
-    return _variantField_17;
-  }
-
-  @override
-  int get expressionFunctionBody_semicolon {
-    assert(kind == idl.LinkedNodeKind.expressionFunctionBody);
-    _variantField_17 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 17, 0);
-    return _variantField_17;
-  }
-
-  @override
-  int get fieldDeclaration_staticKeyword {
-    assert(kind == idl.LinkedNodeKind.fieldDeclaration);
-    _variantField_17 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 17, 0);
-    return _variantField_17;
-  }
-
-  @override
-  int get fieldFormalParameter_thisKeyword {
-    assert(kind == idl.LinkedNodeKind.fieldFormalParameter);
-    _variantField_17 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 17, 0);
-    return _variantField_17;
-  }
-
-  @override
-  int get formalParameterList_rightDelimiter {
-    assert(kind == idl.LinkedNodeKind.formalParameterList);
-    _variantField_17 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 17, 0);
-    return _variantField_17;
-  }
-
-  @override
-  int get forMixin_leftParenthesis {
-    assert(kind == idl.LinkedNodeKind.forElement ||
-        kind == idl.LinkedNodeKind.forStatement);
-    _variantField_17 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 17, 0);
-    return _variantField_17;
-  }
-
-  @override
   int get genericFunctionType_id {
     assert(kind == idl.LinkedNodeKind.genericFunctionType);
     _variantField_17 ??=
@@ -14393,71 +10731,6 @@
   }
 
   @override
-  int get ifMixin_leftParenthesis {
-    assert(kind == idl.LinkedNodeKind.ifElement ||
-        kind == idl.LinkedNodeKind.ifStatement);
-    _variantField_17 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 17, 0);
-    return _variantField_17;
-  }
-
-  @override
-  int get indexExpression_leftBracket {
-    assert(kind == idl.LinkedNodeKind.indexExpression);
-    _variantField_17 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 17, 0);
-    return _variantField_17;
-  }
-
-  @override
-  int get methodDeclaration_operatorKeyword {
-    assert(kind == idl.LinkedNodeKind.methodDeclaration);
-    _variantField_17 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 17, 0);
-    return _variantField_17;
-  }
-
-  @override
-  int get redirectingConstructorInvocation_thisKeyword {
-    assert(kind == idl.LinkedNodeKind.redirectingConstructorInvocation);
-    _variantField_17 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 17, 0);
-    return _variantField_17;
-  }
-
-  @override
-  int get superConstructorInvocation_superKeyword {
-    assert(kind == idl.LinkedNodeKind.superConstructorInvocation);
-    _variantField_17 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 17, 0);
-    return _variantField_17;
-  }
-
-  @override
-  int get switchStatement_switchKeyword {
-    assert(kind == idl.LinkedNodeKind.switchStatement);
-    _variantField_17 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 17, 0);
-    return _variantField_17;
-  }
-
-  @override
-  int get whileStatement_whileKeyword {
-    assert(kind == idl.LinkedNodeKind.whileStatement);
-    _variantField_17 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 17, 0);
-    return _variantField_17;
-  }
-
-  @override
-  int get yieldStatement_semicolon {
-    assert(kind == idl.LinkedNodeKind.yieldStatement);
-    _variantField_17 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 17, 0);
-    return _variantField_17;
-  }
-
-  @override
   idl.LinkedNodeType get annotation_elementType {
     assert(kind == idl.LinkedNodeKind.annotation);
     _variantField_23 ??=
@@ -14682,699 +10955,147 @@
   }
 
   @override
-  int get annotation_period {
-    assert(kind == idl.LinkedNodeKind.annotation);
-    _variantField_16 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 16, 0);
-    return _variantField_16;
-  }
-
-  @override
-  int get argumentList_rightParenthesis {
-    assert(kind == idl.LinkedNodeKind.argumentList);
-    _variantField_16 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 16, 0);
-    return _variantField_16;
-  }
-
-  @override
-  int get assertInitializer_comma {
-    assert(kind == idl.LinkedNodeKind.assertInitializer);
-    _variantField_16 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 16, 0);
-    return _variantField_16;
-  }
-
-  @override
-  int get assertStatement_comma {
-    assert(kind == idl.LinkedNodeKind.assertStatement);
-    _variantField_16 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 16, 0);
-    return _variantField_16;
-  }
-
-  @override
-  int get assignmentExpression_operator {
+  int get assignmentExpression_element {
     assert(kind == idl.LinkedNodeKind.assignmentExpression);
-    _variantField_16 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 16, 0);
-    return _variantField_16;
+    _variantField_15 ??=
+        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
+    return _variantField_15;
   }
 
   @override
-  int get binaryExpression_operator {
+  int get binaryExpression_element {
     assert(kind == idl.LinkedNodeKind.binaryExpression);
-    _variantField_16 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 16, 0);
-    return _variantField_16;
+    _variantField_15 ??=
+        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
+    return _variantField_15;
   }
 
   @override
-  int get block_rightBracket {
-    assert(kind == idl.LinkedNodeKind.block);
-    _variantField_16 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 16, 0);
-    return _variantField_16;
-  }
-
-  @override
-  int get blockFunctionBody_star {
-    assert(kind == idl.LinkedNodeKind.blockFunctionBody);
-    _variantField_16 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 16, 0);
-    return _variantField_16;
-  }
-
-  @override
-  int get breakStatement_semicolon {
-    assert(kind == idl.LinkedNodeKind.breakStatement);
-    _variantField_16 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 16, 0);
-    return _variantField_16;
-  }
-
-  @override
-  int get catchClause_comma {
-    assert(kind == idl.LinkedNodeKind.catchClause);
-    _variantField_16 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 16, 0);
-    return _variantField_16;
-  }
-
-  @override
-  int get classDeclaration_classKeyword {
-    assert(kind == idl.LinkedNodeKind.classDeclaration);
-    _variantField_16 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 16, 0);
-    return _variantField_16;
-  }
-
-  @override
-  int get classTypeAlias_equals {
-    assert(kind == idl.LinkedNodeKind.classTypeAlias);
-    _variantField_16 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 16, 0);
-    return _variantField_16;
-  }
-
-  @override
-  int get compilationUnit_endToken {
-    assert(kind == idl.LinkedNodeKind.compilationUnit);
-    _variantField_16 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 16, 0);
-    return _variantField_16;
-  }
-
-  @override
-  int get conditionalExpression_question {
-    assert(kind == idl.LinkedNodeKind.conditionalExpression);
-    _variantField_16 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 16, 0);
-    return _variantField_16;
-  }
-
-  @override
-  int get configuration_leftParenthesis {
-    assert(kind == idl.LinkedNodeKind.configuration);
-    _variantField_16 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 16, 0);
-    return _variantField_16;
-  }
-
-  @override
-  int get constructorDeclaration_externalKeyword {
-    assert(kind == idl.LinkedNodeKind.constructorDeclaration);
-    _variantField_16 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 16, 0);
-    return _variantField_16;
-  }
-
-  @override
-  int get constructorFieldInitializer_period {
-    assert(kind == idl.LinkedNodeKind.constructorFieldInitializer);
-    _variantField_16 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 16, 0);
-    return _variantField_16;
-  }
-
-  @override
-  int get constructorName_period {
+  int get constructorName_element {
     assert(kind == idl.LinkedNodeKind.constructorName);
-    _variantField_16 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 16, 0);
-    return _variantField_16;
+    _variantField_15 ??=
+        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
+    return _variantField_15;
   }
 
   @override
-  int get continueStatement_semicolon {
-    assert(kind == idl.LinkedNodeKind.continueStatement);
-    _variantField_16 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 16, 0);
-    return _variantField_16;
+  int get emptyFunctionBody_fake {
+    assert(kind == idl.LinkedNodeKind.emptyFunctionBody);
+    _variantField_15 ??=
+        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
+    return _variantField_15;
   }
 
   @override
-  int get doStatement_rightParenthesis {
-    assert(kind == idl.LinkedNodeKind.doStatement);
-    _variantField_16 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 16, 0);
-    return _variantField_16;
+  int get emptyStatement_fake {
+    assert(kind == idl.LinkedNodeKind.emptyStatement);
+    _variantField_15 ??=
+        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
+    return _variantField_15;
   }
 
   @override
-  int get enumDeclaration_leftBracket {
-    assert(kind == idl.LinkedNodeKind.enumDeclaration);
-    _variantField_16 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 16, 0);
-    return _variantField_16;
-  }
-
-  @override
-  int get expressionFunctionBody_keyword {
-    assert(kind == idl.LinkedNodeKind.expressionFunctionBody);
-    _variantField_16 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 16, 0);
-    return _variantField_16;
-  }
-
-  @override
-  int get fieldDeclaration_semicolon {
-    assert(kind == idl.LinkedNodeKind.fieldDeclaration);
-    _variantField_16 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 16, 0);
-    return _variantField_16;
-  }
-
-  @override
-  int get fieldFormalParameter_period {
-    assert(kind == idl.LinkedNodeKind.fieldFormalParameter);
-    _variantField_16 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 16, 0);
-    return _variantField_16;
-  }
-
-  @override
-  int get formalParameterList_leftParenthesis {
-    assert(kind == idl.LinkedNodeKind.formalParameterList);
-    _variantField_16 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 16, 0);
-    return _variantField_16;
-  }
-
-  @override
-  int get forMixin_forKeyword {
-    assert(kind == idl.LinkedNodeKind.forElement ||
-        kind == idl.LinkedNodeKind.forStatement);
-    _variantField_16 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 16, 0);
-    return _variantField_16;
-  }
-
-  @override
-  int get forParts_rightSeparator {
-    assert(kind == idl.LinkedNodeKind.forPartsWithDeclarations ||
-        kind == idl.LinkedNodeKind.forPartsWithExpression);
-    _variantField_16 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 16, 0);
-    return _variantField_16;
-  }
-
-  @override
-  int get functionDeclaration_propertyKeyword {
-    assert(kind == idl.LinkedNodeKind.functionDeclaration);
-    _variantField_16 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 16, 0);
-    return _variantField_16;
-  }
-
-  @override
-  int get genericFunctionType_question {
-    assert(kind == idl.LinkedNodeKind.genericFunctionType);
-    _variantField_16 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 16, 0);
-    return _variantField_16;
-  }
-
-  @override
-  int get genericTypeAlias_equals {
-    assert(kind == idl.LinkedNodeKind.genericTypeAlias);
-    _variantField_16 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 16, 0);
-    return _variantField_16;
-  }
-
-  @override
-  int get ifMixin_ifKeyword {
-    assert(kind == idl.LinkedNodeKind.ifElement ||
-        kind == idl.LinkedNodeKind.ifStatement);
-    _variantField_16 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 16, 0);
-    return _variantField_16;
-  }
-
-  @override
-  int get importDirective_deferredKeyword {
+  int get importDirective_prefixOffset {
     assert(kind == idl.LinkedNodeKind.importDirective);
-    _variantField_16 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 16, 0);
-    return _variantField_16;
+    _variantField_15 ??=
+        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
+    return _variantField_15;
   }
 
   @override
-  int get indexExpression_period {
+  int get indexExpression_element {
     assert(kind == idl.LinkedNodeKind.indexExpression);
-    _variantField_16 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 16, 0);
-    return _variantField_16;
+    _variantField_15 ??=
+        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
+    return _variantField_15;
   }
 
   @override
-  int get integerLiteral_value {
-    assert(kind == idl.LinkedNodeKind.integerLiteral);
-    _variantField_16 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 16, 0);
-    return _variantField_16;
+  int get nullLiteral_fake {
+    assert(kind == idl.LinkedNodeKind.nullLiteral);
+    _variantField_15 ??=
+        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
+    return _variantField_15;
   }
 
   @override
-  int get interpolationExpression_rightBracket {
-    assert(kind == idl.LinkedNodeKind.interpolationExpression);
-    _variantField_16 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 16, 0);
-    return _variantField_16;
-  }
-
-  @override
-  int get isExpression_notOperator {
-    assert(kind == idl.LinkedNodeKind.isExpression);
-    _variantField_16 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 16, 0);
-    return _variantField_16;
-  }
-
-  @override
-  int get listLiteral_rightBracket {
-    assert(kind == idl.LinkedNodeKind.listLiteral);
-    _variantField_16 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 16, 0);
-    return _variantField_16;
-  }
-
-  @override
-  int get methodDeclaration_modifierKeyword {
-    assert(kind == idl.LinkedNodeKind.methodDeclaration);
-    _variantField_16 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 16, 0);
-    return _variantField_16;
-  }
-
-  @override
-  int get nativeFunctionBody_semicolon {
-    assert(kind == idl.LinkedNodeKind.nativeFunctionBody);
-    _variantField_16 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 16, 0);
-    return _variantField_16;
-  }
-
-  @override
-  int get parenthesizedExpression_rightParenthesis {
-    assert(kind == idl.LinkedNodeKind.parenthesizedExpression);
-    _variantField_16 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 16, 0);
-    return _variantField_16;
-  }
-
-  @override
-  int get partOfDirective_ofKeyword {
-    assert(kind == idl.LinkedNodeKind.partOfDirective);
-    _variantField_16 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 16, 0);
-    return _variantField_16;
-  }
-
-  @override
-  int get postfixExpression_operator {
+  int get postfixExpression_element {
     assert(kind == idl.LinkedNodeKind.postfixExpression);
-    _variantField_16 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 16, 0);
-    return _variantField_16;
+    _variantField_15 ??=
+        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
+    return _variantField_15;
   }
 
   @override
-  int get prefixExpression_operator {
+  int get prefixExpression_element {
     assert(kind == idl.LinkedNodeKind.prefixExpression);
-    _variantField_16 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 16, 0);
-    return _variantField_16;
+    _variantField_15 ??=
+        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
+    return _variantField_15;
   }
 
   @override
-  int get redirectingConstructorInvocation_period {
+  int get redirectingConstructorInvocation_element {
     assert(kind == idl.LinkedNodeKind.redirectingConstructorInvocation);
-    _variantField_16 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 16, 0);
-    return _variantField_16;
+    _variantField_15 ??=
+        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
+    return _variantField_15;
   }
 
   @override
-  int get returnStatement_semicolon {
-    assert(kind == idl.LinkedNodeKind.returnStatement);
-    _variantField_16 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 16, 0);
-    return _variantField_16;
-  }
-
-  @override
-  int get setOrMapLiteral_rightBracket {
-    assert(kind == idl.LinkedNodeKind.setOrMapLiteral);
-    _variantField_16 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 16, 0);
-    return _variantField_16;
-  }
-
-  @override
-  int get simpleIdentifier_token {
+  int get simpleIdentifier_element {
     assert(kind == idl.LinkedNodeKind.simpleIdentifier);
-    _variantField_16 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 16, 0);
-    return _variantField_16;
+    _variantField_15 ??=
+        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
+    return _variantField_15;
   }
 
   @override
-  int get superConstructorInvocation_period {
+  int get superConstructorInvocation_element {
     assert(kind == idl.LinkedNodeKind.superConstructorInvocation);
-    _variantField_16 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 16, 0);
-    return _variantField_16;
+    _variantField_15 ??=
+        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
+    return _variantField_15;
   }
 
   @override
-  int get switchMember_colon {
-    assert(kind == idl.LinkedNodeKind.switchCase ||
-        kind == idl.LinkedNodeKind.switchDefault);
-    _variantField_16 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 16, 0);
-    return _variantField_16;
+  idl.UnlinkedTokenType get assignmentExpression_operator {
+    assert(kind == idl.LinkedNodeKind.assignmentExpression);
+    _variantField_28 ??= const _UnlinkedTokenTypeReader()
+        .vTableGet(_bc, _bcOffset, 28, idl.UnlinkedTokenType.NOTHING);
+    return _variantField_28;
   }
 
   @override
-  int get switchStatement_rightParenthesis {
-    assert(kind == idl.LinkedNodeKind.switchStatement);
-    _variantField_16 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 16, 0);
-    return _variantField_16;
+  idl.UnlinkedTokenType get binaryExpression_operator {
+    assert(kind == idl.LinkedNodeKind.binaryExpression);
+    _variantField_28 ??= const _UnlinkedTokenTypeReader()
+        .vTableGet(_bc, _bcOffset, 28, idl.UnlinkedTokenType.NOTHING);
+    return _variantField_28;
   }
 
   @override
-  int get tryStatement_tryKeyword {
-    assert(kind == idl.LinkedNodeKind.tryStatement);
-    _variantField_16 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 16, 0);
-    return _variantField_16;
+  idl.UnlinkedTokenType get postfixExpression_operator {
+    assert(kind == idl.LinkedNodeKind.postfixExpression);
+    _variantField_28 ??= const _UnlinkedTokenTypeReader()
+        .vTableGet(_bc, _bcOffset, 28, idl.UnlinkedTokenType.NOTHING);
+    return _variantField_28;
   }
 
   @override
-  int get typeArgumentList_rightBracket {
-    assert(kind == idl.LinkedNodeKind.typeArgumentList);
-    _variantField_16 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 16, 0);
-    return _variantField_16;
+  idl.UnlinkedTokenType get prefixExpression_operator {
+    assert(kind == idl.LinkedNodeKind.prefixExpression);
+    _variantField_28 ??= const _UnlinkedTokenTypeReader()
+        .vTableGet(_bc, _bcOffset, 28, idl.UnlinkedTokenType.NOTHING);
+    return _variantField_28;
   }
 
   @override
-  int get typeParameterList_rightBracket {
-    assert(kind == idl.LinkedNodeKind.typeParameterList);
-    _variantField_16 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 16, 0);
-    return _variantField_16;
-  }
-
-  @override
-  int get variableDeclarationList_lateKeyword {
-    assert(kind == idl.LinkedNodeKind.variableDeclarationList);
-    _variantField_16 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 16, 0);
-    return _variantField_16;
-  }
-
-  @override
-  int get whileStatement_rightParenthesis {
-    assert(kind == idl.LinkedNodeKind.whileStatement);
-    _variantField_16 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 16, 0);
-    return _variantField_16;
-  }
-
-  @override
-  int get yieldStatement_star {
-    assert(kind == idl.LinkedNodeKind.yieldStatement);
-    _variantField_16 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 16, 0);
-    return _variantField_16;
-  }
-
-  @override
-  int get assertInitializer_rightParenthesis {
-    assert(kind == idl.LinkedNodeKind.assertInitializer);
-    _variantField_18 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 18, 0);
-    return _variantField_18;
-  }
-
-  @override
-  int get assertStatement_rightParenthesis {
-    assert(kind == idl.LinkedNodeKind.assertStatement);
-    _variantField_18 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 18, 0);
-    return _variantField_18;
-  }
-
-  @override
-  int get catchClause_onKeyword {
-    assert(kind == idl.LinkedNodeKind.catchClause);
-    _variantField_18 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 18, 0);
-    return _variantField_18;
-  }
-
-  @override
-  int get classOrMixinDeclaration_rightBracket {
-    assert(kind == idl.LinkedNodeKind.classDeclaration ||
-        kind == idl.LinkedNodeKind.mixinDeclaration);
-    _variantField_18 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 18, 0);
-    return _variantField_18;
-  }
-
-  @override
-  int get configuration_equalToken {
-    assert(kind == idl.LinkedNodeKind.configuration);
-    _variantField_18 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 18, 0);
-    return _variantField_18;
-  }
-
-  @override
-  int get constructorDeclaration_period {
-    assert(kind == idl.LinkedNodeKind.constructorDeclaration);
-    _variantField_18 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 18, 0);
-    return _variantField_18;
-  }
-
-  @override
-  int get directive_keyword {
-    assert(kind == idl.LinkedNodeKind.exportDirective ||
-        kind == idl.LinkedNodeKind.importDirective ||
-        kind == idl.LinkedNodeKind.libraryDirective ||
-        kind == idl.LinkedNodeKind.partDirective ||
-        kind == idl.LinkedNodeKind.partOfDirective);
-    _variantField_18 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 18, 0);
-    return _variantField_18;
-  }
-
-  @override
-  int get doStatement_semicolon {
-    assert(kind == idl.LinkedNodeKind.doStatement);
-    _variantField_18 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 18, 0);
-    return _variantField_18;
-  }
-
-  @override
-  int get formalParameterList_rightParenthesis {
-    assert(kind == idl.LinkedNodeKind.formalParameterList);
-    _variantField_18 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 18, 0);
-    return _variantField_18;
-  }
-
-  @override
-  int get ifMixin_rightParenthesis {
-    assert(kind == idl.LinkedNodeKind.ifElement ||
-        kind == idl.LinkedNodeKind.ifStatement);
-    _variantField_18 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 18, 0);
-    return _variantField_18;
-  }
-
-  @override
-  int get indexExpression_rightBracket {
-    assert(kind == idl.LinkedNodeKind.indexExpression);
-    _variantField_18 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 18, 0);
-    return _variantField_18;
-  }
-
-  @override
-  int get methodDeclaration_propertyKeyword {
-    assert(kind == idl.LinkedNodeKind.methodDeclaration);
-    _variantField_18 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 18, 0);
-    return _variantField_18;
-  }
-
-  @override
-  int get normalFormalParameter_requiredKeyword {
-    assert(kind == idl.LinkedNodeKind.fieldFormalParameter ||
-        kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
-        kind == idl.LinkedNodeKind.simpleFormalParameter);
-    _variantField_18 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 18, 0);
-    return _variantField_18;
-  }
-
-  @override
-  int get switchStatement_leftBracket {
-    assert(kind == idl.LinkedNodeKind.switchStatement);
-    _variantField_18 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 18, 0);
-    return _variantField_18;
-  }
-
-  @override
-  int get typeAlias_typedefKeyword {
-    assert(kind == idl.LinkedNodeKind.classTypeAlias ||
-        kind == idl.LinkedNodeKind.functionTypeAlias ||
-        kind == idl.LinkedNodeKind.genericTypeAlias);
-    _variantField_18 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 18, 0);
-    return _variantField_18;
-  }
-
-  @override
-  int get assertStatement_semicolon {
-    assert(kind == idl.LinkedNodeKind.assertStatement);
-    _variantField_19 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 19, 0);
-    return _variantField_19;
-  }
-
-  @override
-  int get catchClause_rightParenthesis {
-    assert(kind == idl.LinkedNodeKind.catchClause);
-    _variantField_19 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 19, 0);
-    return _variantField_19;
-  }
-
-  @override
-  int get classOrMixinDeclaration_leftBracket {
-    assert(kind == idl.LinkedNodeKind.classDeclaration ||
-        kind == idl.LinkedNodeKind.mixinDeclaration);
-    _variantField_19 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 19, 0);
-    return _variantField_19;
-  }
-
-  @override
-  int get combinator_keyword {
-    assert(kind == idl.LinkedNodeKind.hideCombinator ||
-        kind == idl.LinkedNodeKind.showCombinator);
-    _variantField_19 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 19, 0);
-    return _variantField_19;
-  }
-
-  @override
-  int get constructorDeclaration_separator {
-    assert(kind == idl.LinkedNodeKind.constructorDeclaration);
-    _variantField_19 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 19, 0);
-    return _variantField_19;
-  }
-
-  @override
-  int get doStatement_whileKeyword {
-    assert(kind == idl.LinkedNodeKind.doStatement);
-    _variantField_19 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 19, 0);
-    return _variantField_19;
-  }
-
-  @override
-  int get forMixin_rightParenthesis {
-    assert(kind == idl.LinkedNodeKind.forElement ||
-        kind == idl.LinkedNodeKind.forStatement);
-    _variantField_19 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 19, 0);
-    return _variantField_19;
-  }
-
-  @override
-  int get methodDeclaration_actualProperty {
-    assert(kind == idl.LinkedNodeKind.methodDeclaration);
-    _variantField_19 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 19, 0);
-    return _variantField_19;
-  }
-
-  @override
-  int get normalFormalParameter_covariantKeyword {
-    assert(kind == idl.LinkedNodeKind.fieldFormalParameter ||
-        kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
-        kind == idl.LinkedNodeKind.simpleFormalParameter);
-    _variantField_19 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 19, 0);
-    return _variantField_19;
-  }
-
-  @override
-  int get switchStatement_rightBracket {
-    assert(kind == idl.LinkedNodeKind.switchStatement);
-    _variantField_19 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 19, 0);
-    return _variantField_19;
-  }
-
-  @override
-  int get typeAlias_semicolon {
-    assert(kind == idl.LinkedNodeKind.classTypeAlias ||
-        kind == idl.LinkedNodeKind.functionTypeAlias ||
-        kind == idl.LinkedNodeKind.genericTypeAlias);
-    _variantField_19 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 19, 0);
-    return _variantField_19;
-  }
-
-  @override
-  int get typedLiteral_constKeyword {
-    assert(kind == idl.LinkedNodeKind.listLiteral ||
-        kind == idl.LinkedNodeKind.setOrMapLiteral);
-    _variantField_19 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 19, 0);
-    return _variantField_19;
-  }
-
-  @override
-  int get uriBasedDirective_uriElement {
-    assert(kind == idl.LinkedNodeKind.exportDirective ||
-        kind == idl.LinkedNodeKind.importDirective ||
-        kind == idl.LinkedNodeKind.partDirective);
-    _variantField_19 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 19, 0);
-    return _variantField_19;
+  idl.UnlinkedTokenType get propertyAccess_operator {
+    assert(kind == idl.LinkedNodeKind.propertyAccess);
+    _variantField_28 ??= const _UnlinkedTokenTypeReader()
+        .vTableGet(_bc, _bcOffset, 28, idl.UnlinkedTokenType.NOTHING);
+    return _variantField_28;
   }
 
   @override
@@ -15405,22 +11126,6 @@
   }
 
   @override
-  bool get setOrMapLiteral_isMap {
-    assert(kind == idl.LinkedNodeKind.setOrMapLiteral);
-    _variantField_27 ??=
-        const fb.BoolReader().vTableGet(_bc, _bcOffset, 27, false);
-    return _variantField_27;
-  }
-
-  @override
-  bool get simpleIdentifier_isDeclaration {
-    assert(kind == idl.LinkedNodeKind.simpleIdentifier);
-    _variantField_27 ??=
-        const fb.BoolReader().vTableGet(_bc, _bcOffset, 27, false);
-    return _variantField_27;
-  }
-
-  @override
   bool get typeAlias_hasSelfReference {
     assert(kind == idl.LinkedNodeKind.functionTypeAlias ||
         kind == idl.LinkedNodeKind.genericTypeAlias);
@@ -15488,16 +11193,6 @@
   }
 
   @override
-  idl.LinkedNode get normalFormalParameter_identifier {
-    assert(kind == idl.LinkedNodeKind.fieldFormalParameter ||
-        kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
-        kind == idl.LinkedNodeKind.simpleFormalParameter);
-    _variantField_12 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 12, null);
-    return _variantField_12;
-  }
-
-  @override
   List<idl.LinkedNode> get classOrMixinDeclaration_members {
     assert(kind == idl.LinkedNodeKind.classDeclaration ||
         kind == idl.LinkedNodeKind.mixinDeclaration);
@@ -15573,31 +11268,29 @@
   }
 
   @override
-  int get directive_semicolon {
-    assert(kind == idl.LinkedNodeKind.exportDirective ||
-        kind == idl.LinkedNodeKind.importDirective ||
-        kind == idl.LinkedNodeKind.libraryDirective ||
-        kind == idl.LinkedNodeKind.partDirective ||
-        kind == idl.LinkedNodeKind.partOfDirective);
-    _variantField_33 ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 33, 0);
-    return _variantField_33;
-  }
-
-  @override
-  List<int> get comment_tokens {
+  List<String> get comment_tokens {
     assert(kind == idl.LinkedNodeKind.comment);
-    _variantField_28 ??= const fb.Uint32ListReader()
-        .vTableGet(_bc, _bcOffset, 28, const <int>[]);
-    return _variantField_28;
+    _variantField_36 ??= const fb.ListReader<String>(const fb.StringReader())
+        .vTableGet(_bc, _bcOffset, 36, const <String>[]);
+    return _variantField_36;
   }
 
   @override
-  List<int> get symbolLiteral_components {
-    assert(kind == idl.LinkedNodeKind.symbolLiteral);
-    _variantField_28 ??= const fb.Uint32ListReader()
-        .vTableGet(_bc, _bcOffset, 28, const <int>[]);
-    return _variantField_28;
+  List<String> get mixinDeclaration_superInvokedNames {
+    assert(kind == idl.LinkedNodeKind.mixinDeclaration);
+    _variantField_36 ??= const fb.ListReader<String>(const fb.StringReader())
+        .vTableGet(_bc, _bcOffset, 36, const <String>[]);
+    return _variantField_36;
+  }
+
+  @override
+  List<String> get names {
+    assert(kind == idl.LinkedNodeKind.hideCombinator ||
+        kind == idl.LinkedNodeKind.showCombinator ||
+        kind == idl.LinkedNodeKind.symbolLiteral);
+    _variantField_36 ??= const fb.ListReader<String>(const fb.StringReader())
+        .vTableGet(_bc, _bcOffset, 36, const <String>[]);
+    return _variantField_36;
   }
 
   @override
@@ -15618,6 +11311,15 @@
   }
 
   @override
+  List<idl.LinkedNode> get listLiteral_elements {
+    assert(kind == idl.LinkedNodeKind.listLiteral);
+    _variantField_3 ??=
+        const fb.ListReader<idl.LinkedNode>(const _LinkedNodeReader())
+            .vTableGet(_bc, _bcOffset, 3, const <idl.LinkedNode>[]);
+    return _variantField_3;
+  }
+
+  @override
   List<idl.LinkedNode> get namespaceDirective_configurations {
     assert(kind == idl.LinkedNodeKind.exportDirective ||
         kind == idl.LinkedNodeKind.importDirective);
@@ -15628,6 +11330,15 @@
   }
 
   @override
+  List<idl.LinkedNode> get setOrMapLiteral_elements {
+    assert(kind == idl.LinkedNodeKind.setOrMapLiteral);
+    _variantField_3 ??=
+        const fb.ListReader<idl.LinkedNode>(const _LinkedNodeReader())
+            .vTableGet(_bc, _bcOffset, 3, const <idl.LinkedNode>[]);
+    return _variantField_3;
+  }
+
+  @override
   List<idl.LinkedNode> get switchMember_labels {
     assert(kind == idl.LinkedNodeKind.switchCase ||
         kind == idl.LinkedNodeKind.switchDefault);
@@ -15646,14 +11357,6 @@
   }
 
   @override
-  idl.LinkedNode get methodDeclaration_name {
-    assert(kind == idl.LinkedNodeKind.methodDeclaration);
-    _variantField_10 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 10, null);
-    return _variantField_10;
-  }
-
-  @override
   idl.LinkedNodeFormalParameterKind get defaultFormalParameter_kind {
     assert(kind == idl.LinkedNodeKind.defaultFormalParameter);
     _variantField_26 ??= const _LinkedNodeFormalParameterKindReader().vTableGet(
@@ -15674,23 +11377,17 @@
 
   @override
   idl.LinkedNodeType get expression_type {
-    assert(kind == idl.LinkedNodeKind.adjacentStrings ||
-        kind == idl.LinkedNodeKind.assignmentExpression ||
+    assert(kind == idl.LinkedNodeKind.assignmentExpression ||
         kind == idl.LinkedNodeKind.asExpression ||
         kind == idl.LinkedNodeKind.awaitExpression ||
         kind == idl.LinkedNodeKind.binaryExpression ||
-        kind == idl.LinkedNodeKind.booleanLiteral ||
         kind == idl.LinkedNodeKind.cascadeExpression ||
         kind == idl.LinkedNodeKind.conditionalExpression ||
-        kind == idl.LinkedNodeKind.doubleLiteral ||
         kind == idl.LinkedNodeKind.functionExpressionInvocation ||
         kind == idl.LinkedNodeKind.indexExpression ||
         kind == idl.LinkedNodeKind.instanceCreationExpression ||
-        kind == idl.LinkedNodeKind.integerLiteral ||
-        kind == idl.LinkedNodeKind.isExpression ||
         kind == idl.LinkedNodeKind.listLiteral ||
         kind == idl.LinkedNodeKind.methodInvocation ||
-        kind == idl.LinkedNodeKind.namedExpression ||
         kind == idl.LinkedNodeKind.nullLiteral ||
         kind == idl.LinkedNodeKind.parenthesizedExpression ||
         kind == idl.LinkedNodeKind.prefixExpression ||
@@ -15700,8 +11397,6 @@
         kind == idl.LinkedNodeKind.rethrowExpression ||
         kind == idl.LinkedNodeKind.setOrMapLiteral ||
         kind == idl.LinkedNodeKind.simpleIdentifier ||
-        kind == idl.LinkedNodeKind.simpleStringLiteral ||
-        kind == idl.LinkedNodeKind.stringInterpolation ||
         kind == idl.LinkedNodeKind.superExpression ||
         kind == idl.LinkedNodeKind.symbolLiteral ||
         kind == idl.LinkedNodeKind.thisExpression ||
@@ -15720,6 +11415,53 @@
   }
 
   @override
+  int get flags {
+    _flags ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 18, 0);
+    return _flags;
+  }
+
+  @override
+  String get importDirective_prefix {
+    assert(kind == idl.LinkedNodeKind.importDirective);
+    _variantField_1 ??=
+        const fb.StringReader().vTableGet(_bc, _bcOffset, 1, '');
+    return _variantField_1;
+  }
+
+  @override
+  int get integerLiteral_value {
+    assert(kind == idl.LinkedNodeKind.integerLiteral);
+    _variantField_16 ??=
+        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 16, 0);
+    return _variantField_16;
+  }
+
+  @override
+  int get nameOffset {
+    assert(kind == idl.LinkedNodeKind.classDeclaration ||
+        kind == idl.LinkedNodeKind.classTypeAlias ||
+        kind == idl.LinkedNodeKind.constructorDeclaration ||
+        kind == idl.LinkedNodeKind.enumConstantDeclaration ||
+        kind == idl.LinkedNodeKind.enumDeclaration ||
+        kind == idl.LinkedNodeKind.exportDirective ||
+        kind == idl.LinkedNodeKind.fieldFormalParameter ||
+        kind == idl.LinkedNodeKind.functionDeclaration ||
+        kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
+        kind == idl.LinkedNodeKind.functionTypeAlias ||
+        kind == idl.LinkedNodeKind.genericTypeAlias ||
+        kind == idl.LinkedNodeKind.importDirective ||
+        kind == idl.LinkedNodeKind.methodDeclaration ||
+        kind == idl.LinkedNodeKind.mixinDeclaration ||
+        kind == idl.LinkedNodeKind.partDirective ||
+        kind == idl.LinkedNodeKind.simpleFormalParameter ||
+        kind == idl.LinkedNodeKind.typeParameter ||
+        kind == idl.LinkedNodeKind.variableDeclaration);
+    _variantField_16 ??=
+        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 16, 0);
+    return _variantField_16;
+  }
+
+  @override
   String get interpolationString_value {
     assert(kind == idl.LinkedNodeKind.interpolationString);
     _variantField_30 ??=
@@ -15737,20 +11479,6 @@
   }
 
   @override
-  idl.LinkedNode get namedCompilationUnitMember_name {
-    assert(kind == idl.LinkedNodeKind.classDeclaration ||
-        kind == idl.LinkedNodeKind.classTypeAlias ||
-        kind == idl.LinkedNodeKind.enumDeclaration ||
-        kind == idl.LinkedNodeKind.functionDeclaration ||
-        kind == idl.LinkedNodeKind.functionTypeAlias ||
-        kind == idl.LinkedNodeKind.genericTypeAlias ||
-        kind == idl.LinkedNodeKind.mixinDeclaration);
-    _variantField_14 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 14, null);
-    return _variantField_14;
-  }
-
-  @override
   idl.LinkedNode get normalFormalParameter_comment {
     assert(kind == idl.LinkedNodeKind.fieldFormalParameter ||
         kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
@@ -15761,15 +11489,6 @@
   }
 
   @override
-  idl.LinkedNode get typedLiteral_typeArguments {
-    assert(kind == idl.LinkedNodeKind.listLiteral ||
-        kind == idl.LinkedNodeKind.setOrMapLiteral);
-    _variantField_14 ??=
-        const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 14, null);
-    return _variantField_14;
-  }
-
-  @override
   idl.LinkedNode get uriBasedDirective_uri {
     assert(kind == idl.LinkedNodeKind.exportDirective ||
         kind == idl.LinkedNodeKind.importDirective ||
@@ -15780,12 +11499,6 @@
   }
 
   @override
-  bool get isSynthetic {
-    _isSynthetic ??= const fb.BoolReader().vTableGet(_bc, _bcOffset, 1, false);
-    return _isSynthetic;
-  }
-
-  @override
   idl.LinkedNodeKind get kind {
     _kind ??= const _LinkedNodeKindReader()
         .vTableGet(_bc, _bcOffset, 0, idl.LinkedNodeKind.adjacentStrings);
@@ -15793,11 +11506,9 @@
   }
 
   @override
-  List<String> get mixinDeclaration_superInvokedNames {
-    assert(kind == idl.LinkedNodeKind.mixinDeclaration);
-    _variantField_36 ??= const fb.ListReader<String>(const fb.StringReader())
-        .vTableGet(_bc, _bcOffset, 36, const <String>[]);
-    return _variantField_36;
+  String get name {
+    _name ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 37, '');
+    return _name;
   }
 
   @override
@@ -15818,14 +11529,6 @@
   }
 
   @override
-  bool get setOrMapLiteral_isSet {
-    assert(kind == idl.LinkedNodeKind.setOrMapLiteral);
-    _variantField_31 ??=
-        const fb.BoolReader().vTableGet(_bc, _bcOffset, 31, false);
-    return _variantField_31;
-  }
-
-  @override
   bool get simplyBoundable_isSimplyBounded {
     assert(kind == idl.LinkedNodeKind.classDeclaration ||
         kind == idl.LinkedNodeKind.classTypeAlias ||
@@ -15838,6 +11541,14 @@
   }
 
   @override
+  idl.UnlinkedTokenType get spreadElement_spreadOperator {
+    assert(kind == idl.LinkedNodeKind.spreadElement);
+    _variantField_38 ??= const _UnlinkedTokenTypeReader()
+        .vTableGet(_bc, _bcOffset, 38, idl.UnlinkedTokenType.NOTHING);
+    return _variantField_38;
+  }
+
+  @override
   idl.TopLevelInferenceError get topLevelTypeInferenceError {
     assert(kind == idl.LinkedNodeKind.simpleFormalParameter ||
         kind == idl.LinkedNodeKind.variableDeclaration);
@@ -15857,6 +11568,16 @@
   }
 
   @override
+  int get uriBasedDirective_uriElement {
+    assert(kind == idl.LinkedNodeKind.exportDirective ||
+        kind == idl.LinkedNodeKind.importDirective ||
+        kind == idl.LinkedNodeKind.partDirective);
+    _variantField_19 ??=
+        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 19, 0);
+    return _variantField_19;
+  }
+
+  @override
   idl.LinkedNodeVariablesDeclaration get variableDeclaration_declaration {
     assert(kind == idl.LinkedNodeKind.variableDeclaration);
     _variantField_32 ??= const _LinkedNodeVariablesDeclarationReader()
@@ -15869,9 +11590,10 @@
   @override
   Map<String, Object> toJson() {
     Map<String, Object> _result = <String, Object>{};
-    if (isSynthetic != false) _result["isSynthetic"] = isSynthetic;
+    if (flags != 0) _result["flags"] = flags;
     if (kind != idl.LinkedNodeKind.adjacentStrings)
       _result["kind"] = kind.toString().split('.')[1];
+    if (name != '') _result["name"] = name;
     if (kind == idl.LinkedNodeKind.functionDeclaration) {
       if (actualReturnType != null)
         _result["actualReturnType"] = actualReturnType.toJson();
@@ -15883,20 +11605,12 @@
       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 (nameOffset != 0) _result["nameOffset"] = nameOffset;
     }
     if (kind == idl.LinkedNodeKind.functionExpression) {
       if (actualReturnType != null)
@@ -15927,17 +11641,11 @@
       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 (typeAlias_hasSelfReference != false)
         _result["typeAlias_hasSelfReference"] = typeAlias_hasSelfReference;
       if (codeLength != 0) _result["codeLength"] = codeLength;
       if (codeOffset != 0) _result["codeOffset"] = codeOffset;
-      if (namedCompilationUnitMember_name != null)
-        _result["namedCompilationUnitMember_name"] =
-            namedCompilationUnitMember_name.toJson();
+      if (nameOffset != 0) _result["nameOffset"] = nameOffset;
       if (simplyBoundable_isSimplyBounded != false)
         _result["simplyBoundable_isSimplyBounded"] =
             simplyBoundable_isSimplyBounded;
@@ -15948,9 +11656,6 @@
       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();
@@ -15959,8 +11664,6 @@
       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();
     }
@@ -15974,34 +11677,18 @@
             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_operatorKeyword != 0)
-        _result["methodDeclaration_operatorKeyword"] =
-            methodDeclaration_operatorKeyword;
       if (methodDeclaration_returnType != null)
         _result["methodDeclaration_returnType"] =
             methodDeclaration_returnType.toJson();
-      if (methodDeclaration_modifierKeyword != 0)
-        _result["methodDeclaration_modifierKeyword"] =
-            methodDeclaration_modifierKeyword;
-      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 (nameOffset != 0) _result["nameOffset"] = nameOffset;
     }
     if (kind == idl.LinkedNodeKind.fieldFormalParameter) {
       if (actualType != null) _result["actualType"] = actualType.toJson();
@@ -16013,32 +11700,17 @@
       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_thisKeyword != 0)
-        _result["fieldFormalParameter_thisKeyword"] =
-            fieldFormalParameter_thisKeyword;
       if (fieldFormalParameter_formalParameters != null)
         _result["fieldFormalParameter_formalParameters"] =
             fieldFormalParameter_formalParameters.toJson();
-      if (fieldFormalParameter_period != 0)
-        _result["fieldFormalParameter_period"] = fieldFormalParameter_period;
-      if (normalFormalParameter_requiredKeyword != 0)
-        _result["normalFormalParameter_requiredKeyword"] =
-            normalFormalParameter_requiredKeyword;
-      if (normalFormalParameter_covariantKeyword != 0)
-        _result["normalFormalParameter_covariantKeyword"] =
-            normalFormalParameter_covariantKeyword;
       if (inheritsCovariant != false)
         _result["inheritsCovariant"] = inheritsCovariant;
-      if (normalFormalParameter_identifier != null)
-        _result["normalFormalParameter_identifier"] =
-            normalFormalParameter_identifier.toJson();
       if (codeLength != 0) _result["codeLength"] = codeLength;
       if (codeOffset != 0) _result["codeOffset"] = codeOffset;
+      if (nameOffset != 0) _result["nameOffset"] = nameOffset;
       if (normalFormalParameter_comment != null)
         _result["normalFormalParameter_comment"] =
             normalFormalParameter_comment.toJson();
@@ -16059,19 +11731,11 @@
       if (functionTypedFormalParameter_typeParameters != null)
         _result["functionTypedFormalParameter_typeParameters"] =
             functionTypedFormalParameter_typeParameters.toJson();
-      if (normalFormalParameter_requiredKeyword != 0)
-        _result["normalFormalParameter_requiredKeyword"] =
-            normalFormalParameter_requiredKeyword;
-      if (normalFormalParameter_covariantKeyword != 0)
-        _result["normalFormalParameter_covariantKeyword"] =
-            normalFormalParameter_covariantKeyword;
       if (inheritsCovariant != false)
         _result["inheritsCovariant"] = inheritsCovariant;
-      if (normalFormalParameter_identifier != null)
-        _result["normalFormalParameter_identifier"] =
-            normalFormalParameter_identifier.toJson();
       if (codeLength != 0) _result["codeLength"] = codeLength;
       if (codeOffset != 0) _result["codeOffset"] = codeOffset;
+      if (nameOffset != 0) _result["nameOffset"] = nameOffset;
       if (normalFormalParameter_comment != null)
         _result["normalFormalParameter_comment"] =
             normalFormalParameter_comment.toJson();
@@ -16086,22 +11750,11 @@
       if (simpleFormalParameter_type != null)
         _result["simpleFormalParameter_type"] =
             simpleFormalParameter_type.toJson();
-      if (simpleFormalParameter_keyword != 0)
-        _result["simpleFormalParameter_keyword"] =
-            simpleFormalParameter_keyword;
-      if (normalFormalParameter_requiredKeyword != 0)
-        _result["normalFormalParameter_requiredKeyword"] =
-            normalFormalParameter_requiredKeyword;
-      if (normalFormalParameter_covariantKeyword != 0)
-        _result["normalFormalParameter_covariantKeyword"] =
-            normalFormalParameter_covariantKeyword;
       if (inheritsCovariant != false)
         _result["inheritsCovariant"] = inheritsCovariant;
-      if (normalFormalParameter_identifier != null)
-        _result["normalFormalParameter_identifier"] =
-            normalFormalParameter_identifier.toJson();
       if (codeLength != 0) _result["codeLength"] = codeLength;
       if (codeOffset != 0) _result["codeOffset"] = codeOffset;
+      if (nameOffset != 0) _result["nameOffset"] = nameOffset;
       if (normalFormalParameter_comment != null)
         _result["normalFormalParameter_comment"] =
             normalFormalParameter_comment.toJson();
@@ -16119,14 +11772,11 @@
       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 (inheritsCovariant != false)
         _result["inheritsCovariant"] = inheritsCovariant;
       if (codeLength != 0) _result["codeLength"] = codeLength;
       if (codeOffset != 0) _result["codeOffset"] = codeOffset;
+      if (nameOffset != 0) _result["nameOffset"] = nameOffset;
       if (topLevelTypeInferenceError != null)
         _result["topLevelTypeInferenceError"] =
             topLevelTypeInferenceError.toJson();
@@ -16141,16 +11791,17 @@
       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_elementType != null)
         _result["binaryExpression_elementType"] =
             binaryExpression_elementType.toJson();
-      if (binaryExpression_operator != 0)
-        _result["binaryExpression_operator"] = binaryExpression_operator;
+      if (binaryExpression_element != 0)
+        _result["binaryExpression_element"] = binaryExpression_element;
+      if (binaryExpression_operator != idl.UnlinkedTokenType.NOTHING)
+        _result["binaryExpression_operator"] =
+            binaryExpression_operator.toString().split('.')[1];
       if (expression_type != null)
         _result["expression_type"] = expression_type.toJson();
     }
@@ -16177,8 +11828,6 @@
       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)
@@ -16194,27 +11843,16 @@
       if (adjacentStrings_strings.isNotEmpty)
         _result["adjacentStrings_strings"] =
             adjacentStrings_strings.map((_value) => _value.toJson()).toList();
-      if (expression_type != null)
-        _result["expression_type"] = expression_type.toJson();
     }
     if (kind == idl.LinkedNodeKind.argumentList) {
       if (argumentList_arguments.isNotEmpty)
         _result["argumentList_arguments"] =
             argumentList_arguments.map((_value) => _value.toJson()).toList();
-      if (argumentList_leftParenthesis != 0)
-        _result["argumentList_leftParenthesis"] = argumentList_leftParenthesis;
-      if (argumentList_rightParenthesis != 0)
-        _result["argumentList_rightParenthesis"] =
-            argumentList_rightParenthesis;
     }
     if (kind == idl.LinkedNodeKind.block) {
       if (block_statements.isNotEmpty)
         _result["block_statements"] =
             block_statements.map((_value) => _value.toJson()).toList();
-      if (block_leftBracket != 0)
-        _result["block_leftBracket"] = block_leftBracket;
-      if (block_rightBracket != 0)
-        _result["block_rightBracket"] = block_rightBracket;
     }
     if (kind == idl.LinkedNodeKind.cascadeExpression) {
       if (cascadeExpression_sections.isNotEmpty)
@@ -16242,10 +11880,6 @@
       if (compilationUnit_scriptTag != null)
         _result["compilationUnit_scriptTag"] =
             compilationUnit_scriptTag.toJson();
-      if (compilationUnit_beginToken != 0)
-        _result["compilationUnit_beginToken"] = compilationUnit_beginToken;
-      if (compilationUnit_endToken != 0)
-        _result["compilationUnit_endToken"] = compilationUnit_endToken;
       if (codeLength != 0) _result["codeLength"] = codeLength;
       if (codeOffset != 0) _result["codeOffset"] = codeOffset;
       if (compilationUnit_directives.isNotEmpty)
@@ -16267,27 +11901,9 @@
       if (constructorDeclaration_body != null)
         _result["constructorDeclaration_body"] =
             constructorDeclaration_body.toJson();
-      if (constructorDeclaration_constKeyword != 0)
-        _result["constructorDeclaration_constKeyword"] =
-            constructorDeclaration_constKeyword;
-      if (constructorDeclaration_name != null)
-        _result["constructorDeclaration_name"] =
-            constructorDeclaration_name.toJson();
-      if (constructorDeclaration_factoryKeyword != 0)
-        _result["constructorDeclaration_factoryKeyword"] =
-            constructorDeclaration_factoryKeyword;
       if (constructorDeclaration_parameters != null)
         _result["constructorDeclaration_parameters"] =
             constructorDeclaration_parameters.toJson();
-      if (constructorDeclaration_externalKeyword != 0)
-        _result["constructorDeclaration_externalKeyword"] =
-            constructorDeclaration_externalKeyword;
-      if (constructorDeclaration_period != 0)
-        _result["constructorDeclaration_period"] =
-            constructorDeclaration_period;
-      if (constructorDeclaration_separator != 0)
-        _result["constructorDeclaration_separator"] =
-            constructorDeclaration_separator;
       if (constructorDeclaration_redirectedConstructor != null)
         _result["constructorDeclaration_redirectedConstructor"] =
             constructorDeclaration_redirectedConstructor.toJson();
@@ -16296,6 +11912,7 @@
       if (constructorDeclaration_returnType != null)
         _result["constructorDeclaration_returnType"] =
             constructorDeclaration_returnType.toJson();
+      if (nameOffset != 0) _result["nameOffset"] = nameOffset;
     }
     if (kind == idl.LinkedNodeKind.dottedName) {
       if (dottedName_components.isNotEmpty)
@@ -16311,17 +11928,9 @@
       if (annotatedNode_metadata.isNotEmpty)
         _result["annotatedNode_metadata"] =
             annotatedNode_metadata.map((_value) => _value.toJson()).toList();
-      if (enumDeclaration_enumKeyword != 0)
-        _result["enumDeclaration_enumKeyword"] = enumDeclaration_enumKeyword;
-      if (enumDeclaration_rightBracket != 0)
-        _result["enumDeclaration_rightBracket"] = enumDeclaration_rightBracket;
-      if (enumDeclaration_leftBracket != 0)
-        _result["enumDeclaration_leftBracket"] = enumDeclaration_leftBracket;
       if (codeLength != 0) _result["codeLength"] = codeLength;
       if (codeOffset != 0) _result["codeOffset"] = codeOffset;
-      if (namedCompilationUnitMember_name != null)
-        _result["namedCompilationUnitMember_name"] =
-            namedCompilationUnitMember_name.toJson();
+      if (nameOffset != 0) _result["nameOffset"] = nameOffset;
     }
     if (kind == idl.LinkedNodeKind.formalParameterList) {
       if (formalParameterList_parameters.isNotEmpty)
@@ -16329,35 +11938,27 @@
             formalParameterList_parameters
                 .map((_value) => _value.toJson())
                 .toList();
-      if (formalParameterList_leftDelimiter != 0)
-        _result["formalParameterList_leftDelimiter"] =
-            formalParameterList_leftDelimiter;
-      if (formalParameterList_rightDelimiter != 0)
-        _result["formalParameterList_rightDelimiter"] =
-            formalParameterList_rightDelimiter;
-      if (formalParameterList_leftParenthesis != 0)
-        _result["formalParameterList_leftParenthesis"] =
-            formalParameterList_leftParenthesis;
-      if (formalParameterList_rightParenthesis != 0)
-        _result["formalParameterList_rightParenthesis"] =
-            formalParameterList_rightParenthesis;
-    }
-    if (kind == idl.LinkedNodeKind.hideCombinator) {
-      if (hideCombinator_hiddenNames.isNotEmpty)
-        _result["hideCombinator_hiddenNames"] = hideCombinator_hiddenNames
-            .map((_value) => _value.toJson())
-            .toList();
-      if (combinator_keyword != 0)
-        _result["combinator_keyword"] = combinator_keyword;
     }
     if (kind == idl.LinkedNodeKind.implementsClause) {
       if (implementsClause_interfaces.isNotEmpty)
         _result["implementsClause_interfaces"] = implementsClause_interfaces
             .map((_value) => _value.toJson())
             .toList();
-      if (implementsClause_implementsKeyword != 0)
-        _result["implementsClause_implementsKeyword"] =
-            implementsClause_implementsKeyword;
+    }
+    if (kind == idl.LinkedNodeKind.instanceCreationExpression) {
+      if (instanceCreationExpression_arguments.isNotEmpty)
+        _result["instanceCreationExpression_arguments"] =
+            instanceCreationExpression_arguments
+                .map((_value) => _value.toJson())
+                .toList();
+      if (instanceCreationExpression_constructorName != null)
+        _result["instanceCreationExpression_constructorName"] =
+            instanceCreationExpression_constructorName.toJson();
+      if (instanceCreationExpression_typeArguments != null)
+        _result["instanceCreationExpression_typeArguments"] =
+            instanceCreationExpression_typeArguments.toJson();
+      if (expression_type != null)
+        _result["expression_type"] = expression_type.toJson();
     }
     if (kind == idl.LinkedNodeKind.labeledStatement) {
       if (labeledStatement_labels.isNotEmpty)
@@ -16373,22 +11974,6 @@
             .map((_value) => _value.toJson())
             .toList();
     }
-    if (kind == idl.LinkedNodeKind.listLiteral) {
-      if (listLiteral_elements.isNotEmpty)
-        _result["listLiteral_elements"] =
-            listLiteral_elements.map((_value) => _value.toJson()).toList();
-      if (listLiteral_leftBracket != 0)
-        _result["listLiteral_leftBracket"] = listLiteral_leftBracket;
-      if (listLiteral_rightBracket != 0)
-        _result["listLiteral_rightBracket"] = listLiteral_rightBracket;
-      if (typedLiteral_constKeyword != 0)
-        _result["typedLiteral_constKeyword"] = typedLiteral_constKeyword;
-      if (expression_type != null)
-        _result["expression_type"] = expression_type.toJson();
-      if (typedLiteral_typeArguments != null)
-        _result["typedLiteral_typeArguments"] =
-            typedLiteral_typeArguments.toJson();
-    }
     if (kind == idl.LinkedNodeKind.exportDirective) {
       if (namespaceDirective_combinators.isNotEmpty)
         _result["namespaceDirective_combinators"] =
@@ -16400,17 +11985,12 @@
       if (annotatedNode_metadata.isNotEmpty)
         _result["annotatedNode_metadata"] =
             annotatedNode_metadata.map((_value) => _value.toJson()).toList();
-      if (directive_keyword != 0)
-        _result["directive_keyword"] = directive_keyword;
-      if (uriBasedDirective_uriElement != 0)
-        _result["uriBasedDirective_uriElement"] = uriBasedDirective_uriElement;
-      if (directive_semicolon != 0)
-        _result["directive_semicolon"] = directive_semicolon;
       if (namespaceDirective_configurations.isNotEmpty)
         _result["namespaceDirective_configurations"] =
             namespaceDirective_configurations
                 .map((_value) => _value.toJson())
                 .toList();
+      if (nameOffset != 0) _result["nameOffset"] = nameOffset;
       if (uriBasedDirective_uri != null)
         _result["uriBasedDirective_uri"] = uriBasedDirective_uri.toJson();
       if (namespaceDirective_selectedUri != '')
@@ -16418,6 +11998,8 @@
             namespaceDirective_selectedUri;
       if (uriBasedDirective_uriContent != '')
         _result["uriBasedDirective_uriContent"] = uriBasedDirective_uriContent;
+      if (uriBasedDirective_uriElement != 0)
+        _result["uriBasedDirective_uriElement"] = uriBasedDirective_uriElement;
     }
     if (kind == idl.LinkedNodeKind.importDirective) {
       if (namespaceDirective_combinators.isNotEmpty)
@@ -16430,24 +12012,16 @@
       if (annotatedNode_metadata.isNotEmpty)
         _result["annotatedNode_metadata"] =
             annotatedNode_metadata.map((_value) => _value.toJson()).toList();
-      if (importDirective_prefix != null)
-        _result["importDirective_prefix"] = importDirective_prefix.toJson();
-      if (importDirective_asKeyword != 0)
-        _result["importDirective_asKeyword"] = importDirective_asKeyword;
-      if (importDirective_deferredKeyword != 0)
-        _result["importDirective_deferredKeyword"] =
-            importDirective_deferredKeyword;
-      if (directive_keyword != 0)
-        _result["directive_keyword"] = directive_keyword;
-      if (uriBasedDirective_uriElement != 0)
-        _result["uriBasedDirective_uriElement"] = uriBasedDirective_uriElement;
-      if (directive_semicolon != 0)
-        _result["directive_semicolon"] = directive_semicolon;
+      if (importDirective_prefixOffset != 0)
+        _result["importDirective_prefixOffset"] = importDirective_prefixOffset;
       if (namespaceDirective_configurations.isNotEmpty)
         _result["namespaceDirective_configurations"] =
             namespaceDirective_configurations
                 .map((_value) => _value.toJson())
                 .toList();
+      if (importDirective_prefix != '')
+        _result["importDirective_prefix"] = importDirective_prefix;
+      if (nameOffset != 0) _result["nameOffset"] = nameOffset;
       if (uriBasedDirective_uri != null)
         _result["uriBasedDirective_uri"] = uriBasedDirective_uri.toJson();
       if (namespaceDirective_selectedUri != '')
@@ -16455,6 +12029,8 @@
             namespaceDirective_selectedUri;
       if (uriBasedDirective_uriContent != '')
         _result["uriBasedDirective_uriContent"] = uriBasedDirective_uriContent;
+      if (uriBasedDirective_uriElement != 0)
+        _result["uriBasedDirective_uriElement"] = uriBasedDirective_uriElement;
     }
     if (kind == idl.LinkedNodeKind.onClause) {
       if (onClause_superclassConstraints.isNotEmpty)
@@ -16462,64 +12038,20 @@
             onClause_superclassConstraints
                 .map((_value) => _value.toJson())
                 .toList();
-      if (onClause_onKeyword != 0)
-        _result["onClause_onKeyword"] = onClause_onKeyword;
-    }
-    if (kind == idl.LinkedNodeKind.setOrMapLiteral) {
-      if (setOrMapLiteral_elements.isNotEmpty)
-        _result["setOrMapLiteral_elements"] =
-            setOrMapLiteral_elements.map((_value) => _value.toJson()).toList();
-      if (setOrMapLiteral_leftBracket != 0)
-        _result["setOrMapLiteral_leftBracket"] = setOrMapLiteral_leftBracket;
-      if (setOrMapLiteral_rightBracket != 0)
-        _result["setOrMapLiteral_rightBracket"] = setOrMapLiteral_rightBracket;
-      if (typedLiteral_constKeyword != 0)
-        _result["typedLiteral_constKeyword"] = typedLiteral_constKeyword;
-      if (setOrMapLiteral_isMap != false)
-        _result["setOrMapLiteral_isMap"] = setOrMapLiteral_isMap;
-      if (expression_type != null)
-        _result["expression_type"] = expression_type.toJson();
-      if (typedLiteral_typeArguments != null)
-        _result["typedLiteral_typeArguments"] =
-            typedLiteral_typeArguments.toJson();
-      if (setOrMapLiteral_isSet != false)
-        _result["setOrMapLiteral_isSet"] = setOrMapLiteral_isSet;
-    }
-    if (kind == idl.LinkedNodeKind.showCombinator) {
-      if (showCombinator_shownNames.isNotEmpty)
-        _result["showCombinator_shownNames"] =
-            showCombinator_shownNames.map((_value) => _value.toJson()).toList();
-      if (combinator_keyword != 0)
-        _result["combinator_keyword"] = combinator_keyword;
     }
     if (kind == idl.LinkedNodeKind.stringInterpolation) {
       if (stringInterpolation_elements.isNotEmpty)
         _result["stringInterpolation_elements"] = stringInterpolation_elements
             .map((_value) => _value.toJson())
             .toList();
-      if (expression_type != null)
-        _result["expression_type"] = expression_type.toJson();
     }
     if (kind == idl.LinkedNodeKind.switchStatement) {
       if (switchStatement_members.isNotEmpty)
         _result["switchStatement_members"] =
             switchStatement_members.map((_value) => _value.toJson()).toList();
-      if (switchStatement_leftParenthesis != 0)
-        _result["switchStatement_leftParenthesis"] =
-            switchStatement_leftParenthesis;
       if (switchStatement_expression != null)
         _result["switchStatement_expression"] =
             switchStatement_expression.toJson();
-      if (switchStatement_switchKeyword != 0)
-        _result["switchStatement_switchKeyword"] =
-            switchStatement_switchKeyword;
-      if (switchStatement_rightParenthesis != 0)
-        _result["switchStatement_rightParenthesis"] =
-            switchStatement_rightParenthesis;
-      if (switchStatement_leftBracket != 0)
-        _result["switchStatement_leftBracket"] = switchStatement_leftBracket;
-      if (switchStatement_rightBracket != 0)
-        _result["switchStatement_rightBracket"] = switchStatement_rightBracket;
     }
     if (kind == idl.LinkedNodeKind.tryStatement) {
       if (tryStatement_catchClauses.isNotEmpty)
@@ -16527,24 +12059,46 @@
             tryStatement_catchClauses.map((_value) => _value.toJson()).toList();
       if (tryStatement_body != null)
         _result["tryStatement_body"] = tryStatement_body.toJson();
-      if (tryStatement_finallyKeyword != 0)
-        _result["tryStatement_finallyKeyword"] = tryStatement_finallyKeyword;
       if (tryStatement_finallyBlock != null)
         _result["tryStatement_finallyBlock"] =
             tryStatement_finallyBlock.toJson();
-      if (tryStatement_tryKeyword != 0)
-        _result["tryStatement_tryKeyword"] = tryStatement_tryKeyword;
     }
     if (kind == idl.LinkedNodeKind.typeArgumentList) {
       if (typeArgumentList_arguments.isNotEmpty)
         _result["typeArgumentList_arguments"] = typeArgumentList_arguments
             .map((_value) => _value.toJson())
             .toList();
-      if (typeArgumentList_leftBracket != 0)
-        _result["typeArgumentList_leftBracket"] = typeArgumentList_leftBracket;
-      if (typeArgumentList_rightBracket != 0)
-        _result["typeArgumentList_rightBracket"] =
-            typeArgumentList_rightBracket;
+    }
+    if (kind == idl.LinkedNodeKind.listLiteral) {
+      if (typedLiteral_typeArguments.isNotEmpty)
+        _result["typedLiteral_typeArguments"] = typedLiteral_typeArguments
+            .map((_value) => _value.toJson())
+            .toList();
+      if (listLiteral_elements.isNotEmpty)
+        _result["listLiteral_elements"] =
+            listLiteral_elements.map((_value) => _value.toJson()).toList();
+      if (expression_type != null)
+        _result["expression_type"] = expression_type.toJson();
+    }
+    if (kind == idl.LinkedNodeKind.setOrMapLiteral) {
+      if (typedLiteral_typeArguments.isNotEmpty)
+        _result["typedLiteral_typeArguments"] = typedLiteral_typeArguments
+            .map((_value) => _value.toJson())
+            .toList();
+      if (setOrMapLiteral_elements.isNotEmpty)
+        _result["setOrMapLiteral_elements"] =
+            setOrMapLiteral_elements.map((_value) => _value.toJson()).toList();
+      if (expression_type != null)
+        _result["expression_type"] = expression_type.toJson();
+    }
+    if (kind == idl.LinkedNodeKind.typeName) {
+      if (typeName_typeArguments.isNotEmpty)
+        _result["typeName_typeArguments"] =
+            typeName_typeArguments.map((_value) => _value.toJson()).toList();
+      if (typeName_name != null)
+        _result["typeName_name"] = typeName_name.toJson();
+      if (typeName_type != null)
+        _result["typeName_type"] = typeName_type.toJson();
     }
     if (kind == idl.LinkedNodeKind.typeParameterList) {
       if (typeParameterList_typeParameters.isNotEmpty)
@@ -16552,12 +12106,6 @@
             typeParameterList_typeParameters
                 .map((_value) => _value.toJson())
                 .toList();
-      if (typeParameterList_leftBracket != 0)
-        _result["typeParameterList_leftBracket"] =
-            typeParameterList_leftBracket;
-      if (typeParameterList_rightBracket != 0)
-        _result["typeParameterList_rightBracket"] =
-            typeParameterList_rightBracket;
     }
     if (kind == idl.LinkedNodeKind.variableDeclarationList) {
       if (variableDeclarationList_variables.isNotEmpty)
@@ -16573,19 +12121,11 @@
       if (variableDeclarationList_type != null)
         _result["variableDeclarationList_type"] =
             variableDeclarationList_type.toJson();
-      if (variableDeclarationList_keyword != 0)
-        _result["variableDeclarationList_keyword"] =
-            variableDeclarationList_keyword;
-      if (variableDeclarationList_lateKeyword != 0)
-        _result["variableDeclarationList_lateKeyword"] =
-            variableDeclarationList_lateKeyword;
     }
     if (kind == idl.LinkedNodeKind.withClause) {
       if (withClause_mixinTypes.isNotEmpty)
         _result["withClause_mixinTypes"] =
             withClause_mixinTypes.map((_value) => _value.toJson()).toList();
-      if (withClause_withKeyword != 0)
-        _result["withClause_withKeyword"] = withClause_withKeyword;
     }
     if (kind == idl.LinkedNodeKind.classDeclaration) {
       if (annotatedNode_comment != null)
@@ -16596,24 +12136,12 @@
       if (classDeclaration_extendsClause != null)
         _result["classDeclaration_extendsClause"] =
             classDeclaration_extendsClause.toJson();
-      if (classDeclaration_abstractKeyword != 0)
-        _result["classDeclaration_abstractKeyword"] =
-            classDeclaration_abstractKeyword;
       if (classDeclaration_withClause != null)
         _result["classDeclaration_withClause"] =
             classDeclaration_withClause.toJson();
       if (classDeclaration_nativeClause != null)
         _result["classDeclaration_nativeClause"] =
             classDeclaration_nativeClause.toJson();
-      if (classDeclaration_classKeyword != 0)
-        _result["classDeclaration_classKeyword"] =
-            classDeclaration_classKeyword;
-      if (classOrMixinDeclaration_rightBracket != 0)
-        _result["classOrMixinDeclaration_rightBracket"] =
-            classOrMixinDeclaration_rightBracket;
-      if (classOrMixinDeclaration_leftBracket != 0)
-        _result["classOrMixinDeclaration_leftBracket"] =
-            classOrMixinDeclaration_leftBracket;
       if (classDeclaration_isDartObject != false)
         _result["classDeclaration_isDartObject"] =
             classDeclaration_isDartObject;
@@ -16630,9 +12158,7 @@
             classOrMixinDeclaration_typeParameters.toJson();
       if (codeLength != 0) _result["codeLength"] = codeLength;
       if (codeOffset != 0) _result["codeOffset"] = codeOffset;
-      if (namedCompilationUnitMember_name != null)
-        _result["namedCompilationUnitMember_name"] =
-            namedCompilationUnitMember_name.toJson();
+      if (nameOffset != 0) _result["nameOffset"] = nameOffset;
       if (simplyBoundable_isSimplyBounded != false)
         _result["simplyBoundable_isSimplyBounded"] =
             simplyBoundable_isSimplyBounded;
@@ -16646,29 +12172,18 @@
       if (classTypeAlias_typeParameters != null)
         _result["classTypeAlias_typeParameters"] =
             classTypeAlias_typeParameters.toJson();
-      if (classTypeAlias_abstractKeyword != 0)
-        _result["classTypeAlias_abstractKeyword"] =
-            classTypeAlias_abstractKeyword;
       if (classTypeAlias_superclass != null)
         _result["classTypeAlias_superclass"] =
             classTypeAlias_superclass.toJson();
       if (classTypeAlias_withClause != null)
         _result["classTypeAlias_withClause"] =
             classTypeAlias_withClause.toJson();
-      if (classTypeAlias_equals != 0)
-        _result["classTypeAlias_equals"] = classTypeAlias_equals;
-      if (typeAlias_typedefKeyword != 0)
-        _result["typeAlias_typedefKeyword"] = typeAlias_typedefKeyword;
-      if (typeAlias_semicolon != 0)
-        _result["typeAlias_semicolon"] = typeAlias_semicolon;
       if (classTypeAlias_implementsClause != null)
         _result["classTypeAlias_implementsClause"] =
             classTypeAlias_implementsClause.toJson();
       if (codeLength != 0) _result["codeLength"] = codeLength;
       if (codeOffset != 0) _result["codeOffset"] = codeOffset;
-      if (namedCompilationUnitMember_name != null)
-        _result["namedCompilationUnitMember_name"] =
-            namedCompilationUnitMember_name.toJson();
+      if (nameOffset != 0) _result["nameOffset"] = nameOffset;
       if (simplyBoundable_isSimplyBounded != false)
         _result["simplyBoundable_isSimplyBounded"] =
             simplyBoundable_isSimplyBounded;
@@ -16682,8 +12197,6 @@
       if (declaredIdentifier_identifier != null)
         _result["declaredIdentifier_identifier"] =
             declaredIdentifier_identifier.toJson();
-      if (declaredIdentifier_keyword != 0)
-        _result["declaredIdentifier_keyword"] = declaredIdentifier_keyword;
       if (declaredIdentifier_type != null)
         _result["declaredIdentifier_type"] = declaredIdentifier_type.toJson();
     }
@@ -16693,9 +12206,7 @@
       if (annotatedNode_metadata.isNotEmpty)
         _result["annotatedNode_metadata"] =
             annotatedNode_metadata.map((_value) => _value.toJson()).toList();
-      if (enumConstantDeclaration_name != null)
-        _result["enumConstantDeclaration_name"] =
-            enumConstantDeclaration_name.toJson();
+      if (nameOffset != 0) _result["nameOffset"] = nameOffset;
     }
     if (kind == idl.LinkedNodeKind.fieldDeclaration) {
       if (annotatedNode_comment != null)
@@ -16705,14 +12216,6 @@
             annotatedNode_metadata.map((_value) => _value.toJson()).toList();
       if (fieldDeclaration_fields != null)
         _result["fieldDeclaration_fields"] = fieldDeclaration_fields.toJson();
-      if (fieldDeclaration_covariantKeyword != 0)
-        _result["fieldDeclaration_covariantKeyword"] =
-            fieldDeclaration_covariantKeyword;
-      if (fieldDeclaration_staticKeyword != 0)
-        _result["fieldDeclaration_staticKeyword"] =
-            fieldDeclaration_staticKeyword;
-      if (fieldDeclaration_semicolon != 0)
-        _result["fieldDeclaration_semicolon"] = fieldDeclaration_semicolon;
     }
     if (kind == idl.LinkedNodeKind.genericTypeAlias) {
       if (annotatedNode_comment != null)
@@ -16726,19 +12229,11 @@
       if (genericTypeAlias_functionType != null)
         _result["genericTypeAlias_functionType"] =
             genericTypeAlias_functionType.toJson();
-      if (genericTypeAlias_equals != 0)
-        _result["genericTypeAlias_equals"] = genericTypeAlias_equals;
-      if (typeAlias_typedefKeyword != 0)
-        _result["typeAlias_typedefKeyword"] = typeAlias_typedefKeyword;
-      if (typeAlias_semicolon != 0)
-        _result["typeAlias_semicolon"] = typeAlias_semicolon;
       if (typeAlias_hasSelfReference != false)
         _result["typeAlias_hasSelfReference"] = typeAlias_hasSelfReference;
       if (codeLength != 0) _result["codeLength"] = codeLength;
       if (codeOffset != 0) _result["codeOffset"] = codeOffset;
-      if (namedCompilationUnitMember_name != null)
-        _result["namedCompilationUnitMember_name"] =
-            namedCompilationUnitMember_name.toJson();
+      if (nameOffset != 0) _result["nameOffset"] = nameOffset;
       if (simplyBoundable_isSimplyBounded != false)
         _result["simplyBoundable_isSimplyBounded"] =
             simplyBoundable_isSimplyBounded;
@@ -16751,10 +12246,6 @@
             annotatedNode_metadata.map((_value) => _value.toJson()).toList();
       if (libraryDirective_name != null)
         _result["libraryDirective_name"] = libraryDirective_name.toJson();
-      if (directive_keyword != 0)
-        _result["directive_keyword"] = directive_keyword;
-      if (directive_semicolon != 0)
-        _result["directive_semicolon"] = directive_semicolon;
     }
     if (kind == idl.LinkedNodeKind.mixinDeclaration) {
       if (annotatedNode_comment != null)
@@ -16765,15 +12256,6 @@
       if (mixinDeclaration_onClause != null)
         _result["mixinDeclaration_onClause"] =
             mixinDeclaration_onClause.toJson();
-      if (mixinDeclaration_mixinKeyword != 0)
-        _result["mixinDeclaration_mixinKeyword"] =
-            mixinDeclaration_mixinKeyword;
-      if (classOrMixinDeclaration_rightBracket != 0)
-        _result["classOrMixinDeclaration_rightBracket"] =
-            classOrMixinDeclaration_rightBracket;
-      if (classOrMixinDeclaration_leftBracket != 0)
-        _result["classOrMixinDeclaration_leftBracket"] =
-            classOrMixinDeclaration_leftBracket;
       if (classOrMixinDeclaration_implementsClause != null)
         _result["classOrMixinDeclaration_implementsClause"] =
             classOrMixinDeclaration_implementsClause.toJson();
@@ -16787,12 +12269,10 @@
             classOrMixinDeclaration_typeParameters.toJson();
       if (codeLength != 0) _result["codeLength"] = codeLength;
       if (codeOffset != 0) _result["codeOffset"] = codeOffset;
-      if (namedCompilationUnitMember_name != null)
-        _result["namedCompilationUnitMember_name"] =
-            namedCompilationUnitMember_name.toJson();
       if (mixinDeclaration_superInvokedNames.isNotEmpty)
         _result["mixinDeclaration_superInvokedNames"] =
             mixinDeclaration_superInvokedNames;
+      if (nameOffset != 0) _result["nameOffset"] = nameOffset;
       if (simplyBoundable_isSimplyBounded != false)
         _result["simplyBoundable_isSimplyBounded"] =
             simplyBoundable_isSimplyBounded;
@@ -16803,16 +12283,13 @@
       if (annotatedNode_metadata.isNotEmpty)
         _result["annotatedNode_metadata"] =
             annotatedNode_metadata.map((_value) => _value.toJson()).toList();
-      if (directive_keyword != 0)
-        _result["directive_keyword"] = directive_keyword;
-      if (uriBasedDirective_uriElement != 0)
-        _result["uriBasedDirective_uriElement"] = uriBasedDirective_uriElement;
-      if (directive_semicolon != 0)
-        _result["directive_semicolon"] = directive_semicolon;
+      if (nameOffset != 0) _result["nameOffset"] = nameOffset;
       if (uriBasedDirective_uri != null)
         _result["uriBasedDirective_uri"] = uriBasedDirective_uri.toJson();
       if (uriBasedDirective_uriContent != '')
         _result["uriBasedDirective_uriContent"] = uriBasedDirective_uriContent;
+      if (uriBasedDirective_uriElement != 0)
+        _result["uriBasedDirective_uriElement"] = uriBasedDirective_uriElement;
     }
     if (kind == idl.LinkedNodeKind.partOfDirective) {
       if (annotatedNode_comment != null)
@@ -16825,12 +12302,6 @@
             partOfDirective_libraryName.toJson();
       if (partOfDirective_uri != null)
         _result["partOfDirective_uri"] = partOfDirective_uri.toJson();
-      if (partOfDirective_ofKeyword != 0)
-        _result["partOfDirective_ofKeyword"] = partOfDirective_ofKeyword;
-      if (directive_keyword != 0)
-        _result["directive_keyword"] = directive_keyword;
-      if (directive_semicolon != 0)
-        _result["directive_semicolon"] = directive_semicolon;
     }
     if (kind == idl.LinkedNodeKind.topLevelVariableDeclaration) {
       if (annotatedNode_comment != null)
@@ -16841,9 +12312,6 @@
       if (topLevelVariableDeclaration_variableList != null)
         _result["topLevelVariableDeclaration_variableList"] =
             topLevelVariableDeclaration_variableList.toJson();
-      if (topLevelVariableDeclaration_semicolon != 0)
-        _result["topLevelVariableDeclaration_semicolon"] =
-            topLevelVariableDeclaration_semicolon;
     }
     if (kind == idl.LinkedNodeKind.typeParameter) {
       if (annotatedNode_comment != null)
@@ -16853,15 +12321,12 @@
             annotatedNode_metadata.map((_value) => _value.toJson()).toList();
       if (typeParameter_bound != null)
         _result["typeParameter_bound"] = typeParameter_bound.toJson();
-      if (typeParameter_extendsKeyword != 0)
-        _result["typeParameter_extendsKeyword"] = typeParameter_extendsKeyword;
-      if (typeParameter_name != null)
-        _result["typeParameter_name"] = typeParameter_name.toJson();
       if (typeParameter_defaultType != null)
         _result["typeParameter_defaultType"] =
             typeParameter_defaultType.toJson();
       if (codeLength != 0) _result["codeLength"] = codeLength;
       if (codeOffset != 0) _result["codeOffset"] = codeOffset;
+      if (nameOffset != 0) _result["nameOffset"] = nameOffset;
     }
     if (kind == idl.LinkedNodeKind.switchCase) {
       if (switchMember_statements.isNotEmpty)
@@ -16869,10 +12334,6 @@
             switchMember_statements.map((_value) => _value.toJson()).toList();
       if (switchCase_expression != null)
         _result["switchCase_expression"] = switchCase_expression.toJson();
-      if (switchMember_keyword != 0)
-        _result["switchMember_keyword"] = switchMember_keyword;
-      if (switchMember_colon != 0)
-        _result["switchMember_colon"] = switchMember_colon;
       if (switchMember_labels.isNotEmpty)
         _result["switchMember_labels"] =
             switchMember_labels.map((_value) => _value.toJson()).toList();
@@ -16881,10 +12342,6 @@
       if (switchMember_statements.isNotEmpty)
         _result["switchMember_statements"] =
             switchMember_statements.map((_value) => _value.toJson()).toList();
-      if (switchMember_keyword != 0)
-        _result["switchMember_keyword"] = switchMember_keyword;
-      if (switchMember_colon != 0)
-        _result["switchMember_colon"] = switchMember_colon;
       if (switchMember_labels.isNotEmpty)
         _result["switchMember_labels"] =
             switchMember_labels.map((_value) => _value.toJson()).toList();
@@ -16892,8 +12349,6 @@
     if (kind == idl.LinkedNodeKind.annotation) {
       if (annotation_arguments != null)
         _result["annotation_arguments"] = annotation_arguments.toJson();
-      if (annotation_atSign != 0)
-        _result["annotation_atSign"] = annotation_atSign;
       if (annotation_constructorName != null)
         _result["annotation_constructorName"] =
             annotation_constructorName.toJson();
@@ -16903,14 +12358,10 @@
         _result["annotation_elementType"] = annotation_elementType.toJson();
       if (annotation_name != null)
         _result["annotation_name"] = annotation_name.toJson();
-      if (annotation_period != 0)
-        _result["annotation_period"] = annotation_period;
     }
     if (kind == idl.LinkedNodeKind.asExpression) {
       if (asExpression_expression != null)
         _result["asExpression_expression"] = asExpression_expression.toJson();
-      if (asExpression_asOperator != 0)
-        _result["asExpression_asOperator"] = asExpression_asOperator;
       if (asExpression_type != null)
         _result["asExpression_type"] = asExpression_type.toJson();
       if (expression_type != null)
@@ -16920,56 +12371,32 @@
       if (assertInitializer_condition != null)
         _result["assertInitializer_condition"] =
             assertInitializer_condition.toJson();
-      if (assertInitializer_assertKeyword != 0)
-        _result["assertInitializer_assertKeyword"] =
-            assertInitializer_assertKeyword;
       if (assertInitializer_message != null)
         _result["assertInitializer_message"] =
             assertInitializer_message.toJson();
-      if (assertInitializer_leftParenthesis != 0)
-        _result["assertInitializer_leftParenthesis"] =
-            assertInitializer_leftParenthesis;
-      if (assertInitializer_comma != 0)
-        _result["assertInitializer_comma"] = assertInitializer_comma;
-      if (assertInitializer_rightParenthesis != 0)
-        _result["assertInitializer_rightParenthesis"] =
-            assertInitializer_rightParenthesis;
     }
     if (kind == idl.LinkedNodeKind.assertStatement) {
       if (assertStatement_condition != null)
         _result["assertStatement_condition"] =
             assertStatement_condition.toJson();
-      if (assertStatement_assertKeyword != 0)
-        _result["assertStatement_assertKeyword"] =
-            assertStatement_assertKeyword;
       if (assertStatement_message != null)
         _result["assertStatement_message"] = assertStatement_message.toJson();
-      if (assertStatement_leftParenthesis != 0)
-        _result["assertStatement_leftParenthesis"] =
-            assertStatement_leftParenthesis;
-      if (assertStatement_comma != 0)
-        _result["assertStatement_comma"] = assertStatement_comma;
-      if (assertStatement_rightParenthesis != 0)
-        _result["assertStatement_rightParenthesis"] =
-            assertStatement_rightParenthesis;
-      if (assertStatement_semicolon != 0)
-        _result["assertStatement_semicolon"] = assertStatement_semicolon;
     }
     if (kind == idl.LinkedNodeKind.assignmentExpression) {
       if (assignmentExpression_leftHandSide != null)
         _result["assignmentExpression_leftHandSide"] =
             assignmentExpression_leftHandSide.toJson();
-      if (assignmentExpression_element != 0)
-        _result["assignmentExpression_element"] = assignmentExpression_element;
       if (assignmentExpression_rightHandSide != null)
         _result["assignmentExpression_rightHandSide"] =
             assignmentExpression_rightHandSide.toJson();
       if (assignmentExpression_elementType != null)
         _result["assignmentExpression_elementType"] =
             assignmentExpression_elementType.toJson();
-      if (assignmentExpression_operator != 0)
+      if (assignmentExpression_element != 0)
+        _result["assignmentExpression_element"] = assignmentExpression_element;
+      if (assignmentExpression_operator != idl.UnlinkedTokenType.NOTHING)
         _result["assignmentExpression_operator"] =
-            assignmentExpression_operator;
+            assignmentExpression_operator.toString().split('.')[1];
       if (expression_type != null)
         _result["expression_type"] = expression_type.toJson();
     }
@@ -16977,46 +12404,26 @@
       if (awaitExpression_expression != null)
         _result["awaitExpression_expression"] =
             awaitExpression_expression.toJson();
-      if (awaitExpression_awaitKeyword != 0)
-        _result["awaitExpression_awaitKeyword"] = awaitExpression_awaitKeyword;
       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();
-      if (blockFunctionBody_keyword != 0)
-        _result["blockFunctionBody_keyword"] = blockFunctionBody_keyword;
-      if (blockFunctionBody_star != 0)
-        _result["blockFunctionBody_star"] = blockFunctionBody_star;
     }
     if (kind == idl.LinkedNodeKind.breakStatement) {
       if (breakStatement_label != null)
         _result["breakStatement_label"] = breakStatement_label.toJson();
-      if (breakStatement_breakKeyword != 0)
-        _result["breakStatement_breakKeyword"] = breakStatement_breakKeyword;
-      if (breakStatement_semicolon != 0)
-        _result["breakStatement_semicolon"] = breakStatement_semicolon;
     }
     if (kind == idl.LinkedNodeKind.catchClause) {
       if (catchClause_body != null)
         _result["catchClause_body"] = catchClause_body.toJson();
-      if (catchClause_catchKeyword != 0)
-        _result["catchClause_catchKeyword"] = catchClause_catchKeyword;
       if (catchClause_exceptionParameter != null)
         _result["catchClause_exceptionParameter"] =
             catchClause_exceptionParameter.toJson();
-      if (catchClause_leftParenthesis != 0)
-        _result["catchClause_leftParenthesis"] = catchClause_leftParenthesis;
       if (catchClause_exceptionType != null)
         _result["catchClause_exceptionType"] =
             catchClause_exceptionType.toJson();
-      if (catchClause_comma != 0)
-        _result["catchClause_comma"] = catchClause_comma;
-      if (catchClause_onKeyword != 0)
-        _result["catchClause_onKeyword"] = catchClause_onKeyword;
-      if (catchClause_rightParenthesis != 0)
-        _result["catchClause_rightParenthesis"] = catchClause_rightParenthesis;
       if (catchClause_stackTraceParameter != null)
         _result["catchClause_stackTraceParameter"] =
             catchClause_stackTraceParameter.toJson();
@@ -17025,91 +12432,55 @@
       if (commentReference_identifier != null)
         _result["commentReference_identifier"] =
             commentReference_identifier.toJson();
-      if (commentReference_newKeyword != 0)
-        _result["commentReference_newKeyword"] = commentReference_newKeyword;
     }
     if (kind == idl.LinkedNodeKind.conditionalExpression) {
       if (conditionalExpression_condition != null)
         _result["conditionalExpression_condition"] =
             conditionalExpression_condition.toJson();
-      if (conditionalExpression_colon != 0)
-        _result["conditionalExpression_colon"] = conditionalExpression_colon;
       if (conditionalExpression_elseExpression != null)
         _result["conditionalExpression_elseExpression"] =
             conditionalExpression_elseExpression.toJson();
       if (conditionalExpression_thenExpression != null)
         _result["conditionalExpression_thenExpression"] =
             conditionalExpression_thenExpression.toJson();
-      if (conditionalExpression_question != 0)
-        _result["conditionalExpression_question"] =
-            conditionalExpression_question;
       if (expression_type != null)
         _result["expression_type"] = expression_type.toJson();
     }
     if (kind == idl.LinkedNodeKind.configuration) {
       if (configuration_name != null)
         _result["configuration_name"] = configuration_name.toJson();
-      if (configuration_ifKeyword != 0)
-        _result["configuration_ifKeyword"] = configuration_ifKeyword;
       if (configuration_value != null)
         _result["configuration_value"] = configuration_value.toJson();
-      if (configuration_rightParenthesis != 0)
-        _result["configuration_rightParenthesis"] =
-            configuration_rightParenthesis;
       if (configuration_uri != null)
         _result["configuration_uri"] = configuration_uri.toJson();
-      if (configuration_leftParenthesis != 0)
-        _result["configuration_leftParenthesis"] =
-            configuration_leftParenthesis;
-      if (configuration_equalToken != 0)
-        _result["configuration_equalToken"] = configuration_equalToken;
     }
     if (kind == idl.LinkedNodeKind.constructorFieldInitializer) {
       if (constructorFieldInitializer_expression != null)
         _result["constructorFieldInitializer_expression"] =
             constructorFieldInitializer_expression.toJson();
-      if (constructorFieldInitializer_equals != 0)
-        _result["constructorFieldInitializer_equals"] =
-            constructorFieldInitializer_equals;
       if (constructorFieldInitializer_fieldName != null)
         _result["constructorFieldInitializer_fieldName"] =
             constructorFieldInitializer_fieldName.toJson();
-      if (constructorFieldInitializer_thisKeyword != 0)
-        _result["constructorFieldInitializer_thisKeyword"] =
-            constructorFieldInitializer_thisKeyword;
-      if (constructorFieldInitializer_period != 0)
-        _result["constructorFieldInitializer_period"] =
-            constructorFieldInitializer_period;
     }
     if (kind == idl.LinkedNodeKind.constructorName) {
       if (constructorName_name != null)
         _result["constructorName_name"] = constructorName_name.toJson();
-      if (constructorName_element != 0)
-        _result["constructorName_element"] = constructorName_element;
       if (constructorName_type != null)
         _result["constructorName_type"] = constructorName_type.toJson();
       if (constructorName_elementType != null)
         _result["constructorName_elementType"] =
             constructorName_elementType.toJson();
-      if (constructorName_period != 0)
-        _result["constructorName_period"] = constructorName_period;
+      if (constructorName_element != 0)
+        _result["constructorName_element"] = constructorName_element;
     }
     if (kind == idl.LinkedNodeKind.continueStatement) {
       if (continueStatement_label != null)
         _result["continueStatement_label"] = continueStatement_label.toJson();
-      if (continueStatement_continueKeyword != 0)
-        _result["continueStatement_continueKeyword"] =
-            continueStatement_continueKeyword;
-      if (continueStatement_semicolon != 0)
-        _result["continueStatement_semicolon"] = continueStatement_semicolon;
     }
     if (kind == idl.LinkedNodeKind.defaultFormalParameter) {
       if (defaultFormalParameter_defaultValue != null)
         _result["defaultFormalParameter_defaultValue"] =
             defaultFormalParameter_defaultValue.toJson();
-      if (defaultFormalParameter_separator != 0)
-        _result["defaultFormalParameter_separator"] =
-            defaultFormalParameter_separator;
       if (defaultFormalParameter_parameter != null)
         _result["defaultFormalParameter_parameter"] =
             defaultFormalParameter_parameter.toJson();
@@ -17123,51 +12494,26 @@
     if (kind == idl.LinkedNodeKind.doStatement) {
       if (doStatement_body != null)
         _result["doStatement_body"] = doStatement_body.toJson();
-      if (doStatement_leftParenthesis != 0)
-        _result["doStatement_leftParenthesis"] = doStatement_leftParenthesis;
       if (doStatement_condition != null)
         _result["doStatement_condition"] = doStatement_condition.toJson();
-      if (doStatement_doKeyword != 0)
-        _result["doStatement_doKeyword"] = doStatement_doKeyword;
-      if (doStatement_rightParenthesis != 0)
-        _result["doStatement_rightParenthesis"] = doStatement_rightParenthesis;
-      if (doStatement_semicolon != 0)
-        _result["doStatement_semicolon"] = doStatement_semicolon;
-      if (doStatement_whileKeyword != 0)
-        _result["doStatement_whileKeyword"] = doStatement_whileKeyword;
     }
     if (kind == idl.LinkedNodeKind.expressionFunctionBody) {
       if (expressionFunctionBody_expression != null)
         _result["expressionFunctionBody_expression"] =
             expressionFunctionBody_expression.toJson();
-      if (expressionFunctionBody_arrow != 0)
-        _result["expressionFunctionBody_arrow"] = expressionFunctionBody_arrow;
-      if (expressionFunctionBody_semicolon != 0)
-        _result["expressionFunctionBody_semicolon"] =
-            expressionFunctionBody_semicolon;
-      if (expressionFunctionBody_keyword != 0)
-        _result["expressionFunctionBody_keyword"] =
-            expressionFunctionBody_keyword;
     }
     if (kind == idl.LinkedNodeKind.expressionStatement) {
       if (expressionStatement_expression != null)
         _result["expressionStatement_expression"] =
             expressionStatement_expression.toJson();
-      if (expressionStatement_semicolon != 0)
-        _result["expressionStatement_semicolon"] =
-            expressionStatement_semicolon;
     }
     if (kind == idl.LinkedNodeKind.extendsClause) {
       if (extendsClause_superclass != null)
         _result["extendsClause_superclass"] = extendsClause_superclass.toJson();
-      if (extendsClause_extendsKeyword != 0)
-        _result["extendsClause_extendsKeyword"] = extendsClause_extendsKeyword;
     }
     if (kind == idl.LinkedNodeKind.forEachPartsWithDeclaration) {
       if (forEachParts_iterable != null)
         _result["forEachParts_iterable"] = forEachParts_iterable.toJson();
-      if (forEachParts_inKeyword != 0)
-        _result["forEachParts_inKeyword"] = forEachParts_inKeyword;
       if (forEachPartsWithDeclaration_loopVariable != null)
         _result["forEachPartsWithDeclaration_loopVariable"] =
             forEachPartsWithDeclaration_loopVariable.toJson();
@@ -17175,8 +12521,6 @@
     if (kind == idl.LinkedNodeKind.forEachPartsWithIdentifier) {
       if (forEachParts_iterable != null)
         _result["forEachParts_iterable"] = forEachParts_iterable.toJson();
-      if (forEachParts_inKeyword != 0)
-        _result["forEachParts_inKeyword"] = forEachParts_inKeyword;
       if (forEachPartsWithIdentifier_identifier != null)
         _result["forEachPartsWithIdentifier_identifier"] =
             forEachPartsWithIdentifier_identifier.toJson();
@@ -17184,41 +12528,21 @@
     if (kind == idl.LinkedNodeKind.forElement) {
       if (forMixin_forLoopParts != null)
         _result["forMixin_forLoopParts"] = forMixin_forLoopParts.toJson();
-      if (forMixin_awaitKeyword != 0)
-        _result["forMixin_awaitKeyword"] = forMixin_awaitKeyword;
       if (forElement_body != null)
         _result["forElement_body"] = forElement_body.toJson();
-      if (forMixin_leftParenthesis != 0)
-        _result["forMixin_leftParenthesis"] = forMixin_leftParenthesis;
-      if (forMixin_forKeyword != 0)
-        _result["forMixin_forKeyword"] = forMixin_forKeyword;
-      if (forMixin_rightParenthesis != 0)
-        _result["forMixin_rightParenthesis"] = forMixin_rightParenthesis;
     }
     if (kind == idl.LinkedNodeKind.forStatement) {
       if (forMixin_forLoopParts != null)
         _result["forMixin_forLoopParts"] = forMixin_forLoopParts.toJson();
-      if (forMixin_awaitKeyword != 0)
-        _result["forMixin_awaitKeyword"] = forMixin_awaitKeyword;
       if (forStatement_body != null)
         _result["forStatement_body"] = forStatement_body.toJson();
-      if (forMixin_leftParenthesis != 0)
-        _result["forMixin_leftParenthesis"] = forMixin_leftParenthesis;
-      if (forMixin_forKeyword != 0)
-        _result["forMixin_forKeyword"] = forMixin_forKeyword;
-      if (forMixin_rightParenthesis != 0)
-        _result["forMixin_rightParenthesis"] = forMixin_rightParenthesis;
     }
     if (kind == idl.LinkedNodeKind.forPartsWithDeclarations) {
       if (forParts_condition != null)
         _result["forParts_condition"] = forParts_condition.toJson();
-      if (forParts_leftSeparator != 0)
-        _result["forParts_leftSeparator"] = forParts_leftSeparator;
       if (forPartsWithDeclarations_variables != null)
         _result["forPartsWithDeclarations_variables"] =
             forPartsWithDeclarations_variables.toJson();
-      if (forParts_rightSeparator != 0)
-        _result["forParts_rightSeparator"] = forParts_rightSeparator;
       if (forParts_updaters.isNotEmpty)
         _result["forParts_updaters"] =
             forParts_updaters.map((_value) => _value.toJson()).toList();
@@ -17226,13 +12550,9 @@
     if (kind == idl.LinkedNodeKind.forPartsWithExpression) {
       if (forParts_condition != null)
         _result["forParts_condition"] = forParts_condition.toJson();
-      if (forParts_leftSeparator != 0)
-        _result["forParts_leftSeparator"] = forParts_leftSeparator;
       if (forPartsWithExpression_initialization != null)
         _result["forPartsWithExpression_initialization"] =
             forPartsWithExpression_initialization.toJson();
-      if (forParts_rightSeparator != 0)
-        _result["forParts_rightSeparator"] = forParts_rightSeparator;
       if (forParts_updaters.isNotEmpty)
         _result["forParts_updaters"] =
             forParts_updaters.map((_value) => _value.toJson()).toList();
@@ -17245,69 +12565,31 @@
     if (kind == idl.LinkedNodeKind.ifElement) {
       if (ifMixin_condition != null)
         _result["ifMixin_condition"] = ifMixin_condition.toJson();
-      if (ifMixin_elseKeyword != 0)
-        _result["ifMixin_elseKeyword"] = ifMixin_elseKeyword;
-      if (ifMixin_leftParenthesis != 0)
-        _result["ifMixin_leftParenthesis"] = ifMixin_leftParenthesis;
       if (ifElement_thenElement != null)
         _result["ifElement_thenElement"] = ifElement_thenElement.toJson();
-      if (ifMixin_ifKeyword != 0)
-        _result["ifMixin_ifKeyword"] = ifMixin_ifKeyword;
-      if (ifMixin_rightParenthesis != 0)
-        _result["ifMixin_rightParenthesis"] = ifMixin_rightParenthesis;
       if (ifElement_elseElement != null)
         _result["ifElement_elseElement"] = ifElement_elseElement.toJson();
     }
     if (kind == idl.LinkedNodeKind.ifStatement) {
       if (ifMixin_condition != null)
         _result["ifMixin_condition"] = ifMixin_condition.toJson();
-      if (ifMixin_elseKeyword != 0)
-        _result["ifMixin_elseKeyword"] = ifMixin_elseKeyword;
       if (ifStatement_elseStatement != null)
         _result["ifStatement_elseStatement"] =
             ifStatement_elseStatement.toJson();
-      if (ifMixin_leftParenthesis != 0)
-        _result["ifMixin_leftParenthesis"] = ifMixin_leftParenthesis;
       if (ifStatement_thenStatement != null)
         _result["ifStatement_thenStatement"] =
             ifStatement_thenStatement.toJson();
-      if (ifMixin_ifKeyword != 0)
-        _result["ifMixin_ifKeyword"] = ifMixin_ifKeyword;
-      if (ifMixin_rightParenthesis != 0)
-        _result["ifMixin_rightParenthesis"] = ifMixin_rightParenthesis;
     }
     if (kind == idl.LinkedNodeKind.indexExpression) {
       if (indexExpression_index != null)
         _result["indexExpression_index"] = indexExpression_index.toJson();
-      if (indexExpression_element != 0)
-        _result["indexExpression_element"] = indexExpression_element;
       if (indexExpression_target != null)
         _result["indexExpression_target"] = indexExpression_target.toJson();
-      if (indexExpression_leftBracket != 0)
-        _result["indexExpression_leftBracket"] = indexExpression_leftBracket;
       if (indexExpression_elementType != null)
         _result["indexExpression_elementType"] =
             indexExpression_elementType.toJson();
-      if (indexExpression_period != 0)
-        _result["indexExpression_period"] = indexExpression_period;
-      if (indexExpression_rightBracket != 0)
-        _result["indexExpression_rightBracket"] = indexExpression_rightBracket;
-      if (expression_type != null)
-        _result["expression_type"] = expression_type.toJson();
-    }
-    if (kind == idl.LinkedNodeKind.instanceCreationExpression) {
-      if (instanceCreationExpression_arguments != null)
-        _result["instanceCreationExpression_arguments"] =
-            instanceCreationExpression_arguments.toJson();
-      if (instanceCreationExpression_keyword != 0)
-        _result["instanceCreationExpression_keyword"] =
-            instanceCreationExpression_keyword;
-      if (instanceCreationExpression_constructorName != null)
-        _result["instanceCreationExpression_constructorName"] =
-            instanceCreationExpression_constructorName.toJson();
-      if (instanceCreationExpression_typeArguments != null)
-        _result["instanceCreationExpression_typeArguments"] =
-            instanceCreationExpression_typeArguments.toJson();
+      if (indexExpression_element != 0)
+        _result["indexExpression_element"] = indexExpression_element;
       if (expression_type != null)
         _result["expression_type"] = expression_type.toJson();
     }
@@ -17315,34 +12597,19 @@
       if (interpolationExpression_expression != null)
         _result["interpolationExpression_expression"] =
             interpolationExpression_expression.toJson();
-      if (interpolationExpression_leftBracket != 0)
-        _result["interpolationExpression_leftBracket"] =
-            interpolationExpression_leftBracket;
-      if (interpolationExpression_rightBracket != 0)
-        _result["interpolationExpression_rightBracket"] =
-            interpolationExpression_rightBracket;
     }
     if (kind == idl.LinkedNodeKind.isExpression) {
       if (isExpression_expression != null)
         _result["isExpression_expression"] = isExpression_expression.toJson();
-      if (isExpression_isOperator != 0)
-        _result["isExpression_isOperator"] = isExpression_isOperator;
       if (isExpression_type != null)
         _result["isExpression_type"] = isExpression_type.toJson();
-      if (isExpression_notOperator != 0)
-        _result["isExpression_notOperator"] = isExpression_notOperator;
-      if (expression_type != null)
-        _result["expression_type"] = expression_type.toJson();
     }
     if (kind == idl.LinkedNodeKind.label) {
       if (label_label != null) _result["label_label"] = label_label.toJson();
-      if (label_colon != 0) _result["label_colon"] = label_colon;
     }
     if (kind == idl.LinkedNodeKind.mapLiteralEntry) {
       if (mapLiteralEntry_key != null)
         _result["mapLiteralEntry_key"] = mapLiteralEntry_key.toJson();
-      if (mapLiteralEntry_separator != 0)
-        _result["mapLiteralEntry_separator"] = mapLiteralEntry_separator;
       if (mapLiteralEntry_value != null)
         _result["mapLiteralEntry_value"] = mapLiteralEntry_value.toJson();
     }
@@ -17352,35 +12619,20 @@
             namedExpression_expression.toJson();
       if (namedExpression_name != null)
         _result["namedExpression_name"] = namedExpression_name.toJson();
-      if (expression_type != null)
-        _result["expression_type"] = expression_type.toJson();
     }
     if (kind == idl.LinkedNodeKind.nativeClause) {
       if (nativeClause_name != null)
         _result["nativeClause_name"] = nativeClause_name.toJson();
-      if (nativeClause_nativeKeyword != 0)
-        _result["nativeClause_nativeKeyword"] = nativeClause_nativeKeyword;
     }
     if (kind == idl.LinkedNodeKind.nativeFunctionBody) {
       if (nativeFunctionBody_stringLiteral != null)
         _result["nativeFunctionBody_stringLiteral"] =
             nativeFunctionBody_stringLiteral.toJson();
-      if (nativeFunctionBody_nativeKeyword != 0)
-        _result["nativeFunctionBody_nativeKeyword"] =
-            nativeFunctionBody_nativeKeyword;
-      if (nativeFunctionBody_semicolon != 0)
-        _result["nativeFunctionBody_semicolon"] = nativeFunctionBody_semicolon;
     }
     if (kind == idl.LinkedNodeKind.parenthesizedExpression) {
       if (parenthesizedExpression_expression != null)
         _result["parenthesizedExpression_expression"] =
             parenthesizedExpression_expression.toJson();
-      if (parenthesizedExpression_leftParenthesis != 0)
-        _result["parenthesizedExpression_leftParenthesis"] =
-            parenthesizedExpression_leftParenthesis;
-      if (parenthesizedExpression_rightParenthesis != 0)
-        _result["parenthesizedExpression_rightParenthesis"] =
-            parenthesizedExpression_rightParenthesis;
       if (expression_type != null)
         _result["expression_type"] = expression_type.toJson();
     }
@@ -17388,13 +12640,14 @@
       if (postfixExpression_operand != null)
         _result["postfixExpression_operand"] =
             postfixExpression_operand.toJson();
-      if (postfixExpression_element != 0)
-        _result["postfixExpression_element"] = postfixExpression_element;
       if (postfixExpression_elementType != null)
         _result["postfixExpression_elementType"] =
             postfixExpression_elementType.toJson();
-      if (postfixExpression_operator != 0)
-        _result["postfixExpression_operator"] = postfixExpression_operator;
+      if (postfixExpression_element != 0)
+        _result["postfixExpression_element"] = postfixExpression_element;
+      if (postfixExpression_operator != idl.UnlinkedTokenType.NOTHING)
+        _result["postfixExpression_operator"] =
+            postfixExpression_operator.toString().split('.')[1];
       if (expression_type != null)
         _result["expression_type"] = expression_type.toJson();
     }
@@ -17402,8 +12655,6 @@
       if (prefixedIdentifier_identifier != null)
         _result["prefixedIdentifier_identifier"] =
             prefixedIdentifier_identifier.toJson();
-      if (prefixedIdentifier_period != 0)
-        _result["prefixedIdentifier_period"] = prefixedIdentifier_period;
       if (prefixedIdentifier_prefix != null)
         _result["prefixedIdentifier_prefix"] =
             prefixedIdentifier_prefix.toJson();
@@ -17413,13 +12664,14 @@
     if (kind == idl.LinkedNodeKind.prefixExpression) {
       if (prefixExpression_operand != null)
         _result["prefixExpression_operand"] = prefixExpression_operand.toJson();
-      if (prefixExpression_element != 0)
-        _result["prefixExpression_element"] = prefixExpression_element;
       if (prefixExpression_elementType != null)
         _result["prefixExpression_elementType"] =
             prefixExpression_elementType.toJson();
-      if (prefixExpression_operator != 0)
-        _result["prefixExpression_operator"] = prefixExpression_operator;
+      if (prefixExpression_element != 0)
+        _result["prefixExpression_element"] = prefixExpression_element;
+      if (prefixExpression_operator != idl.UnlinkedTokenType.NOTHING)
+        _result["prefixExpression_operator"] =
+            prefixExpression_operator.toString().split('.')[1];
       if (expression_type != null)
         _result["expression_type"] = expression_type.toJson();
     }
@@ -17427,10 +12679,11 @@
       if (propertyAccess_propertyName != null)
         _result["propertyAccess_propertyName"] =
             propertyAccess_propertyName.toJson();
-      if (propertyAccess_operator != 0)
-        _result["propertyAccess_operator"] = propertyAccess_operator;
       if (propertyAccess_target != null)
         _result["propertyAccess_target"] = propertyAccess_target.toJson();
+      if (propertyAccess_operator != idl.UnlinkedTokenType.NOTHING)
+        _result["propertyAccess_operator"] =
+            propertyAccess_operator.toString().split('.')[1];
       if (expression_type != null)
         _result["expression_type"] = expression_type.toJson();
     }
@@ -17438,209 +12691,132 @@
       if (redirectingConstructorInvocation_arguments != null)
         _result["redirectingConstructorInvocation_arguments"] =
             redirectingConstructorInvocation_arguments.toJson();
-      if (redirectingConstructorInvocation_element != 0)
-        _result["redirectingConstructorInvocation_element"] =
-            redirectingConstructorInvocation_element;
       if (redirectingConstructorInvocation_constructorName != null)
         _result["redirectingConstructorInvocation_constructorName"] =
             redirectingConstructorInvocation_constructorName.toJson();
-      if (redirectingConstructorInvocation_thisKeyword != 0)
-        _result["redirectingConstructorInvocation_thisKeyword"] =
-            redirectingConstructorInvocation_thisKeyword;
       if (redirectingConstructorInvocation_elementType != null)
         _result["redirectingConstructorInvocation_elementType"] =
             redirectingConstructorInvocation_elementType.toJson();
-      if (redirectingConstructorInvocation_period != 0)
-        _result["redirectingConstructorInvocation_period"] =
-            redirectingConstructorInvocation_period;
+      if (redirectingConstructorInvocation_element != 0)
+        _result["redirectingConstructorInvocation_element"] =
+            redirectingConstructorInvocation_element;
     }
     if (kind == idl.LinkedNodeKind.returnStatement) {
       if (returnStatement_expression != null)
         _result["returnStatement_expression"] =
             returnStatement_expression.toJson();
-      if (returnStatement_returnKeyword != 0)
-        _result["returnStatement_returnKeyword"] =
-            returnStatement_returnKeyword;
-      if (returnStatement_semicolon != 0)
-        _result["returnStatement_semicolon"] = returnStatement_semicolon;
     }
     if (kind == idl.LinkedNodeKind.spreadElement) {
       if (spreadElement_expression != null)
         _result["spreadElement_expression"] = spreadElement_expression.toJson();
-      if (spreadElement_spreadOperator != 0)
-        _result["spreadElement_spreadOperator"] = spreadElement_spreadOperator;
+      if (spreadElement_spreadOperator != idl.UnlinkedTokenType.NOTHING)
+        _result["spreadElement_spreadOperator"] =
+            spreadElement_spreadOperator.toString().split('.')[1];
     }
     if (kind == idl.LinkedNodeKind.superConstructorInvocation) {
       if (superConstructorInvocation_arguments != null)
         _result["superConstructorInvocation_arguments"] =
             superConstructorInvocation_arguments.toJson();
-      if (superConstructorInvocation_element != 0)
-        _result["superConstructorInvocation_element"] =
-            superConstructorInvocation_element;
       if (superConstructorInvocation_constructorName != null)
         _result["superConstructorInvocation_constructorName"] =
             superConstructorInvocation_constructorName.toJson();
-      if (superConstructorInvocation_superKeyword != 0)
-        _result["superConstructorInvocation_superKeyword"] =
-            superConstructorInvocation_superKeyword;
       if (superConstructorInvocation_elementType != null)
         _result["superConstructorInvocation_elementType"] =
             superConstructorInvocation_elementType.toJson();
-      if (superConstructorInvocation_period != 0)
-        _result["superConstructorInvocation_period"] =
-            superConstructorInvocation_period;
+      if (superConstructorInvocation_element != 0)
+        _result["superConstructorInvocation_element"] =
+            superConstructorInvocation_element;
     }
     if (kind == idl.LinkedNodeKind.throwExpression) {
       if (throwExpression_expression != null)
         _result["throwExpression_expression"] =
             throwExpression_expression.toJson();
-      if (throwExpression_throwKeyword != 0)
-        _result["throwExpression_throwKeyword"] = throwExpression_throwKeyword;
       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"] =
             variableDeclarationStatement_variables.toJson();
-      if (variableDeclarationStatement_semicolon != 0)
-        _result["variableDeclarationStatement_semicolon"] =
-            variableDeclarationStatement_semicolon;
     }
     if (kind == idl.LinkedNodeKind.whileStatement) {
       if (whileStatement_body != null)
         _result["whileStatement_body"] = whileStatement_body.toJson();
-      if (whileStatement_leftParenthesis != 0)
-        _result["whileStatement_leftParenthesis"] =
-            whileStatement_leftParenthesis;
       if (whileStatement_condition != null)
         _result["whileStatement_condition"] = whileStatement_condition.toJson();
-      if (whileStatement_whileKeyword != 0)
-        _result["whileStatement_whileKeyword"] = whileStatement_whileKeyword;
-      if (whileStatement_rightParenthesis != 0)
-        _result["whileStatement_rightParenthesis"] =
-            whileStatement_rightParenthesis;
     }
     if (kind == idl.LinkedNodeKind.yieldStatement) {
       if (yieldStatement_expression != null)
         _result["yieldStatement_expression"] =
             yieldStatement_expression.toJson();
-      if (yieldStatement_yieldKeyword != 0)
-        _result["yieldStatement_yieldKeyword"] = yieldStatement_yieldKeyword;
-      if (yieldStatement_semicolon != 0)
-        _result["yieldStatement_semicolon"] = yieldStatement_semicolon;
-      if (yieldStatement_star != 0)
-        _result["yieldStatement_star"] = yieldStatement_star;
     }
-    if (kind == idl.LinkedNodeKind.booleanLiteral) {
-      if (booleanLiteral_literal != 0)
-        _result["booleanLiteral_literal"] = booleanLiteral_literal;
-      if (booleanLiteral_value != false)
-        _result["booleanLiteral_value"] = booleanLiteral_value;
-      if (expression_type != null)
-        _result["expression_type"] = expression_type.toJson();
-    }
-    if (kind == idl.LinkedNodeKind.doubleLiteral) {
-      if (doubleLiteral_literal != 0)
-        _result["doubleLiteral_literal"] = doubleLiteral_literal;
-      if (doubleLiteral_value != 0.0)
-        _result["doubleLiteral_value"] = doubleLiteral_value.isFinite
-            ? doubleLiteral_value
-            : doubleLiteral_value.toString();
+    if (kind == idl.LinkedNodeKind.simpleIdentifier) {
+      if (simpleIdentifier_elementType != null)
+        _result["simpleIdentifier_elementType"] =
+            simpleIdentifier_elementType.toJson();
+      if (simpleIdentifier_element != 0)
+        _result["simpleIdentifier_element"] = simpleIdentifier_element;
       if (expression_type != null)
         _result["expression_type"] = expression_type.toJson();
     }
     if (kind == idl.LinkedNodeKind.emptyFunctionBody) {
-      if (emptyFunctionBody_semicolon != 0)
-        _result["emptyFunctionBody_semicolon"] = emptyFunctionBody_semicolon;
+      if (emptyFunctionBody_fake != 0)
+        _result["emptyFunctionBody_fake"] = emptyFunctionBody_fake;
     }
     if (kind == idl.LinkedNodeKind.emptyStatement) {
-      if (emptyStatement_semicolon != 0)
-        _result["emptyStatement_semicolon"] = emptyStatement_semicolon;
-    }
-    if (kind == idl.LinkedNodeKind.integerLiteral) {
-      if (integerLiteral_literal != 0)
-        _result["integerLiteral_literal"] = integerLiteral_literal;
-      if (integerLiteral_value != 0)
-        _result["integerLiteral_value"] = integerLiteral_value;
-      if (expression_type != null)
-        _result["expression_type"] = expression_type.toJson();
-    }
-    if (kind == idl.LinkedNodeKind.interpolationString) {
-      if (interpolationString_token != 0)
-        _result["interpolationString_token"] = interpolationString_token;
-      if (interpolationString_value != '')
-        _result["interpolationString_value"] = interpolationString_value;
+      if (emptyStatement_fake != 0)
+        _result["emptyStatement_fake"] = emptyStatement_fake;
     }
     if (kind == idl.LinkedNodeKind.nullLiteral) {
-      if (nullLiteral_literal != 0)
-        _result["nullLiteral_literal"] = nullLiteral_literal;
+      if (nullLiteral_fake != 0) _result["nullLiteral_fake"] = nullLiteral_fake;
       if (expression_type != null)
         _result["expression_type"] = expression_type.toJson();
     }
-    if (kind == idl.LinkedNodeKind.rethrowExpression) {
-      if (rethrowExpression_rethrowKeyword != 0)
-        _result["rethrowExpression_rethrowKeyword"] =
-            rethrowExpression_rethrowKeyword;
-      if (expression_type != null)
-        _result["expression_type"] = expression_type.toJson();
+    if (kind == idl.LinkedNodeKind.booleanLiteral) {
+      if (booleanLiteral_value != false)
+        _result["booleanLiteral_value"] = booleanLiteral_value;
     }
-    if (kind == idl.LinkedNodeKind.scriptTag) {
-      if (scriptTag_scriptTag != 0)
-        _result["scriptTag_scriptTag"] = scriptTag_scriptTag;
+    if (kind == idl.LinkedNodeKind.hideCombinator) {
+      if (names.isNotEmpty) _result["names"] = names;
     }
-    if (kind == idl.LinkedNodeKind.simpleIdentifier) {
-      if (simpleIdentifier_element != 0)
-        _result["simpleIdentifier_element"] = simpleIdentifier_element;
-      if (simpleIdentifier_elementType != null)
-        _result["simpleIdentifier_elementType"] =
-            simpleIdentifier_elementType.toJson();
-      if (simpleIdentifier_token != 0)
-        _result["simpleIdentifier_token"] = simpleIdentifier_token;
-      if (simpleIdentifier_isDeclaration != false)
-        _result["simpleIdentifier_isDeclaration"] =
-            simpleIdentifier_isDeclaration;
-      if (expression_type != null)
-        _result["expression_type"] = expression_type.toJson();
-    }
-    if (kind == idl.LinkedNodeKind.simpleStringLiteral) {
-      if (simpleStringLiteral_token != 0)
-        _result["simpleStringLiteral_token"] = simpleStringLiteral_token;
-      if (expression_type != null)
-        _result["expression_type"] = expression_type.toJson();
-      if (simpleStringLiteral_value != '')
-        _result["simpleStringLiteral_value"] = simpleStringLiteral_value;
-    }
-    if (kind == idl.LinkedNodeKind.superExpression) {
-      if (superExpression_superKeyword != 0)
-        _result["superExpression_superKeyword"] = superExpression_superKeyword;
-      if (expression_type != null)
-        _result["expression_type"] = expression_type.toJson();
+    if (kind == idl.LinkedNodeKind.showCombinator) {
+      if (names.isNotEmpty) _result["names"] = names;
     }
     if (kind == idl.LinkedNodeKind.symbolLiteral) {
-      if (symbolLiteral_poundSign != 0)
-        _result["symbolLiteral_poundSign"] = symbolLiteral_poundSign;
-      if (symbolLiteral_components.isNotEmpty)
-        _result["symbolLiteral_components"] = symbolLiteral_components;
+      if (names.isNotEmpty) _result["names"] = names;
+      if (expression_type != null)
+        _result["expression_type"] = expression_type.toJson();
+    }
+    if (kind == idl.LinkedNodeKind.doubleLiteral) {
+      if (doubleLiteral_value != 0.0)
+        _result["doubleLiteral_value"] = doubleLiteral_value.isFinite
+            ? doubleLiteral_value
+            : doubleLiteral_value.toString();
+    }
+    if (kind == idl.LinkedNodeKind.rethrowExpression) {
+      if (expression_type != null)
+        _result["expression_type"] = expression_type.toJson();
+    }
+    if (kind == idl.LinkedNodeKind.superExpression) {
       if (expression_type != null)
         _result["expression_type"] = expression_type.toJson();
     }
     if (kind == idl.LinkedNodeKind.thisExpression) {
-      if (thisExpression_thisKeyword != 0)
-        _result["thisExpression_thisKeyword"] = thisExpression_thisKeyword;
       if (expression_type != null)
         _result["expression_type"] = expression_type.toJson();
     }
+    if (kind == idl.LinkedNodeKind.integerLiteral) {
+      if (integerLiteral_value != 0)
+        _result["integerLiteral_value"] = integerLiteral_value;
+    }
+    if (kind == idl.LinkedNodeKind.interpolationString) {
+      if (interpolationString_value != '')
+        _result["interpolationString_value"] = interpolationString_value;
+    }
+    if (kind == idl.LinkedNodeKind.simpleStringLiteral) {
+      if (simpleStringLiteral_value != '')
+        _result["simpleStringLiteral_value"] = simpleStringLiteral_value;
+    }
     return _result;
   }
 
@@ -17653,16 +12829,13 @@
         "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,
+        "flags": flags,
+        "nameOffset": nameOffset,
         "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.functionExpression) {
@@ -17672,8 +12845,9 @@
         "functionExpression_formalParameters":
             functionExpression_formalParameters,
         "functionExpression_typeParameters": functionExpression_typeParameters,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
         "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.functionTypeAlias) {
@@ -17685,14 +12859,13 @@
             functionTypeAlias_formalParameters,
         "functionTypeAlias_returnType": functionTypeAlias_returnType,
         "functionTypeAlias_typeParameters": functionTypeAlias_typeParameters,
-        "typeAlias_typedefKeyword": typeAlias_typedefKeyword,
-        "typeAlias_semicolon": typeAlias_semicolon,
         "typeAlias_hasSelfReference": typeAlias_hasSelfReference,
         "codeLength": codeLength,
         "codeOffset": codeOffset,
-        "namedCompilationUnitMember_name": namedCompilationUnitMember_name,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
+        "nameOffset": nameOffset,
         "kind": kind,
+        "name": name,
         "simplyBoundable_isSimplyBounded": simplyBoundable_isSimplyBounded,
       };
     }
@@ -17701,16 +12874,14 @@
         "actualReturnType": actualReturnType,
         "genericFunctionType_typeParameters":
             genericFunctionType_typeParameters,
-        "genericFunctionType_functionKeyword":
-            genericFunctionType_functionKeyword,
         "genericFunctionType_returnType": genericFunctionType_returnType,
         "genericFunctionType_id": genericFunctionType_id,
         "genericFunctionType_formalParameters":
             genericFunctionType_formalParameters,
-        "genericFunctionType_question": genericFunctionType_question,
         "genericFunctionType_type": genericFunctionType_type,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
         "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.methodDeclaration) {
@@ -17719,20 +12890,16 @@
         "annotatedNode_comment": annotatedNode_comment,
         "annotatedNode_metadata": annotatedNode_metadata,
         "methodDeclaration_body": methodDeclaration_body,
-        "methodDeclaration_externalKeyword": methodDeclaration_externalKeyword,
         "methodDeclaration_formalParameters":
             methodDeclaration_formalParameters,
-        "methodDeclaration_operatorKeyword": methodDeclaration_operatorKeyword,
         "methodDeclaration_returnType": methodDeclaration_returnType,
-        "methodDeclaration_modifierKeyword": methodDeclaration_modifierKeyword,
-        "methodDeclaration_propertyKeyword": methodDeclaration_propertyKeyword,
-        "methodDeclaration_actualProperty": methodDeclaration_actualProperty,
         "methodDeclaration_typeParameters": methodDeclaration_typeParameters,
         "codeLength": codeLength,
         "codeOffset": codeOffset,
-        "methodDeclaration_name": methodDeclaration_name,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
+        "nameOffset": nameOffset,
         "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.fieldFormalParameter) {
@@ -17740,24 +12907,18 @@
         "actualType": actualType,
         "normalFormalParameter_metadata": normalFormalParameter_metadata,
         "fieldFormalParameter_type": fieldFormalParameter_type,
-        "fieldFormalParameter_keyword": fieldFormalParameter_keyword,
         "fieldFormalParameter_typeParameters":
             fieldFormalParameter_typeParameters,
-        "fieldFormalParameter_thisKeyword": fieldFormalParameter_thisKeyword,
         "fieldFormalParameter_formalParameters":
             fieldFormalParameter_formalParameters,
-        "fieldFormalParameter_period": fieldFormalParameter_period,
-        "normalFormalParameter_requiredKeyword":
-            normalFormalParameter_requiredKeyword,
-        "normalFormalParameter_covariantKeyword":
-            normalFormalParameter_covariantKeyword,
         "inheritsCovariant": inheritsCovariant,
-        "normalFormalParameter_identifier": normalFormalParameter_identifier,
         "codeLength": codeLength,
         "codeOffset": codeOffset,
+        "flags": flags,
+        "nameOffset": nameOffset,
         "normalFormalParameter_comment": normalFormalParameter_comment,
-        "isSynthetic": isSynthetic,
         "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.functionTypedFormalParameter) {
@@ -17770,17 +12931,14 @@
             functionTypedFormalParameter_returnType,
         "functionTypedFormalParameter_typeParameters":
             functionTypedFormalParameter_typeParameters,
-        "normalFormalParameter_requiredKeyword":
-            normalFormalParameter_requiredKeyword,
-        "normalFormalParameter_covariantKeyword":
-            normalFormalParameter_covariantKeyword,
         "inheritsCovariant": inheritsCovariant,
-        "normalFormalParameter_identifier": normalFormalParameter_identifier,
         "codeLength": codeLength,
         "codeOffset": codeOffset,
+        "flags": flags,
+        "nameOffset": nameOffset,
         "normalFormalParameter_comment": normalFormalParameter_comment,
-        "isSynthetic": isSynthetic,
         "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.simpleFormalParameter) {
@@ -17788,18 +12946,14 @@
         "actualType": actualType,
         "normalFormalParameter_metadata": normalFormalParameter_metadata,
         "simpleFormalParameter_type": simpleFormalParameter_type,
-        "simpleFormalParameter_keyword": simpleFormalParameter_keyword,
-        "normalFormalParameter_requiredKeyword":
-            normalFormalParameter_requiredKeyword,
-        "normalFormalParameter_covariantKeyword":
-            normalFormalParameter_covariantKeyword,
         "inheritsCovariant": inheritsCovariant,
-        "normalFormalParameter_identifier": normalFormalParameter_identifier,
         "codeLength": codeLength,
         "codeOffset": codeOffset,
+        "flags": flags,
+        "nameOffset": nameOffset,
         "normalFormalParameter_comment": normalFormalParameter_comment,
-        "isSynthetic": isSynthetic,
         "kind": kind,
+        "name": name,
         "topLevelTypeInferenceError": topLevelTypeInferenceError,
       };
     }
@@ -17809,13 +12963,13 @@
         "annotatedNode_comment": annotatedNode_comment,
         "annotatedNode_metadata": annotatedNode_metadata,
         "variableDeclaration_initializer": variableDeclaration_initializer,
-        "variableDeclaration_equals": variableDeclaration_equals,
-        "variableDeclaration_name": variableDeclaration_name,
         "inheritsCovariant": inheritsCovariant,
         "codeLength": codeLength,
         "codeOffset": codeOffset,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
+        "nameOffset": nameOffset,
         "kind": kind,
+        "name": name,
         "topLevelTypeInferenceError": topLevelTypeInferenceError,
         "variableDeclaration_declaration": variableDeclaration_declaration,
       };
@@ -17824,13 +12978,14 @@
       return {
         "binaryExpression_invokeType": binaryExpression_invokeType,
         "binaryExpression_leftOperand": binaryExpression_leftOperand,
-        "binaryExpression_element": binaryExpression_element,
         "binaryExpression_rightOperand": binaryExpression_rightOperand,
         "binaryExpression_elementType": binaryExpression_elementType,
+        "binaryExpression_element": binaryExpression_element,
         "binaryExpression_operator": binaryExpression_operator,
         "expression_type": expression_type,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
         "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.functionExpressionInvocation) {
@@ -17841,49 +12996,48 @@
         "invocationExpression_typeArguments":
             invocationExpression_typeArguments,
         "expression_type": expression_type,
+        "flags": flags,
         "invocationExpression_arguments": invocationExpression_arguments,
-        "isSynthetic": isSynthetic,
         "kind": kind,
+        "name": name,
       };
     }
     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,
+        "flags": flags,
         "invocationExpression_arguments": invocationExpression_arguments,
-        "isSynthetic": isSynthetic,
         "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.adjacentStrings) {
       return {
         "adjacentStrings_strings": adjacentStrings_strings,
-        "expression_type": expression_type,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
         "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.argumentList) {
       return {
         "argumentList_arguments": argumentList_arguments,
-        "argumentList_leftParenthesis": argumentList_leftParenthesis,
-        "argumentList_rightParenthesis": argumentList_rightParenthesis,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
         "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.block) {
       return {
         "block_statements": block_statements,
-        "block_leftBracket": block_leftBracket,
-        "block_rightBracket": block_rightBracket,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
         "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.cascadeExpression) {
@@ -17891,8 +13045,9 @@
         "cascadeExpression_sections": cascadeExpression_sections,
         "cascadeExpression_target": cascadeExpression_target,
         "expression_type": expression_type,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
         "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.comment) {
@@ -17900,21 +13055,21 @@
         "comment_references": comment_references,
         "comment_tokens": comment_tokens,
         "comment_type": comment_type,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
         "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.compilationUnit) {
       return {
         "compilationUnit_declarations": compilationUnit_declarations,
         "compilationUnit_scriptTag": compilationUnit_scriptTag,
-        "compilationUnit_beginToken": compilationUnit_beginToken,
-        "compilationUnit_endToken": compilationUnit_endToken,
         "codeLength": codeLength,
         "codeOffset": codeOffset,
         "compilationUnit_directives": compilationUnit_directives,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
         "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.constructorDeclaration) {
@@ -17924,30 +13079,24 @@
         "annotatedNode_comment": annotatedNode_comment,
         "annotatedNode_metadata": annotatedNode_metadata,
         "constructorDeclaration_body": constructorDeclaration_body,
-        "constructorDeclaration_constKeyword":
-            constructorDeclaration_constKeyword,
-        "constructorDeclaration_name": constructorDeclaration_name,
-        "constructorDeclaration_factoryKeyword":
-            constructorDeclaration_factoryKeyword,
         "constructorDeclaration_parameters": constructorDeclaration_parameters,
-        "constructorDeclaration_externalKeyword":
-            constructorDeclaration_externalKeyword,
-        "constructorDeclaration_period": constructorDeclaration_period,
-        "constructorDeclaration_separator": constructorDeclaration_separator,
         "constructorDeclaration_redirectedConstructor":
             constructorDeclaration_redirectedConstructor,
         "codeLength": codeLength,
         "codeOffset": codeOffset,
         "constructorDeclaration_returnType": constructorDeclaration_returnType,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
+        "nameOffset": nameOffset,
         "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.dottedName) {
       return {
         "dottedName_components": dottedName_components,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
         "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.enumDeclaration) {
@@ -17955,72 +13104,59 @@
         "enumDeclaration_constants": enumDeclaration_constants,
         "annotatedNode_comment": annotatedNode_comment,
         "annotatedNode_metadata": annotatedNode_metadata,
-        "enumDeclaration_enumKeyword": enumDeclaration_enumKeyword,
-        "enumDeclaration_rightBracket": enumDeclaration_rightBracket,
-        "enumDeclaration_leftBracket": enumDeclaration_leftBracket,
         "codeLength": codeLength,
         "codeOffset": codeOffset,
-        "namedCompilationUnitMember_name": namedCompilationUnitMember_name,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
+        "nameOffset": nameOffset,
         "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.formalParameterList) {
       return {
         "formalParameterList_parameters": formalParameterList_parameters,
-        "formalParameterList_leftDelimiter": formalParameterList_leftDelimiter,
-        "formalParameterList_rightDelimiter":
-            formalParameterList_rightDelimiter,
-        "formalParameterList_leftParenthesis":
-            formalParameterList_leftParenthesis,
-        "formalParameterList_rightParenthesis":
-            formalParameterList_rightParenthesis,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
         "kind": kind,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.hideCombinator) {
-      return {
-        "hideCombinator_hiddenNames": hideCombinator_hiddenNames,
-        "combinator_keyword": combinator_keyword,
-        "isSynthetic": isSynthetic,
-        "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.implementsClause) {
       return {
         "implementsClause_interfaces": implementsClause_interfaces,
-        "implementsClause_implementsKeyword":
-            implementsClause_implementsKeyword,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
         "kind": kind,
+        "name": name,
+      };
+    }
+    if (kind == idl.LinkedNodeKind.instanceCreationExpression) {
+      return {
+        "instanceCreationExpression_arguments":
+            instanceCreationExpression_arguments,
+        "instanceCreationExpression_constructorName":
+            instanceCreationExpression_constructorName,
+        "instanceCreationExpression_typeArguments":
+            instanceCreationExpression_typeArguments,
+        "expression_type": expression_type,
+        "flags": flags,
+        "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.labeledStatement) {
       return {
         "labeledStatement_labels": labeledStatement_labels,
         "labeledStatement_statement": labeledStatement_statement,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
         "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.libraryIdentifier) {
       return {
         "libraryIdentifier_components": libraryIdentifier_components,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
         "kind": kind,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.listLiteral) {
-      return {
-        "listLiteral_elements": listLiteral_elements,
-        "listLiteral_leftBracket": listLiteral_leftBracket,
-        "listLiteral_rightBracket": listLiteral_rightBracket,
-        "typedLiteral_constKeyword": typedLiteral_constKeyword,
-        "expression_type": expression_type,
-        "typedLiteral_typeArguments": typedLiteral_typeArguments,
-        "isSynthetic": isSynthetic,
-        "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.exportDirective) {
@@ -18028,15 +13164,15 @@
         "namespaceDirective_combinators": namespaceDirective_combinators,
         "annotatedNode_comment": annotatedNode_comment,
         "annotatedNode_metadata": annotatedNode_metadata,
-        "directive_keyword": directive_keyword,
-        "uriBasedDirective_uriElement": uriBasedDirective_uriElement,
-        "directive_semicolon": directive_semicolon,
         "namespaceDirective_configurations": namespaceDirective_configurations,
+        "flags": flags,
+        "nameOffset": nameOffset,
         "uriBasedDirective_uri": uriBasedDirective_uri,
-        "isSynthetic": isSynthetic,
         "kind": kind,
+        "name": name,
         "namespaceDirective_selectedUri": namespaceDirective_selectedUri,
         "uriBasedDirective_uriContent": uriBasedDirective_uriContent,
+        "uriBasedDirective_uriElement": uriBasedDirective_uriElement,
       };
     }
     if (kind == idl.LinkedNodeKind.importDirective) {
@@ -18044,98 +13180,98 @@
         "namespaceDirective_combinators": namespaceDirective_combinators,
         "annotatedNode_comment": annotatedNode_comment,
         "annotatedNode_metadata": annotatedNode_metadata,
-        "importDirective_prefix": importDirective_prefix,
-        "importDirective_asKeyword": importDirective_asKeyword,
-        "importDirective_deferredKeyword": importDirective_deferredKeyword,
-        "directive_keyword": directive_keyword,
-        "uriBasedDirective_uriElement": uriBasedDirective_uriElement,
-        "directive_semicolon": directive_semicolon,
+        "importDirective_prefixOffset": importDirective_prefixOffset,
         "namespaceDirective_configurations": namespaceDirective_configurations,
+        "flags": flags,
+        "importDirective_prefix": importDirective_prefix,
+        "nameOffset": nameOffset,
         "uriBasedDirective_uri": uriBasedDirective_uri,
-        "isSynthetic": isSynthetic,
         "kind": kind,
+        "name": name,
         "namespaceDirective_selectedUri": namespaceDirective_selectedUri,
         "uriBasedDirective_uriContent": uriBasedDirective_uriContent,
+        "uriBasedDirective_uriElement": uriBasedDirective_uriElement,
       };
     }
     if (kind == idl.LinkedNodeKind.onClause) {
       return {
         "onClause_superclassConstraints": onClause_superclassConstraints,
-        "onClause_onKeyword": onClause_onKeyword,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
         "kind": kind,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.setOrMapLiteral) {
-      return {
-        "setOrMapLiteral_elements": setOrMapLiteral_elements,
-        "setOrMapLiteral_leftBracket": setOrMapLiteral_leftBracket,
-        "setOrMapLiteral_rightBracket": setOrMapLiteral_rightBracket,
-        "typedLiteral_constKeyword": typedLiteral_constKeyword,
-        "setOrMapLiteral_isMap": setOrMapLiteral_isMap,
-        "expression_type": expression_type,
-        "typedLiteral_typeArguments": typedLiteral_typeArguments,
-        "isSynthetic": isSynthetic,
-        "kind": kind,
-        "setOrMapLiteral_isSet": setOrMapLiteral_isSet,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.showCombinator) {
-      return {
-        "showCombinator_shownNames": showCombinator_shownNames,
-        "combinator_keyword": combinator_keyword,
-        "isSynthetic": isSynthetic,
-        "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.stringInterpolation) {
       return {
         "stringInterpolation_elements": stringInterpolation_elements,
-        "expression_type": expression_type,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
         "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.switchStatement) {
       return {
         "switchStatement_members": switchStatement_members,
-        "switchStatement_leftParenthesis": switchStatement_leftParenthesis,
         "switchStatement_expression": switchStatement_expression,
-        "switchStatement_switchKeyword": switchStatement_switchKeyword,
-        "switchStatement_rightParenthesis": switchStatement_rightParenthesis,
-        "switchStatement_leftBracket": switchStatement_leftBracket,
-        "switchStatement_rightBracket": switchStatement_rightBracket,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
         "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.tryStatement) {
       return {
         "tryStatement_catchClauses": tryStatement_catchClauses,
         "tryStatement_body": tryStatement_body,
-        "tryStatement_finallyKeyword": tryStatement_finallyKeyword,
         "tryStatement_finallyBlock": tryStatement_finallyBlock,
-        "tryStatement_tryKeyword": tryStatement_tryKeyword,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
         "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.typeArgumentList) {
       return {
         "typeArgumentList_arguments": typeArgumentList_arguments,
-        "typeArgumentList_leftBracket": typeArgumentList_leftBracket,
-        "typeArgumentList_rightBracket": typeArgumentList_rightBracket,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
         "kind": kind,
+        "name": name,
+      };
+    }
+    if (kind == idl.LinkedNodeKind.listLiteral) {
+      return {
+        "typedLiteral_typeArguments": typedLiteral_typeArguments,
+        "listLiteral_elements": listLiteral_elements,
+        "expression_type": expression_type,
+        "flags": flags,
+        "kind": kind,
+        "name": name,
+      };
+    }
+    if (kind == idl.LinkedNodeKind.setOrMapLiteral) {
+      return {
+        "typedLiteral_typeArguments": typedLiteral_typeArguments,
+        "setOrMapLiteral_elements": setOrMapLiteral_elements,
+        "expression_type": expression_type,
+        "flags": flags,
+        "kind": kind,
+        "name": name,
+      };
+    }
+    if (kind == idl.LinkedNodeKind.typeName) {
+      return {
+        "typeName_typeArguments": typeName_typeArguments,
+        "typeName_name": typeName_name,
+        "typeName_type": typeName_type,
+        "flags": flags,
+        "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.typeParameterList) {
       return {
         "typeParameterList_typeParameters": typeParameterList_typeParameters,
-        "typeParameterList_leftBracket": typeParameterList_leftBracket,
-        "typeParameterList_rightBracket": typeParameterList_rightBracket,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
         "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.variableDeclarationList) {
@@ -18144,19 +13280,17 @@
         "annotatedNode_comment": annotatedNode_comment,
         "annotatedNode_metadata": annotatedNode_metadata,
         "variableDeclarationList_type": variableDeclarationList_type,
-        "variableDeclarationList_keyword": variableDeclarationList_keyword,
-        "variableDeclarationList_lateKeyword":
-            variableDeclarationList_lateKeyword,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
         "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.withClause) {
       return {
         "withClause_mixinTypes": withClause_mixinTypes,
-        "withClause_withKeyword": withClause_withKeyword,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
         "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.classDeclaration) {
@@ -18164,14 +13298,8 @@
         "annotatedNode_comment": annotatedNode_comment,
         "annotatedNode_metadata": annotatedNode_metadata,
         "classDeclaration_extendsClause": classDeclaration_extendsClause,
-        "classDeclaration_abstractKeyword": classDeclaration_abstractKeyword,
         "classDeclaration_withClause": classDeclaration_withClause,
         "classDeclaration_nativeClause": classDeclaration_nativeClause,
-        "classDeclaration_classKeyword": classDeclaration_classKeyword,
-        "classOrMixinDeclaration_rightBracket":
-            classOrMixinDeclaration_rightBracket,
-        "classOrMixinDeclaration_leftBracket":
-            classOrMixinDeclaration_leftBracket,
         "classDeclaration_isDartObject": classDeclaration_isDartObject,
         "classOrMixinDeclaration_implementsClause":
             classOrMixinDeclaration_implementsClause,
@@ -18180,9 +13308,10 @@
             classOrMixinDeclaration_typeParameters,
         "codeLength": codeLength,
         "codeOffset": codeOffset,
-        "namedCompilationUnitMember_name": namedCompilationUnitMember_name,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
+        "nameOffset": nameOffset,
         "kind": kind,
+        "name": name,
         "simplyBoundable_isSimplyBounded": simplyBoundable_isSimplyBounded,
       };
     }
@@ -18191,18 +13320,15 @@
         "annotatedNode_comment": annotatedNode_comment,
         "annotatedNode_metadata": annotatedNode_metadata,
         "classTypeAlias_typeParameters": classTypeAlias_typeParameters,
-        "classTypeAlias_abstractKeyword": classTypeAlias_abstractKeyword,
         "classTypeAlias_superclass": classTypeAlias_superclass,
         "classTypeAlias_withClause": classTypeAlias_withClause,
-        "classTypeAlias_equals": classTypeAlias_equals,
-        "typeAlias_typedefKeyword": typeAlias_typedefKeyword,
-        "typeAlias_semicolon": typeAlias_semicolon,
         "classTypeAlias_implementsClause": classTypeAlias_implementsClause,
         "codeLength": codeLength,
         "codeOffset": codeOffset,
-        "namedCompilationUnitMember_name": namedCompilationUnitMember_name,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
+        "nameOffset": nameOffset,
         "kind": kind,
+        "name": name,
         "simplyBoundable_isSimplyBounded": simplyBoundable_isSimplyBounded,
       };
     }
@@ -18211,19 +13337,20 @@
         "annotatedNode_comment": annotatedNode_comment,
         "annotatedNode_metadata": annotatedNode_metadata,
         "declaredIdentifier_identifier": declaredIdentifier_identifier,
-        "declaredIdentifier_keyword": declaredIdentifier_keyword,
         "declaredIdentifier_type": declaredIdentifier_type,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
         "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.enumConstantDeclaration) {
       return {
         "annotatedNode_comment": annotatedNode_comment,
         "annotatedNode_metadata": annotatedNode_metadata,
-        "enumConstantDeclaration_name": enumConstantDeclaration_name,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
+        "nameOffset": nameOffset,
         "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.fieldDeclaration) {
@@ -18231,11 +13358,9 @@
         "annotatedNode_comment": annotatedNode_comment,
         "annotatedNode_metadata": annotatedNode_metadata,
         "fieldDeclaration_fields": fieldDeclaration_fields,
-        "fieldDeclaration_covariantKeyword": fieldDeclaration_covariantKeyword,
-        "fieldDeclaration_staticKeyword": fieldDeclaration_staticKeyword,
-        "fieldDeclaration_semicolon": fieldDeclaration_semicolon,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
         "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.genericTypeAlias) {
@@ -18244,15 +13369,13 @@
         "annotatedNode_metadata": annotatedNode_metadata,
         "genericTypeAlias_typeParameters": genericTypeAlias_typeParameters,
         "genericTypeAlias_functionType": genericTypeAlias_functionType,
-        "genericTypeAlias_equals": genericTypeAlias_equals,
-        "typeAlias_typedefKeyword": typeAlias_typedefKeyword,
-        "typeAlias_semicolon": typeAlias_semicolon,
         "typeAlias_hasSelfReference": typeAlias_hasSelfReference,
         "codeLength": codeLength,
         "codeOffset": codeOffset,
-        "namedCompilationUnitMember_name": namedCompilationUnitMember_name,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
+        "nameOffset": nameOffset,
         "kind": kind,
+        "name": name,
         "simplyBoundable_isSimplyBounded": simplyBoundable_isSimplyBounded,
       };
     }
@@ -18261,10 +13384,9 @@
         "annotatedNode_comment": annotatedNode_comment,
         "annotatedNode_metadata": annotatedNode_metadata,
         "libraryDirective_name": libraryDirective_name,
-        "directive_keyword": directive_keyword,
-        "directive_semicolon": directive_semicolon,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
         "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.mixinDeclaration) {
@@ -18272,11 +13394,6 @@
         "annotatedNode_comment": annotatedNode_comment,
         "annotatedNode_metadata": annotatedNode_metadata,
         "mixinDeclaration_onClause": mixinDeclaration_onClause,
-        "mixinDeclaration_mixinKeyword": mixinDeclaration_mixinKeyword,
-        "classOrMixinDeclaration_rightBracket":
-            classOrMixinDeclaration_rightBracket,
-        "classOrMixinDeclaration_leftBracket":
-            classOrMixinDeclaration_leftBracket,
         "classOrMixinDeclaration_implementsClause":
             classOrMixinDeclaration_implementsClause,
         "classOrMixinDeclaration_members": classOrMixinDeclaration_members,
@@ -18284,11 +13401,12 @@
             classOrMixinDeclaration_typeParameters,
         "codeLength": codeLength,
         "codeOffset": codeOffset,
-        "namedCompilationUnitMember_name": namedCompilationUnitMember_name,
-        "isSynthetic": isSynthetic,
-        "kind": kind,
         "mixinDeclaration_superInvokedNames":
             mixinDeclaration_superInvokedNames,
+        "flags": flags,
+        "nameOffset": nameOffset,
+        "kind": kind,
+        "name": name,
         "simplyBoundable_isSimplyBounded": simplyBoundable_isSimplyBounded,
       };
     }
@@ -18296,13 +13414,13 @@
       return {
         "annotatedNode_comment": annotatedNode_comment,
         "annotatedNode_metadata": annotatedNode_metadata,
-        "directive_keyword": directive_keyword,
-        "uriBasedDirective_uriElement": uriBasedDirective_uriElement,
-        "directive_semicolon": directive_semicolon,
+        "flags": flags,
+        "nameOffset": nameOffset,
         "uriBasedDirective_uri": uriBasedDirective_uri,
-        "isSynthetic": isSynthetic,
         "kind": kind,
+        "name": name,
         "uriBasedDirective_uriContent": uriBasedDirective_uriContent,
+        "uriBasedDirective_uriElement": uriBasedDirective_uriElement,
       };
     }
     if (kind == idl.LinkedNodeKind.partOfDirective) {
@@ -18311,11 +13429,9 @@
         "annotatedNode_metadata": annotatedNode_metadata,
         "partOfDirective_libraryName": partOfDirective_libraryName,
         "partOfDirective_uri": partOfDirective_uri,
-        "partOfDirective_ofKeyword": partOfDirective_ofKeyword,
-        "directive_keyword": directive_keyword,
-        "directive_semicolon": directive_semicolon,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
         "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.topLevelVariableDeclaration) {
@@ -18324,10 +13440,9 @@
         "annotatedNode_metadata": annotatedNode_metadata,
         "topLevelVariableDeclaration_variableList":
             topLevelVariableDeclaration_variableList,
-        "topLevelVariableDeclaration_semicolon":
-            topLevelVariableDeclaration_semicolon,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
         "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.typeParameter) {
@@ -18335,732 +13450,651 @@
         "annotatedNode_comment": annotatedNode_comment,
         "annotatedNode_metadata": annotatedNode_metadata,
         "typeParameter_bound": typeParameter_bound,
-        "typeParameter_extendsKeyword": typeParameter_extendsKeyword,
-        "typeParameter_name": typeParameter_name,
         "typeParameter_defaultType": typeParameter_defaultType,
         "codeLength": codeLength,
         "codeOffset": codeOffset,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
+        "nameOffset": nameOffset,
         "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.switchCase) {
       return {
         "switchMember_statements": switchMember_statements,
         "switchCase_expression": switchCase_expression,
-        "switchMember_keyword": switchMember_keyword,
-        "switchMember_colon": switchMember_colon,
         "switchMember_labels": switchMember_labels,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
         "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.switchDefault) {
       return {
         "switchMember_statements": switchMember_statements,
-        "switchMember_keyword": switchMember_keyword,
-        "switchMember_colon": switchMember_colon,
         "switchMember_labels": switchMember_labels,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
         "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.annotation) {
       return {
         "annotation_arguments": annotation_arguments,
-        "annotation_atSign": annotation_atSign,
         "annotation_constructorName": annotation_constructorName,
         "annotation_element": annotation_element,
         "annotation_elementType": annotation_elementType,
         "annotation_name": annotation_name,
-        "annotation_period": annotation_period,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
         "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.asExpression) {
       return {
         "asExpression_expression": asExpression_expression,
-        "asExpression_asOperator": asExpression_asOperator,
         "asExpression_type": asExpression_type,
         "expression_type": expression_type,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
         "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.assertInitializer) {
       return {
         "assertInitializer_condition": assertInitializer_condition,
-        "assertInitializer_assertKeyword": assertInitializer_assertKeyword,
         "assertInitializer_message": assertInitializer_message,
-        "assertInitializer_leftParenthesis": assertInitializer_leftParenthesis,
-        "assertInitializer_comma": assertInitializer_comma,
-        "assertInitializer_rightParenthesis":
-            assertInitializer_rightParenthesis,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
         "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.assertStatement) {
       return {
         "assertStatement_condition": assertStatement_condition,
-        "assertStatement_assertKeyword": assertStatement_assertKeyword,
         "assertStatement_message": assertStatement_message,
-        "assertStatement_leftParenthesis": assertStatement_leftParenthesis,
-        "assertStatement_comma": assertStatement_comma,
-        "assertStatement_rightParenthesis": assertStatement_rightParenthesis,
-        "assertStatement_semicolon": assertStatement_semicolon,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
         "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.assignmentExpression) {
       return {
         "assignmentExpression_leftHandSide": assignmentExpression_leftHandSide,
-        "assignmentExpression_element": assignmentExpression_element,
         "assignmentExpression_rightHandSide":
             assignmentExpression_rightHandSide,
         "assignmentExpression_elementType": assignmentExpression_elementType,
+        "assignmentExpression_element": assignmentExpression_element,
         "assignmentExpression_operator": assignmentExpression_operator,
         "expression_type": expression_type,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
         "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.awaitExpression) {
       return {
         "awaitExpression_expression": awaitExpression_expression,
-        "awaitExpression_awaitKeyword": awaitExpression_awaitKeyword,
         "expression_type": expression_type,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
         "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.blockFunctionBody) {
       return {
         "blockFunctionBody_block": blockFunctionBody_block,
-        "blockFunctionBody_keyword": blockFunctionBody_keyword,
-        "blockFunctionBody_star": blockFunctionBody_star,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
         "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.breakStatement) {
       return {
         "breakStatement_label": breakStatement_label,
-        "breakStatement_breakKeyword": breakStatement_breakKeyword,
-        "breakStatement_semicolon": breakStatement_semicolon,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
         "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.catchClause) {
       return {
         "catchClause_body": catchClause_body,
-        "catchClause_catchKeyword": catchClause_catchKeyword,
         "catchClause_exceptionParameter": catchClause_exceptionParameter,
-        "catchClause_leftParenthesis": catchClause_leftParenthesis,
         "catchClause_exceptionType": catchClause_exceptionType,
-        "catchClause_comma": catchClause_comma,
-        "catchClause_onKeyword": catchClause_onKeyword,
-        "catchClause_rightParenthesis": catchClause_rightParenthesis,
         "catchClause_stackTraceParameter": catchClause_stackTraceParameter,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
         "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.commentReference) {
       return {
         "commentReference_identifier": commentReference_identifier,
-        "commentReference_newKeyword": commentReference_newKeyword,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
         "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.conditionalExpression) {
       return {
         "conditionalExpression_condition": conditionalExpression_condition,
-        "conditionalExpression_colon": conditionalExpression_colon,
         "conditionalExpression_elseExpression":
             conditionalExpression_elseExpression,
         "conditionalExpression_thenExpression":
             conditionalExpression_thenExpression,
-        "conditionalExpression_question": conditionalExpression_question,
         "expression_type": expression_type,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
         "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.configuration) {
       return {
         "configuration_name": configuration_name,
-        "configuration_ifKeyword": configuration_ifKeyword,
         "configuration_value": configuration_value,
-        "configuration_rightParenthesis": configuration_rightParenthesis,
         "configuration_uri": configuration_uri,
-        "configuration_leftParenthesis": configuration_leftParenthesis,
-        "configuration_equalToken": configuration_equalToken,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
         "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.constructorFieldInitializer) {
       return {
         "constructorFieldInitializer_expression":
             constructorFieldInitializer_expression,
-        "constructorFieldInitializer_equals":
-            constructorFieldInitializer_equals,
         "constructorFieldInitializer_fieldName":
             constructorFieldInitializer_fieldName,
-        "constructorFieldInitializer_thisKeyword":
-            constructorFieldInitializer_thisKeyword,
-        "constructorFieldInitializer_period":
-            constructorFieldInitializer_period,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
         "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.constructorName) {
       return {
         "constructorName_name": constructorName_name,
-        "constructorName_element": constructorName_element,
         "constructorName_type": constructorName_type,
         "constructorName_elementType": constructorName_elementType,
-        "constructorName_period": constructorName_period,
-        "isSynthetic": isSynthetic,
+        "constructorName_element": constructorName_element,
+        "flags": flags,
         "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.continueStatement) {
       return {
         "continueStatement_label": continueStatement_label,
-        "continueStatement_continueKeyword": continueStatement_continueKeyword,
-        "continueStatement_semicolon": continueStatement_semicolon,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
         "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.defaultFormalParameter) {
       return {
         "defaultFormalParameter_defaultValue":
             defaultFormalParameter_defaultValue,
-        "defaultFormalParameter_separator": defaultFormalParameter_separator,
         "defaultFormalParameter_parameter": defaultFormalParameter_parameter,
         "codeLength": codeLength,
         "codeOffset": codeOffset,
         "defaultFormalParameter_kind": defaultFormalParameter_kind,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
         "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.doStatement) {
       return {
         "doStatement_body": doStatement_body,
-        "doStatement_leftParenthesis": doStatement_leftParenthesis,
         "doStatement_condition": doStatement_condition,
-        "doStatement_doKeyword": doStatement_doKeyword,
-        "doStatement_rightParenthesis": doStatement_rightParenthesis,
-        "doStatement_semicolon": doStatement_semicolon,
-        "doStatement_whileKeyword": doStatement_whileKeyword,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
         "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.expressionFunctionBody) {
       return {
         "expressionFunctionBody_expression": expressionFunctionBody_expression,
-        "expressionFunctionBody_arrow": expressionFunctionBody_arrow,
-        "expressionFunctionBody_semicolon": expressionFunctionBody_semicolon,
-        "expressionFunctionBody_keyword": expressionFunctionBody_keyword,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
         "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.expressionStatement) {
       return {
         "expressionStatement_expression": expressionStatement_expression,
-        "expressionStatement_semicolon": expressionStatement_semicolon,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
         "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.extendsClause) {
       return {
         "extendsClause_superclass": extendsClause_superclass,
-        "extendsClause_extendsKeyword": extendsClause_extendsKeyword,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
         "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.forEachPartsWithDeclaration) {
       return {
         "forEachParts_iterable": forEachParts_iterable,
-        "forEachParts_inKeyword": forEachParts_inKeyword,
         "forEachPartsWithDeclaration_loopVariable":
             forEachPartsWithDeclaration_loopVariable,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
         "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.forEachPartsWithIdentifier) {
       return {
         "forEachParts_iterable": forEachParts_iterable,
-        "forEachParts_inKeyword": forEachParts_inKeyword,
         "forEachPartsWithIdentifier_identifier":
             forEachPartsWithIdentifier_identifier,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
         "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.forElement) {
       return {
         "forMixin_forLoopParts": forMixin_forLoopParts,
-        "forMixin_awaitKeyword": forMixin_awaitKeyword,
         "forElement_body": forElement_body,
-        "forMixin_leftParenthesis": forMixin_leftParenthesis,
-        "forMixin_forKeyword": forMixin_forKeyword,
-        "forMixin_rightParenthesis": forMixin_rightParenthesis,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
         "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.forStatement) {
       return {
         "forMixin_forLoopParts": forMixin_forLoopParts,
-        "forMixin_awaitKeyword": forMixin_awaitKeyword,
         "forStatement_body": forStatement_body,
-        "forMixin_leftParenthesis": forMixin_leftParenthesis,
-        "forMixin_forKeyword": forMixin_forKeyword,
-        "forMixin_rightParenthesis": forMixin_rightParenthesis,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
         "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.forPartsWithDeclarations) {
       return {
         "forParts_condition": forParts_condition,
-        "forParts_leftSeparator": forParts_leftSeparator,
         "forPartsWithDeclarations_variables":
             forPartsWithDeclarations_variables,
-        "forParts_rightSeparator": forParts_rightSeparator,
         "forParts_updaters": forParts_updaters,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
         "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.forPartsWithExpression) {
       return {
         "forParts_condition": forParts_condition,
-        "forParts_leftSeparator": forParts_leftSeparator,
         "forPartsWithExpression_initialization":
             forPartsWithExpression_initialization,
-        "forParts_rightSeparator": forParts_rightSeparator,
         "forParts_updaters": forParts_updaters,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
         "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.functionDeclarationStatement) {
       return {
         "functionDeclarationStatement_functionDeclaration":
             functionDeclarationStatement_functionDeclaration,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
         "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.ifElement) {
       return {
         "ifMixin_condition": ifMixin_condition,
-        "ifMixin_elseKeyword": ifMixin_elseKeyword,
-        "ifMixin_leftParenthesis": ifMixin_leftParenthesis,
         "ifElement_thenElement": ifElement_thenElement,
-        "ifMixin_ifKeyword": ifMixin_ifKeyword,
-        "ifMixin_rightParenthesis": ifMixin_rightParenthesis,
         "ifElement_elseElement": ifElement_elseElement,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
         "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.ifStatement) {
       return {
         "ifMixin_condition": ifMixin_condition,
-        "ifMixin_elseKeyword": ifMixin_elseKeyword,
         "ifStatement_elseStatement": ifStatement_elseStatement,
-        "ifMixin_leftParenthesis": ifMixin_leftParenthesis,
         "ifStatement_thenStatement": ifStatement_thenStatement,
-        "ifMixin_ifKeyword": ifMixin_ifKeyword,
-        "ifMixin_rightParenthesis": ifMixin_rightParenthesis,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
         "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.indexExpression) {
       return {
         "indexExpression_index": indexExpression_index,
-        "indexExpression_element": indexExpression_element,
         "indexExpression_target": indexExpression_target,
-        "indexExpression_leftBracket": indexExpression_leftBracket,
         "indexExpression_elementType": indexExpression_elementType,
-        "indexExpression_period": indexExpression_period,
-        "indexExpression_rightBracket": indexExpression_rightBracket,
+        "indexExpression_element": indexExpression_element,
         "expression_type": expression_type,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
         "kind": kind,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.instanceCreationExpression) {
-      return {
-        "instanceCreationExpression_arguments":
-            instanceCreationExpression_arguments,
-        "instanceCreationExpression_keyword":
-            instanceCreationExpression_keyword,
-        "instanceCreationExpression_constructorName":
-            instanceCreationExpression_constructorName,
-        "instanceCreationExpression_typeArguments":
-            instanceCreationExpression_typeArguments,
-        "expression_type": expression_type,
-        "isSynthetic": isSynthetic,
-        "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.interpolationExpression) {
       return {
         "interpolationExpression_expression":
             interpolationExpression_expression,
-        "interpolationExpression_leftBracket":
-            interpolationExpression_leftBracket,
-        "interpolationExpression_rightBracket":
-            interpolationExpression_rightBracket,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
         "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.isExpression) {
       return {
         "isExpression_expression": isExpression_expression,
-        "isExpression_isOperator": isExpression_isOperator,
         "isExpression_type": isExpression_type,
-        "isExpression_notOperator": isExpression_notOperator,
-        "expression_type": expression_type,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
         "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.label) {
       return {
         "label_label": label_label,
-        "label_colon": label_colon,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
         "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.mapLiteralEntry) {
       return {
         "mapLiteralEntry_key": mapLiteralEntry_key,
-        "mapLiteralEntry_separator": mapLiteralEntry_separator,
         "mapLiteralEntry_value": mapLiteralEntry_value,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
         "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.namedExpression) {
       return {
         "namedExpression_expression": namedExpression_expression,
         "namedExpression_name": namedExpression_name,
-        "expression_type": expression_type,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
         "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.nativeClause) {
       return {
         "nativeClause_name": nativeClause_name,
-        "nativeClause_nativeKeyword": nativeClause_nativeKeyword,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
         "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.nativeFunctionBody) {
       return {
         "nativeFunctionBody_stringLiteral": nativeFunctionBody_stringLiteral,
-        "nativeFunctionBody_nativeKeyword": nativeFunctionBody_nativeKeyword,
-        "nativeFunctionBody_semicolon": nativeFunctionBody_semicolon,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
         "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.parenthesizedExpression) {
       return {
         "parenthesizedExpression_expression":
             parenthesizedExpression_expression,
-        "parenthesizedExpression_leftParenthesis":
-            parenthesizedExpression_leftParenthesis,
-        "parenthesizedExpression_rightParenthesis":
-            parenthesizedExpression_rightParenthesis,
         "expression_type": expression_type,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
         "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.postfixExpression) {
       return {
         "postfixExpression_operand": postfixExpression_operand,
-        "postfixExpression_element": postfixExpression_element,
         "postfixExpression_elementType": postfixExpression_elementType,
+        "postfixExpression_element": postfixExpression_element,
         "postfixExpression_operator": postfixExpression_operator,
         "expression_type": expression_type,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
         "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.prefixedIdentifier) {
       return {
         "prefixedIdentifier_identifier": prefixedIdentifier_identifier,
-        "prefixedIdentifier_period": prefixedIdentifier_period,
         "prefixedIdentifier_prefix": prefixedIdentifier_prefix,
         "expression_type": expression_type,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
         "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.prefixExpression) {
       return {
         "prefixExpression_operand": prefixExpression_operand,
-        "prefixExpression_element": prefixExpression_element,
         "prefixExpression_elementType": prefixExpression_elementType,
+        "prefixExpression_element": prefixExpression_element,
         "prefixExpression_operator": prefixExpression_operator,
         "expression_type": expression_type,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
         "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.propertyAccess) {
       return {
         "propertyAccess_propertyName": propertyAccess_propertyName,
-        "propertyAccess_operator": propertyAccess_operator,
         "propertyAccess_target": propertyAccess_target,
+        "propertyAccess_operator": propertyAccess_operator,
         "expression_type": expression_type,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
         "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.redirectingConstructorInvocation) {
       return {
         "redirectingConstructorInvocation_arguments":
             redirectingConstructorInvocation_arguments,
-        "redirectingConstructorInvocation_element":
-            redirectingConstructorInvocation_element,
         "redirectingConstructorInvocation_constructorName":
             redirectingConstructorInvocation_constructorName,
-        "redirectingConstructorInvocation_thisKeyword":
-            redirectingConstructorInvocation_thisKeyword,
         "redirectingConstructorInvocation_elementType":
             redirectingConstructorInvocation_elementType,
-        "redirectingConstructorInvocation_period":
-            redirectingConstructorInvocation_period,
-        "isSynthetic": isSynthetic,
+        "redirectingConstructorInvocation_element":
+            redirectingConstructorInvocation_element,
+        "flags": flags,
         "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.returnStatement) {
       return {
         "returnStatement_expression": returnStatement_expression,
-        "returnStatement_returnKeyword": returnStatement_returnKeyword,
-        "returnStatement_semicolon": returnStatement_semicolon,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
         "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.spreadElement) {
       return {
         "spreadElement_expression": spreadElement_expression,
-        "spreadElement_spreadOperator": spreadElement_spreadOperator,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
         "kind": kind,
+        "name": name,
+        "spreadElement_spreadOperator": spreadElement_spreadOperator,
       };
     }
     if (kind == idl.LinkedNodeKind.superConstructorInvocation) {
       return {
         "superConstructorInvocation_arguments":
             superConstructorInvocation_arguments,
-        "superConstructorInvocation_element":
-            superConstructorInvocation_element,
         "superConstructorInvocation_constructorName":
             superConstructorInvocation_constructorName,
-        "superConstructorInvocation_superKeyword":
-            superConstructorInvocation_superKeyword,
         "superConstructorInvocation_elementType":
             superConstructorInvocation_elementType,
-        "superConstructorInvocation_period": superConstructorInvocation_period,
-        "isSynthetic": isSynthetic,
+        "superConstructorInvocation_element":
+            superConstructorInvocation_element,
+        "flags": flags,
         "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.throwExpression) {
       return {
         "throwExpression_expression": throwExpression_expression,
-        "throwExpression_throwKeyword": throwExpression_throwKeyword,
         "expression_type": expression_type,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
         "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,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.variableDeclarationStatement) {
       return {
         "variableDeclarationStatement_variables":
             variableDeclarationStatement_variables,
-        "variableDeclarationStatement_semicolon":
-            variableDeclarationStatement_semicolon,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
         "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.whileStatement) {
       return {
         "whileStatement_body": whileStatement_body,
-        "whileStatement_leftParenthesis": whileStatement_leftParenthesis,
         "whileStatement_condition": whileStatement_condition,
-        "whileStatement_whileKeyword": whileStatement_whileKeyword,
-        "whileStatement_rightParenthesis": whileStatement_rightParenthesis,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
         "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.yieldStatement) {
       return {
         "yieldStatement_expression": yieldStatement_expression,
-        "yieldStatement_yieldKeyword": yieldStatement_yieldKeyword,
-        "yieldStatement_semicolon": yieldStatement_semicolon,
-        "yieldStatement_star": yieldStatement_star,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
         "kind": kind,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.booleanLiteral) {
-      return {
-        "booleanLiteral_literal": booleanLiteral_literal,
-        "booleanLiteral_value": booleanLiteral_value,
-        "expression_type": expression_type,
-        "isSynthetic": isSynthetic,
-        "kind": kind,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.doubleLiteral) {
-      return {
-        "doubleLiteral_literal": doubleLiteral_literal,
-        "doubleLiteral_value": doubleLiteral_value,
-        "expression_type": expression_type,
-        "isSynthetic": isSynthetic,
-        "kind": kind,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.emptyFunctionBody) {
-      return {
-        "emptyFunctionBody_semicolon": emptyFunctionBody_semicolon,
-        "isSynthetic": isSynthetic,
-        "kind": kind,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.emptyStatement) {
-      return {
-        "emptyStatement_semicolon": emptyStatement_semicolon,
-        "isSynthetic": isSynthetic,
-        "kind": kind,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.integerLiteral) {
-      return {
-        "integerLiteral_literal": integerLiteral_literal,
-        "integerLiteral_value": integerLiteral_value,
-        "expression_type": expression_type,
-        "isSynthetic": isSynthetic,
-        "kind": kind,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.interpolationString) {
-      return {
-        "interpolationString_token": interpolationString_token,
-        "interpolationString_value": interpolationString_value,
-        "isSynthetic": isSynthetic,
-        "kind": kind,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.nullLiteral) {
-      return {
-        "nullLiteral_literal": nullLiteral_literal,
-        "expression_type": expression_type,
-        "isSynthetic": isSynthetic,
-        "kind": kind,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.rethrowExpression) {
-      return {
-        "rethrowExpression_rethrowKeyword": rethrowExpression_rethrowKeyword,
-        "expression_type": expression_type,
-        "isSynthetic": isSynthetic,
-        "kind": kind,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.scriptTag) {
-      return {
-        "scriptTag_scriptTag": scriptTag_scriptTag,
-        "isSynthetic": isSynthetic,
-        "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.simpleIdentifier) {
       return {
-        "simpleIdentifier_element": simpleIdentifier_element,
         "simpleIdentifier_elementType": simpleIdentifier_elementType,
-        "simpleIdentifier_token": simpleIdentifier_token,
-        "simpleIdentifier_isDeclaration": simpleIdentifier_isDeclaration,
+        "simpleIdentifier_element": simpleIdentifier_element,
         "expression_type": expression_type,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
         "kind": kind,
+        "name": name,
       };
     }
-    if (kind == idl.LinkedNodeKind.simpleStringLiteral) {
+    if (kind == idl.LinkedNodeKind.emptyFunctionBody) {
       return {
-        "simpleStringLiteral_token": simpleStringLiteral_token,
-        "expression_type": expression_type,
-        "isSynthetic": isSynthetic,
+        "emptyFunctionBody_fake": emptyFunctionBody_fake,
+        "flags": flags,
         "kind": kind,
-        "simpleStringLiteral_value": simpleStringLiteral_value,
+        "name": name,
       };
     }
-    if (kind == idl.LinkedNodeKind.superExpression) {
+    if (kind == idl.LinkedNodeKind.emptyStatement) {
       return {
-        "superExpression_superKeyword": superExpression_superKeyword,
-        "expression_type": expression_type,
-        "isSynthetic": isSynthetic,
+        "emptyStatement_fake": emptyStatement_fake,
+        "flags": flags,
         "kind": kind,
+        "name": name,
+      };
+    }
+    if (kind == idl.LinkedNodeKind.nullLiteral) {
+      return {
+        "nullLiteral_fake": nullLiteral_fake,
+        "expression_type": expression_type,
+        "flags": flags,
+        "kind": kind,
+        "name": name,
+      };
+    }
+    if (kind == idl.LinkedNodeKind.booleanLiteral) {
+      return {
+        "booleanLiteral_value": booleanLiteral_value,
+        "flags": flags,
+        "kind": kind,
+        "name": name,
+      };
+    }
+    if (kind == idl.LinkedNodeKind.hideCombinator) {
+      return {
+        "names": names,
+        "flags": flags,
+        "kind": kind,
+        "name": name,
+      };
+    }
+    if (kind == idl.LinkedNodeKind.showCombinator) {
+      return {
+        "names": names,
+        "flags": flags,
+        "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.symbolLiteral) {
       return {
-        "symbolLiteral_poundSign": symbolLiteral_poundSign,
-        "symbolLiteral_components": symbolLiteral_components,
+        "names": names,
         "expression_type": expression_type,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
         "kind": kind,
+        "name": name,
+      };
+    }
+    if (kind == idl.LinkedNodeKind.doubleLiteral) {
+      return {
+        "doubleLiteral_value": doubleLiteral_value,
+        "flags": flags,
+        "kind": kind,
+        "name": name,
+      };
+    }
+    if (kind == idl.LinkedNodeKind.rethrowExpression) {
+      return {
+        "expression_type": expression_type,
+        "flags": flags,
+        "kind": kind,
+        "name": name,
+      };
+    }
+    if (kind == idl.LinkedNodeKind.superExpression) {
+      return {
+        "expression_type": expression_type,
+        "flags": flags,
+        "kind": kind,
+        "name": name,
       };
     }
     if (kind == idl.LinkedNodeKind.thisExpression) {
       return {
-        "thisExpression_thisKeyword": thisExpression_thisKeyword,
         "expression_type": expression_type,
-        "isSynthetic": isSynthetic,
+        "flags": flags,
         "kind": kind,
+        "name": name,
+      };
+    }
+    if (kind == idl.LinkedNodeKind.integerLiteral) {
+      return {
+        "flags": flags,
+        "integerLiteral_value": integerLiteral_value,
+        "kind": kind,
+        "name": name,
+      };
+    }
+    if (kind == idl.LinkedNodeKind.interpolationString) {
+      return {
+        "flags": flags,
+        "interpolationString_value": interpolationString_value,
+        "kind": kind,
+        "name": name,
+      };
+    }
+    if (kind == idl.LinkedNodeKind.simpleStringLiteral) {
+      return {
+        "flags": flags,
+        "kind": kind,
+        "name": name,
+        "simpleStringLiteral_value": simpleStringLiteral_value,
       };
     }
     throw StateError("Unexpected $kind");
@@ -20223,11 +15257,27 @@
 class LinkedNodeUnitBuilder extends Object
     with _LinkedNodeUnitMixin
     implements idl.LinkedNodeUnit {
+  List<LinkedNodeBuilder> _genericFunctionTypes;
   bool _isSynthetic;
   List<int> _lineStarts;
   LinkedNodeBuilder _node;
   UnlinkedTokensBuilder _tokens;
   String _uriStr;
+  bool _isNNBD;
+
+  @override
+  List<LinkedNodeBuilder> get genericFunctionTypes =>
+      _genericFunctionTypes ??= <LinkedNodeBuilder>[];
+
+  /// All generic function types in the unit - in generic type aliases, or used
+  /// directly as type annotations.
+  ///
+  /// They are requested in two cases: when we are reading a node that contains
+  /// them (e.g. a return type of a method), or when we run over unresolved
+  /// AST in declaration resolver.
+  set genericFunctionTypes(List<LinkedNodeBuilder> value) {
+    this._genericFunctionTypes = value;
+  }
 
   @override
   bool get isSynthetic => _isSynthetic ??= false;
@@ -20266,20 +15316,32 @@
     this._uriStr = value;
   }
 
+  @override
+  bool get isNNBD => _isNNBD ??= false;
+
+  set isNNBD(bool value) {
+    this._isNNBD = value;
+  }
+
   LinkedNodeUnitBuilder(
-      {bool isSynthetic,
+      {List<LinkedNodeBuilder> genericFunctionTypes,
+      bool isSynthetic,
       List<int> lineStarts,
       LinkedNodeBuilder node,
       UnlinkedTokensBuilder tokens,
-      String uriStr})
-      : _isSynthetic = isSynthetic,
+      String uriStr,
+      bool isNNBD})
+      : _genericFunctionTypes = genericFunctionTypes,
+        _isSynthetic = isSynthetic,
         _lineStarts = lineStarts,
         _node = node,
         _tokens = tokens,
-        _uriStr = uriStr;
+        _uriStr = uriStr,
+        _isNNBD = isNNBD;
 
   /// Flush [informative] data recursively.
   void flushInformative() {
+    _genericFunctionTypes?.forEach((b) => b.flushInformative());
     _lineStarts = null;
     _node?.flushInformative();
     _tokens?.flushInformative();
@@ -20293,13 +15355,27 @@
     signature.addBool(this._node != null);
     this._node?.collectApiSignature(signature);
     signature.addBool(this._isSynthetic == true);
+    if (this._genericFunctionTypes == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._genericFunctionTypes.length);
+      for (var x in this._genericFunctionTypes) {
+        x?.collectApiSignature(signature);
+      }
+    }
+    signature.addBool(this._isNNBD == true);
   }
 
   fb.Offset finish(fb.Builder fbBuilder) {
+    fb.Offset offset_genericFunctionTypes;
     fb.Offset offset_lineStarts;
     fb.Offset offset_node;
     fb.Offset offset_tokens;
     fb.Offset offset_uriStr;
+    if (!(_genericFunctionTypes == null || _genericFunctionTypes.isEmpty)) {
+      offset_genericFunctionTypes = fbBuilder.writeList(
+          _genericFunctionTypes.map((b) => b.finish(fbBuilder)).toList());
+    }
     if (!(_lineStarts == null || _lineStarts.isEmpty)) {
       offset_lineStarts = fbBuilder.writeListUint32(_lineStarts);
     }
@@ -20313,6 +15389,9 @@
       offset_uriStr = fbBuilder.writeString(_uriStr);
     }
     fbBuilder.startTable();
+    if (offset_genericFunctionTypes != null) {
+      fbBuilder.addOffset(5, offset_genericFunctionTypes);
+    }
     if (_isSynthetic == true) {
       fbBuilder.addBool(3, true);
     }
@@ -20328,6 +15407,9 @@
     if (offset_uriStr != null) {
       fbBuilder.addOffset(0, offset_uriStr);
     }
+    if (_isNNBD == true) {
+      fbBuilder.addBool(6, true);
+    }
     return fbBuilder.endTable();
   }
 }
@@ -20348,11 +15430,21 @@
 
   _LinkedNodeUnitImpl(this._bc, this._bcOffset);
 
+  List<idl.LinkedNode> _genericFunctionTypes;
   bool _isSynthetic;
   List<int> _lineStarts;
   idl.LinkedNode _node;
   idl.UnlinkedTokens _tokens;
   String _uriStr;
+  bool _isNNBD;
+
+  @override
+  List<idl.LinkedNode> get genericFunctionTypes {
+    _genericFunctionTypes ??=
+        const fb.ListReader<idl.LinkedNode>(const _LinkedNodeReader())
+            .vTableGet(_bc, _bcOffset, 5, const <idl.LinkedNode>[]);
+    return _genericFunctionTypes;
+  }
 
   @override
   bool get isSynthetic {
@@ -20385,27 +15477,39 @@
     _uriStr ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 0, '');
     return _uriStr;
   }
+
+  @override
+  bool get isNNBD {
+    _isNNBD ??= const fb.BoolReader().vTableGet(_bc, _bcOffset, 6, false);
+    return _isNNBD;
+  }
 }
 
 abstract class _LinkedNodeUnitMixin implements idl.LinkedNodeUnit {
   @override
   Map<String, Object> toJson() {
     Map<String, Object> _result = <String, Object>{};
+    if (genericFunctionTypes.isNotEmpty)
+      _result["genericFunctionTypes"] =
+          genericFunctionTypes.map((_value) => _value.toJson()).toList();
     if (isSynthetic != false) _result["isSynthetic"] = isSynthetic;
     if (lineStarts.isNotEmpty) _result["lineStarts"] = lineStarts;
     if (node != null) _result["node"] = node.toJson();
     if (tokens != null) _result["tokens"] = tokens.toJson();
     if (uriStr != '') _result["uriStr"] = uriStr;
+    if (isNNBD != false) _result["isNNBD"] = isNNBD;
     return _result;
   }
 
   @override
   Map<String, Object> toMap() => {
+        "genericFunctionTypes": genericFunctionTypes,
         "isSynthetic": isSynthetic,
         "lineStarts": lineStarts,
         "node": node,
         "tokens": tokens,
         "uriStr": uriStr,
+        "isNNBD": isNNBD,
       };
 
   @override
@@ -21138,6 +16242,7 @@
 class PackageBundleBuilder extends Object
     with _PackageBundleMixin
     implements idl.PackageBundle {
+  LinkedNodeBundleBuilder _bundle2;
   List<LinkedLibraryBuilder> _linkedLibraries;
   List<String> _linkedLibraryUris;
   int _majorVersion;
@@ -21150,6 +16255,14 @@
       throw new UnimplementedError('attempt to access deprecated field');
 
   @override
+  LinkedNodeBundleBuilder get bundle2 => _bundle2;
+
+  /// The version 2 of the summary.
+  set bundle2(LinkedNodeBundleBuilder value) {
+    this._bundle2 = value;
+  }
+
+  @override
   Null get dependencies =>
       throw new UnimplementedError('attempt to access deprecated field');
 
@@ -21213,13 +16326,15 @@
   }
 
   PackageBundleBuilder(
-      {List<LinkedLibraryBuilder> linkedLibraries,
+      {LinkedNodeBundleBuilder bundle2,
+      List<LinkedLibraryBuilder> linkedLibraries,
       List<String> linkedLibraryUris,
       int majorVersion,
       int minorVersion,
       List<UnlinkedUnitBuilder> unlinkedUnits,
       List<String> unlinkedUnitUris})
-      : _linkedLibraries = linkedLibraries,
+      : _bundle2 = bundle2,
+        _linkedLibraries = linkedLibraries,
         _linkedLibraryUris = linkedLibraryUris,
         _majorVersion = majorVersion,
         _minorVersion = minorVersion,
@@ -21228,6 +16343,7 @@
 
   /// Flush [informative] data recursively.
   void flushInformative() {
+    _bundle2?.flushInformative();
     _linkedLibraries?.forEach((b) => b.flushInformative());
     _unlinkedUnits?.forEach((b) => b.flushInformative());
   }
@@ -21268,6 +16384,8 @@
     }
     signature.addInt(this._majorVersion ?? 0);
     signature.addInt(this._minorVersion ?? 0);
+    signature.addBool(this._bundle2 != null);
+    this._bundle2?.collectApiSignature(signature);
   }
 
   List<int> toBuffer() {
@@ -21276,10 +16394,14 @@
   }
 
   fb.Offset finish(fb.Builder fbBuilder) {
+    fb.Offset offset_bundle2;
     fb.Offset offset_linkedLibraries;
     fb.Offset offset_linkedLibraryUris;
     fb.Offset offset_unlinkedUnits;
     fb.Offset offset_unlinkedUnitUris;
+    if (_bundle2 != null) {
+      offset_bundle2 = _bundle2.finish(fbBuilder);
+    }
     if (!(_linkedLibraries == null || _linkedLibraries.isEmpty)) {
       offset_linkedLibraries = fbBuilder
           .writeList(_linkedLibraries.map((b) => b.finish(fbBuilder)).toList());
@@ -21297,6 +16419,9 @@
           _unlinkedUnitUris.map((b) => fbBuilder.writeString(b)).toList());
     }
     fbBuilder.startTable();
+    if (offset_bundle2 != null) {
+      fbBuilder.addOffset(9, offset_bundle2);
+    }
     if (offset_linkedLibraries != null) {
       fbBuilder.addOffset(0, offset_linkedLibraries);
     }
@@ -21340,6 +16465,7 @@
 
   _PackageBundleImpl(this._bc, this._bcOffset);
 
+  idl.LinkedNodeBundle _bundle2;
   List<idl.LinkedLibrary> _linkedLibraries;
   List<String> _linkedLibraryUris;
   int _majorVersion;
@@ -21352,6 +16478,13 @@
       throw new UnimplementedError('attempt to access deprecated field');
 
   @override
+  idl.LinkedNodeBundle get bundle2 {
+    _bundle2 ??=
+        const _LinkedNodeBundleReader().vTableGet(_bc, _bcOffset, 9, null);
+    return _bundle2;
+  }
+
+  @override
   Null get dependencies =>
       throw new UnimplementedError('attempt to access deprecated field');
 
@@ -21406,6 +16539,7 @@
   @override
   Map<String, Object> toJson() {
     Map<String, Object> _result = <String, Object>{};
+    if (bundle2 != null) _result["bundle2"] = bundle2.toJson();
     if (linkedLibraries.isNotEmpty)
       _result["linkedLibraries"] =
           linkedLibraries.map((_value) => _value.toJson()).toList();
@@ -21423,6 +16557,7 @@
 
   @override
   Map<String, Object> toMap() => {
+        "bundle2": bundle2,
         "linkedLibraries": linkedLibraries,
         "linkedLibraryUris": linkedLibraryUris,
         "majorVersion": majorVersion,
@@ -28479,6 +23614,7 @@
   List<UnlinkedExecutableBuilder> _executables;
   List<UnlinkedExportNonPublicBuilder> _exports;
   List<UnlinkedImportBuilder> _imports;
+  bool _isNNBD;
   bool _isPartOf;
   List<UnlinkedExprBuilder> _libraryAnnotations;
   UnlinkedDocumentationCommentBuilder _libraryDocumentationComment;
@@ -28562,6 +23698,14 @@
   }
 
   @override
+  bool get isNNBD => _isNNBD ??= false;
+
+  /// Indicates whether this compilation unit is opted into NNBD.
+  set isNNBD(bool value) {
+    this._isNNBD = value;
+  }
+
+  @override
   bool get isPartOf => _isPartOf ??= false;
 
   /// Indicates whether the unit contains a "part of" declaration.
@@ -28689,6 +23833,7 @@
       List<UnlinkedExecutableBuilder> executables,
       List<UnlinkedExportNonPublicBuilder> exports,
       List<UnlinkedImportBuilder> imports,
+      bool isNNBD,
       bool isPartOf,
       List<UnlinkedExprBuilder> libraryAnnotations,
       UnlinkedDocumentationCommentBuilder libraryDocumentationComment,
@@ -28709,6 +23854,7 @@
         _executables = executables,
         _exports = exports,
         _imports = imports,
+        _isNNBD = isNNBD,
         _isPartOf = isPartOf,
         _libraryAnnotations = libraryAnnotations,
         _libraryDocumentationComment = libraryDocumentationComment,
@@ -28846,6 +23992,7 @@
         x?.collectApiSignature(signature);
       }
     }
+    signature.addBool(this._isNNBD == true);
   }
 
   List<int> toBuffer() {
@@ -28956,6 +24103,9 @@
     if (offset_imports != null) {
       fbBuilder.addOffset(5, offset_imports);
     }
+    if (_isNNBD == true) {
+      fbBuilder.addBool(21, true);
+    }
     if (_isPartOf == true) {
       fbBuilder.addBool(18, true);
     }
@@ -29027,6 +24177,7 @@
   List<idl.UnlinkedExecutable> _executables;
   List<idl.UnlinkedExportNonPublic> _exports;
   List<idl.UnlinkedImport> _imports;
+  bool _isNNBD;
   bool _isPartOf;
   List<idl.UnlinkedExpr> _libraryAnnotations;
   idl.UnlinkedDocumentationComment _libraryDocumentationComment;
@@ -29099,6 +24250,12 @@
   }
 
   @override
+  bool get isNNBD {
+    _isNNBD ??= const fb.BoolReader().vTableGet(_bc, _bcOffset, 21, false);
+    return _isNNBD;
+  }
+
+  @override
   bool get isPartOf {
     _isPartOf ??= const fb.BoolReader().vTableGet(_bc, _bcOffset, 18, false);
     return _isPartOf;
@@ -29211,6 +24368,7 @@
       _result["exports"] = exports.map((_value) => _value.toJson()).toList();
     if (imports.isNotEmpty)
       _result["imports"] = imports.map((_value) => _value.toJson()).toList();
+    if (isNNBD != false) _result["isNNBD"] = isNNBD;
     if (isPartOf != false) _result["isPartOf"] = isPartOf;
     if (libraryAnnotations.isNotEmpty)
       _result["libraryAnnotations"] =
@@ -29250,6 +24408,7 @@
         "executables": executables,
         "exports": exports,
         "imports": imports,
+        "isNNBD": isNNBD,
         "isPartOf": isPartOf,
         "libraryAnnotations": libraryAnnotations,
         "libraryDocumentationComment": libraryDocumentationComment,
diff --git a/pkg/analyzer/lib/src/summary/format.fbs b/pkg/analyzer/lib/src/summary/format.fbs
index b7053cb..6d9af7a 100644
--- a/pkg/analyzer/lib/src/summary/format.fbs
+++ b/pkg/analyzer/lib/src/summary/format.fbs
@@ -369,8 +369,6 @@
 
   returnStatement,
 
-  scriptTag,
-
   setOrMapLiteral,
 
   showCombinator,
@@ -1894,8 +1892,6 @@
 
   variantField_6:LinkedNode (id: 6);
 
-  variantField_15:uint (id: 15);
-
   variantField_7:LinkedNode (id: 7);
 
   variantField_17:uint (id: 17);
@@ -1904,11 +1900,9 @@
 
   variantField_8:LinkedNode (id: 8);
 
-  variantField_16:uint (id: 16);
+  variantField_15:uint (id: 15);
 
-  variantField_18:uint (id: 18);
-
-  variantField_19:uint (id: 19);
+  variantField_28:UnlinkedTokenType (id: 28);
 
   variantField_27:bool (id: 27);
 
@@ -1924,7 +1918,7 @@
 
   variantField_33:uint (id: 33);
 
-  variantField_28:[uint] (id: 28);
+  variantField_36:[string] (id: 36);
 
   variantField_29:LinkedNodeCommentType (id: 29);
 
@@ -1938,24 +1932,32 @@
 
   variantField_25:LinkedNodeType (id: 25);
 
+  flags:uint (id: 18);
+
+  variantField_1:string (id: 1);
+
+  variantField_16:uint (id: 16);
+
   variantField_30:string (id: 30);
 
   variantField_14:LinkedNode (id: 14);
 
-  isSynthetic:bool (id: 1);
-
   kind:LinkedNodeKind (id: 0);
 
-  variantField_36:[string] (id: 36);
+  name:string (id: 37);
 
   variantField_20:string (id: 20);
 
   variantField_31:bool (id: 31);
 
+  variantField_38:UnlinkedTokenType (id: 38);
+
   variantField_35:TopLevelInferenceError (id: 35);
 
   variantField_22:string (id: 22);
 
+  variantField_19:uint (id: 19);
+
   variantField_32:LinkedNodeVariablesDeclaration (id: 32);
 }
 
@@ -2034,6 +2036,14 @@
 
 /// Information about a single library in a [LinkedNodeLibrary].
 table LinkedNodeUnit {
+  /// All generic function types in the unit - in generic type aliases, or used
+  /// directly as type annotations.
+  ///
+  /// They are requested in two cases: when we are reading a node that contains
+  /// them (e.g. a return type of a method), or when we run over unresolved
+  /// AST in declaration resolver.
+  genericFunctionTypes:[LinkedNode] (id: 5);
+
   isSynthetic:bool (id: 3);
 
   /// Offsets of the first character of each line in the source code.
@@ -2044,6 +2054,8 @@
   tokens:UnlinkedTokens (id: 1);
 
   uriStr:string (id: 0);
+
+  isNNBD:bool (id: 6);
 }
 
 /// Information about a top-level declaration, or a field declaration that
@@ -2148,6 +2160,9 @@
   /// package may have changed.
   apiSignature:string (id: 7, deprecated);
 
+  /// The version 2 of the summary.
+  bundle2:LinkedNodeBundle (id: 9);
+
   /// Information about the packages this package depends on, if known.
   dependencies:[PackageDependencyInfo] (id: 8, deprecated);
 
@@ -3031,6 +3046,9 @@
   /// Import declarations in the compilation unit.
   imports:[UnlinkedImport] (id: 5);
 
+  /// Indicates whether this compilation unit is opted into NNBD.
+  isNNBD:bool (id: 21);
+
   /// Indicates whether the unit contains a "part of" declaration.
   isPartOf:bool (id: 18);
 
diff --git a/pkg/analyzer/lib/src/summary/idl.dart b/pkg/analyzer/lib/src/summary/idl.dart
index d0e04f4..3e2a821 100644
--- a/pkg/analyzer/lib/src/summary/idl.dart
+++ b/pkg/analyzer/lib/src/summary/idl.dart
@@ -875,9 +875,6 @@
   @VariantId(6, variant: LinkedNodeKind.annotation)
   LinkedNode get annotation_arguments;
 
-  @VariantId(15, variant: LinkedNodeKind.annotation)
-  int get annotation_atSign;
-
   @VariantId(7, variant: LinkedNodeKind.annotation)
   LinkedNode get annotation_constructorName;
 
@@ -890,66 +887,27 @@
   @VariantId(8, variant: LinkedNodeKind.annotation)
   LinkedNode get annotation_name;
 
-  @VariantId(16, variant: LinkedNodeKind.annotation)
-  int get annotation_period;
-
   @VariantId(2, variant: LinkedNodeKind.argumentList)
   List<LinkedNode> get argumentList_arguments;
 
-  @VariantId(15, variant: LinkedNodeKind.argumentList)
-  int get argumentList_leftParenthesis;
-
-  @VariantId(16, variant: LinkedNodeKind.argumentList)
-  int get argumentList_rightParenthesis;
-
-  @VariantId(15, variant: LinkedNodeKind.asExpression)
-  int get asExpression_asOperator;
-
   @VariantId(6, variant: LinkedNodeKind.asExpression)
   LinkedNode get asExpression_expression;
 
   @VariantId(7, variant: LinkedNodeKind.asExpression)
   LinkedNode get asExpression_type;
 
-  @VariantId(15, variant: LinkedNodeKind.assertInitializer)
-  int get assertInitializer_assertKeyword;
-
-  @VariantId(16, variant: LinkedNodeKind.assertInitializer)
-  int get assertInitializer_comma;
-
   @VariantId(6, variant: LinkedNodeKind.assertInitializer)
   LinkedNode get assertInitializer_condition;
 
-  @VariantId(17, variant: LinkedNodeKind.assertInitializer)
-  int get assertInitializer_leftParenthesis;
-
   @VariantId(7, variant: LinkedNodeKind.assertInitializer)
   LinkedNode get assertInitializer_message;
 
-  @VariantId(18, variant: LinkedNodeKind.assertInitializer)
-  int get assertInitializer_rightParenthesis;
-
-  @VariantId(15, variant: LinkedNodeKind.assertStatement)
-  int get assertStatement_assertKeyword;
-
-  @VariantId(16, variant: LinkedNodeKind.assertStatement)
-  int get assertStatement_comma;
-
   @VariantId(6, variant: LinkedNodeKind.assertStatement)
   LinkedNode get assertStatement_condition;
 
-  @VariantId(17, variant: LinkedNodeKind.assertStatement)
-  int get assertStatement_leftParenthesis;
-
   @VariantId(7, variant: LinkedNodeKind.assertStatement)
   LinkedNode get assertStatement_message;
 
-  @VariantId(18, variant: LinkedNodeKind.assertStatement)
-  int get assertStatement_rightParenthesis;
-
-  @VariantId(19, variant: LinkedNodeKind.assertStatement)
-  int get assertStatement_semicolon;
-
   @VariantId(15, variant: LinkedNodeKind.assignmentExpression)
   int get assignmentExpression_element;
 
@@ -959,15 +917,12 @@
   @VariantId(6, variant: LinkedNodeKind.assignmentExpression)
   LinkedNode get assignmentExpression_leftHandSide;
 
-  @VariantId(16, variant: LinkedNodeKind.assignmentExpression)
-  int get assignmentExpression_operator;
+  @VariantId(28, variant: LinkedNodeKind.assignmentExpression)
+  UnlinkedTokenType get assignmentExpression_operator;
 
   @VariantId(7, variant: LinkedNodeKind.assignmentExpression)
   LinkedNode get assignmentExpression_rightHandSide;
 
-  @VariantId(15, variant: LinkedNodeKind.awaitExpression)
-  int get awaitExpression_awaitKeyword;
-
   @VariantId(6, variant: LinkedNodeKind.awaitExpression)
   LinkedNode get awaitExpression_expression;
 
@@ -983,45 +938,24 @@
   @VariantId(6, variant: LinkedNodeKind.binaryExpression)
   LinkedNode get binaryExpression_leftOperand;
 
-  @VariantId(16, variant: LinkedNodeKind.binaryExpression)
-  int get binaryExpression_operator;
+  @VariantId(28, variant: LinkedNodeKind.binaryExpression)
+  UnlinkedTokenType get binaryExpression_operator;
 
   @VariantId(7, variant: LinkedNodeKind.binaryExpression)
   LinkedNode get binaryExpression_rightOperand;
 
-  @VariantId(15, variant: LinkedNodeKind.block)
-  int get block_leftBracket;
-
-  @VariantId(16, variant: LinkedNodeKind.block)
-  int get block_rightBracket;
-
   @VariantId(2, variant: LinkedNodeKind.block)
   List<LinkedNode> get block_statements;
 
   @VariantId(6, variant: LinkedNodeKind.blockFunctionBody)
   LinkedNode get blockFunctionBody_block;
 
-  @VariantId(15, variant: LinkedNodeKind.blockFunctionBody)
-  int get blockFunctionBody_keyword;
-
-  @VariantId(16, variant: LinkedNodeKind.blockFunctionBody)
-  int get blockFunctionBody_star;
-
-  @VariantId(15, variant: LinkedNodeKind.booleanLiteral)
-  int get booleanLiteral_literal;
-
   @VariantId(27, variant: LinkedNodeKind.booleanLiteral)
   bool get booleanLiteral_value;
 
-  @VariantId(15, variant: LinkedNodeKind.breakStatement)
-  int get breakStatement_breakKeyword;
-
   @VariantId(6, variant: LinkedNodeKind.breakStatement)
   LinkedNode get breakStatement_label;
 
-  @VariantId(16, variant: LinkedNodeKind.breakStatement)
-  int get breakStatement_semicolon;
-
   @VariantId(2, variant: LinkedNodeKind.cascadeExpression)
   List<LinkedNode> get cascadeExpression_sections;
 
@@ -1031,36 +965,15 @@
   @VariantId(6, variant: LinkedNodeKind.catchClause)
   LinkedNode get catchClause_body;
 
-  @VariantId(15, variant: LinkedNodeKind.catchClause)
-  int get catchClause_catchKeyword;
-
-  @VariantId(16, variant: LinkedNodeKind.catchClause)
-  int get catchClause_comma;
-
   @VariantId(7, variant: LinkedNodeKind.catchClause)
   LinkedNode get catchClause_exceptionParameter;
 
   @VariantId(8, variant: LinkedNodeKind.catchClause)
   LinkedNode get catchClause_exceptionType;
 
-  @VariantId(17, variant: LinkedNodeKind.catchClause)
-  int get catchClause_leftParenthesis;
-
-  @VariantId(18, variant: LinkedNodeKind.catchClause)
-  int get catchClause_onKeyword;
-
-  @VariantId(19, variant: LinkedNodeKind.catchClause)
-  int get catchClause_rightParenthesis;
-
   @VariantId(9, variant: LinkedNodeKind.catchClause)
   LinkedNode get catchClause_stackTraceParameter;
 
-  @VariantId(15, variant: LinkedNodeKind.classDeclaration)
-  int get classDeclaration_abstractKeyword;
-
-  @VariantId(16, variant: LinkedNodeKind.classDeclaration)
-  int get classDeclaration_classKeyword;
-
   @VariantId(6, variant: LinkedNodeKind.classDeclaration)
   LinkedNode get classDeclaration_extendsClause;
 
@@ -1079,36 +992,18 @@
   ])
   LinkedNode get classOrMixinDeclaration_implementsClause;
 
-  @VariantId(19, variantList: [
-    LinkedNodeKind.classDeclaration,
-    LinkedNodeKind.mixinDeclaration,
-  ])
-  int get classOrMixinDeclaration_leftBracket;
-
   @VariantId(5, variantList: [
     LinkedNodeKind.classDeclaration,
     LinkedNodeKind.mixinDeclaration,
   ])
   List<LinkedNode> get classOrMixinDeclaration_members;
 
-  @VariantId(18, variantList: [
-    LinkedNodeKind.classDeclaration,
-    LinkedNodeKind.mixinDeclaration,
-  ])
-  int get classOrMixinDeclaration_rightBracket;
-
   @VariantId(13, variantList: [
     LinkedNodeKind.classDeclaration,
     LinkedNodeKind.mixinDeclaration,
   ])
   LinkedNode get classOrMixinDeclaration_typeParameters;
 
-  @VariantId(15, variant: LinkedNodeKind.classTypeAlias)
-  int get classTypeAlias_abstractKeyword;
-
-  @VariantId(16, variant: LinkedNodeKind.classTypeAlias)
-  int get classTypeAlias_equals;
-
   @VariantId(9, variant: LinkedNodeKind.classTypeAlias)
   LinkedNode get classTypeAlias_implementsClause;
 
@@ -1161,17 +1056,11 @@
   ])
   int get codeOffset;
 
-  @VariantId(19, variantList: [
-    LinkedNodeKind.hideCombinator,
-    LinkedNodeKind.showCombinator,
-  ])
-  int get combinator_keyword;
-
   @VariantId(2, variant: LinkedNodeKind.comment)
   List<LinkedNode> get comment_references;
 
-  @VariantId(28, variant: LinkedNodeKind.comment)
-  List<int> get comment_tokens;
+  @VariantId(36, variant: LinkedNodeKind.comment)
+  List<String> get comment_tokens;
 
   @VariantId(29, variant: LinkedNodeKind.comment)
   LinkedNodeCommentType get comment_type;
@@ -1179,54 +1068,27 @@
   @VariantId(6, variant: LinkedNodeKind.commentReference)
   LinkedNode get commentReference_identifier;
 
-  @VariantId(15, variant: LinkedNodeKind.commentReference)
-  int get commentReference_newKeyword;
-
-  @VariantId(15, variant: LinkedNodeKind.compilationUnit)
-  int get compilationUnit_beginToken;
-
   @VariantId(2, variant: LinkedNodeKind.compilationUnit)
   List<LinkedNode> get compilationUnit_declarations;
 
   @VariantId(3, variant: LinkedNodeKind.compilationUnit)
   List<LinkedNode> get compilationUnit_directives;
 
-  @VariantId(16, variant: LinkedNodeKind.compilationUnit)
-  int get compilationUnit_endToken;
-
   @VariantId(6, variant: LinkedNodeKind.compilationUnit)
   LinkedNode get compilationUnit_scriptTag;
 
-  @VariantId(15, variant: LinkedNodeKind.conditionalExpression)
-  int get conditionalExpression_colon;
-
   @VariantId(6, variant: LinkedNodeKind.conditionalExpression)
   LinkedNode get conditionalExpression_condition;
 
   @VariantId(7, variant: LinkedNodeKind.conditionalExpression)
   LinkedNode get conditionalExpression_elseExpression;
 
-  @VariantId(16, variant: LinkedNodeKind.conditionalExpression)
-  int get conditionalExpression_question;
-
   @VariantId(8, variant: LinkedNodeKind.conditionalExpression)
   LinkedNode get conditionalExpression_thenExpression;
 
-  @VariantId(18, variant: LinkedNodeKind.configuration)
-  int get configuration_equalToken;
-
-  @VariantId(15, variant: LinkedNodeKind.configuration)
-  int get configuration_ifKeyword;
-
-  @VariantId(16, variant: LinkedNodeKind.configuration)
-  int get configuration_leftParenthesis;
-
   @VariantId(6, variant: LinkedNodeKind.configuration)
   LinkedNode get configuration_name;
 
-  @VariantId(17, variant: LinkedNodeKind.configuration)
-  int get configuration_rightParenthesis;
-
   @VariantId(8, variant: LinkedNodeKind.configuration)
   LinkedNode get configuration_uri;
 
@@ -1236,51 +1098,24 @@
   @VariantId(6, variant: LinkedNodeKind.constructorDeclaration)
   LinkedNode get constructorDeclaration_body;
 
-  @VariantId(15, variant: LinkedNodeKind.constructorDeclaration)
-  int get constructorDeclaration_constKeyword;
-
-  @VariantId(16, variant: LinkedNodeKind.constructorDeclaration)
-  int get constructorDeclaration_externalKeyword;
-
-  @VariantId(17, variant: LinkedNodeKind.constructorDeclaration)
-  int get constructorDeclaration_factoryKeyword;
-
   @VariantId(2, variant: LinkedNodeKind.constructorDeclaration)
   List<LinkedNode> get constructorDeclaration_initializers;
 
-  @VariantId(7, variant: LinkedNodeKind.constructorDeclaration)
-  LinkedNode get constructorDeclaration_name;
-
   @VariantId(8, variant: LinkedNodeKind.constructorDeclaration)
   LinkedNode get constructorDeclaration_parameters;
 
-  @VariantId(18, variant: LinkedNodeKind.constructorDeclaration)
-  int get constructorDeclaration_period;
-
   @VariantId(9, variant: LinkedNodeKind.constructorDeclaration)
   LinkedNode get constructorDeclaration_redirectedConstructor;
 
   @VariantId(10, variant: LinkedNodeKind.constructorDeclaration)
   LinkedNode get constructorDeclaration_returnType;
 
-  @VariantId(19, variant: LinkedNodeKind.constructorDeclaration)
-  int get constructorDeclaration_separator;
-
-  @VariantId(15, variant: LinkedNodeKind.constructorFieldInitializer)
-  int get constructorFieldInitializer_equals;
-
   @VariantId(6, variant: LinkedNodeKind.constructorFieldInitializer)
   LinkedNode get constructorFieldInitializer_expression;
 
   @VariantId(7, variant: LinkedNodeKind.constructorFieldInitializer)
   LinkedNode get constructorFieldInitializer_fieldName;
 
-  @VariantId(16, variant: LinkedNodeKind.constructorFieldInitializer)
-  int get constructorFieldInitializer_period;
-
-  @VariantId(17, variant: LinkedNodeKind.constructorFieldInitializer)
-  int get constructorFieldInitializer_thisKeyword;
-
   @VariantId(15, variant: LinkedNodeKind.constructorName)
   int get constructorName_element;
 
@@ -1290,27 +1125,15 @@
   @VariantId(6, variant: LinkedNodeKind.constructorName)
   LinkedNode get constructorName_name;
 
-  @VariantId(16, variant: LinkedNodeKind.constructorName)
-  int get constructorName_period;
-
   @VariantId(7, variant: LinkedNodeKind.constructorName)
   LinkedNode get constructorName_type;
 
-  @VariantId(15, variant: LinkedNodeKind.continueStatement)
-  int get continueStatement_continueKeyword;
-
   @VariantId(6, variant: LinkedNodeKind.continueStatement)
   LinkedNode get continueStatement_label;
 
-  @VariantId(16, variant: LinkedNodeKind.continueStatement)
-  int get continueStatement_semicolon;
-
   @VariantId(6, variant: LinkedNodeKind.declaredIdentifier)
   LinkedNode get declaredIdentifier_identifier;
 
-  @VariantId(15, variant: LinkedNodeKind.declaredIdentifier)
-  int get declaredIdentifier_keyword;
-
   @VariantId(7, variant: LinkedNodeKind.declaredIdentifier)
   LinkedNode get declaredIdentifier_type;
 
@@ -1323,96 +1146,39 @@
   @VariantId(7, variant: LinkedNodeKind.defaultFormalParameter)
   LinkedNode get defaultFormalParameter_parameter;
 
-  @VariantId(15, variant: LinkedNodeKind.defaultFormalParameter)
-  int get defaultFormalParameter_separator;
-
-  @VariantId(18, variantList: [
-    LinkedNodeKind.exportDirective,
-    LinkedNodeKind.importDirective,
-    LinkedNodeKind.libraryDirective,
-    LinkedNodeKind.partDirective,
-    LinkedNodeKind.partOfDirective,
-  ])
-  int get directive_keyword;
-
-  @VariantId(33, variantList: [
-    LinkedNodeKind.exportDirective,
-    LinkedNodeKind.importDirective,
-    LinkedNodeKind.libraryDirective,
-    LinkedNodeKind.partDirective,
-    LinkedNodeKind.partOfDirective,
-  ])
-  int get directive_semicolon;
-
   @VariantId(6, variant: LinkedNodeKind.doStatement)
   LinkedNode get doStatement_body;
 
   @VariantId(7, variant: LinkedNodeKind.doStatement)
   LinkedNode get doStatement_condition;
 
-  @VariantId(17, variant: LinkedNodeKind.doStatement)
-  int get doStatement_doKeyword;
-
-  @VariantId(15, variant: LinkedNodeKind.doStatement)
-  int get doStatement_leftParenthesis;
-
-  @VariantId(16, variant: LinkedNodeKind.doStatement)
-  int get doStatement_rightParenthesis;
-
-  @VariantId(18, variant: LinkedNodeKind.doStatement)
-  int get doStatement_semicolon;
-
-  @VariantId(19, variant: LinkedNodeKind.doStatement)
-  int get doStatement_whileKeyword;
-
   @VariantId(2, variant: LinkedNodeKind.dottedName)
   List<LinkedNode> get dottedName_components;
 
-  @VariantId(15, variant: LinkedNodeKind.doubleLiteral)
-  int get doubleLiteral_literal;
-
   @VariantId(21, variant: LinkedNodeKind.doubleLiteral)
   double get doubleLiteral_value;
 
   @VariantId(15, variant: LinkedNodeKind.emptyFunctionBody)
-  int get emptyFunctionBody_semicolon;
+  int get emptyFunctionBody_fake;
 
   @VariantId(15, variant: LinkedNodeKind.emptyStatement)
-  int get emptyStatement_semicolon;
-
-  @VariantId(6, variant: LinkedNodeKind.enumConstantDeclaration)
-  LinkedNode get enumConstantDeclaration_name;
+  int get emptyStatement_fake;
 
   @VariantId(2, variant: LinkedNodeKind.enumDeclaration)
   List<LinkedNode> get enumDeclaration_constants;
 
-  @VariantId(15, variant: LinkedNodeKind.enumDeclaration)
-  int get enumDeclaration_enumKeyword;
-
-  @VariantId(16, variant: LinkedNodeKind.enumDeclaration)
-  int get enumDeclaration_leftBracket;
-
-  @VariantId(17, variant: LinkedNodeKind.enumDeclaration)
-  int get enumDeclaration_rightBracket;
-
   @VariantId(25, variantList: [
-    LinkedNodeKind.adjacentStrings,
     LinkedNodeKind.assignmentExpression,
     LinkedNodeKind.asExpression,
     LinkedNodeKind.awaitExpression,
     LinkedNodeKind.binaryExpression,
-    LinkedNodeKind.booleanLiteral,
     LinkedNodeKind.cascadeExpression,
     LinkedNodeKind.conditionalExpression,
-    LinkedNodeKind.doubleLiteral,
     LinkedNodeKind.functionExpressionInvocation,
     LinkedNodeKind.indexExpression,
     LinkedNodeKind.instanceCreationExpression,
-    LinkedNodeKind.integerLiteral,
-    LinkedNodeKind.isExpression,
     LinkedNodeKind.listLiteral,
     LinkedNodeKind.methodInvocation,
-    LinkedNodeKind.namedExpression,
     LinkedNodeKind.nullLiteral,
     LinkedNodeKind.parenthesizedExpression,
     LinkedNodeKind.prefixExpression,
@@ -1422,8 +1188,6 @@
     LinkedNodeKind.rethrowExpression,
     LinkedNodeKind.setOrMapLiteral,
     LinkedNodeKind.simpleIdentifier,
-    LinkedNodeKind.simpleStringLiteral,
-    LinkedNodeKind.stringInterpolation,
     LinkedNodeKind.superExpression,
     LinkedNodeKind.symbolLiteral,
     LinkedNodeKind.thisExpression,
@@ -1431,65 +1195,29 @@
   ])
   LinkedNodeType get expression_type;
 
-  @VariantId(15, variant: LinkedNodeKind.expressionFunctionBody)
-  int get expressionFunctionBody_arrow;
-
   @VariantId(6, variant: LinkedNodeKind.expressionFunctionBody)
   LinkedNode get expressionFunctionBody_expression;
 
-  @VariantId(16, variant: LinkedNodeKind.expressionFunctionBody)
-  int get expressionFunctionBody_keyword;
-
-  @VariantId(17, variant: LinkedNodeKind.expressionFunctionBody)
-  int get expressionFunctionBody_semicolon;
-
   @VariantId(6, variant: LinkedNodeKind.expressionStatement)
   LinkedNode get expressionStatement_expression;
 
-  @VariantId(15, variant: LinkedNodeKind.expressionStatement)
-  int get expressionStatement_semicolon;
-
-  @VariantId(15, variant: LinkedNodeKind.extendsClause)
-  int get extendsClause_extendsKeyword;
-
   @VariantId(6, variant: LinkedNodeKind.extendsClause)
   LinkedNode get extendsClause_superclass;
 
-  @VariantId(15, variant: LinkedNodeKind.fieldDeclaration)
-  int get fieldDeclaration_covariantKeyword;
-
   @VariantId(6, variant: LinkedNodeKind.fieldDeclaration)
   LinkedNode get fieldDeclaration_fields;
 
-  @VariantId(16, variant: LinkedNodeKind.fieldDeclaration)
-  int get fieldDeclaration_semicolon;
-
-  @VariantId(17, variant: LinkedNodeKind.fieldDeclaration)
-  int get fieldDeclaration_staticKeyword;
-
   @VariantId(8, variant: LinkedNodeKind.fieldFormalParameter)
   LinkedNode get fieldFormalParameter_formalParameters;
 
-  @VariantId(15, variant: LinkedNodeKind.fieldFormalParameter)
-  int get fieldFormalParameter_keyword;
-
-  @VariantId(16, variant: LinkedNodeKind.fieldFormalParameter)
-  int get fieldFormalParameter_period;
-
-  @VariantId(17, variant: LinkedNodeKind.fieldFormalParameter)
-  int get fieldFormalParameter_thisKeyword;
-
   @VariantId(6, variant: LinkedNodeKind.fieldFormalParameter)
   LinkedNode get fieldFormalParameter_type;
 
   @VariantId(7, variant: LinkedNodeKind.fieldFormalParameter)
   LinkedNode get fieldFormalParameter_typeParameters;
 
-  @VariantId(15, variantList: [
-    LinkedNodeKind.forEachPartsWithDeclaration,
-    LinkedNodeKind.forEachPartsWithIdentifier,
-  ])
-  int get forEachParts_inKeyword;
+  @Id(18)
+  int get flags;
 
   @VariantId(6, variantList: [
     LinkedNodeKind.forEachPartsWithDeclaration,
@@ -1506,69 +1234,21 @@
   @VariantId(7, variant: LinkedNodeKind.forElement)
   LinkedNode get forElement_body;
 
-  @VariantId(15, variant: LinkedNodeKind.formalParameterList)
-  int get formalParameterList_leftDelimiter;
-
-  @VariantId(16, variant: LinkedNodeKind.formalParameterList)
-  int get formalParameterList_leftParenthesis;
-
   @VariantId(2, variant: LinkedNodeKind.formalParameterList)
   List<LinkedNode> get formalParameterList_parameters;
 
-  @VariantId(17, variant: LinkedNodeKind.formalParameterList)
-  int get formalParameterList_rightDelimiter;
-
-  @VariantId(18, variant: LinkedNodeKind.formalParameterList)
-  int get formalParameterList_rightParenthesis;
-
-  @VariantId(15, variantList: [
-    LinkedNodeKind.forElement,
-    LinkedNodeKind.forStatement,
-  ])
-  int get forMixin_awaitKeyword;
-
-  @VariantId(16, variantList: [
-    LinkedNodeKind.forElement,
-    LinkedNodeKind.forStatement,
-  ])
-  int get forMixin_forKeyword;
-
   @VariantId(6, variantList: [
     LinkedNodeKind.forElement,
     LinkedNodeKind.forStatement,
   ])
   LinkedNode get forMixin_forLoopParts;
 
-  @VariantId(17, variantList: [
-    LinkedNodeKind.forElement,
-    LinkedNodeKind.forStatement,
-  ])
-  int get forMixin_leftParenthesis;
-
-  @VariantId(19, variantList: [
-    LinkedNodeKind.forElement,
-    LinkedNodeKind.forStatement,
-  ])
-  int get forMixin_rightParenthesis;
-
   @VariantId(6, variantList: [
     LinkedNodeKind.forPartsWithDeclarations,
     LinkedNodeKind.forPartsWithExpression,
   ])
   LinkedNode get forParts_condition;
 
-  @VariantId(15, variantList: [
-    LinkedNodeKind.forPartsWithDeclarations,
-    LinkedNodeKind.forPartsWithExpression,
-  ])
-  int get forParts_leftSeparator;
-
-  @VariantId(16, variantList: [
-    LinkedNodeKind.forPartsWithDeclarations,
-    LinkedNodeKind.forPartsWithExpression,
-  ])
-  int get forParts_rightSeparator;
-
   @VariantId(5, variantList: [
     LinkedNodeKind.forPartsWithDeclarations,
     LinkedNodeKind.forPartsWithExpression,
@@ -1584,15 +1264,9 @@
   @VariantId(7, variant: LinkedNodeKind.forStatement)
   LinkedNode get forStatement_body;
 
-  @VariantId(15, variant: LinkedNodeKind.functionDeclaration)
-  int get functionDeclaration_externalKeyword;
-
   @VariantId(6, variant: LinkedNodeKind.functionDeclaration)
   LinkedNode get functionDeclaration_functionExpression;
 
-  @VariantId(16, variant: LinkedNodeKind.functionDeclaration)
-  int get functionDeclaration_propertyKeyword;
-
   @VariantId(7, variant: LinkedNodeKind.functionDeclaration)
   LinkedNode get functionDeclaration_returnType;
 
@@ -1632,15 +1306,9 @@
   @VariantId(8, variant: LinkedNodeKind.genericFunctionType)
   LinkedNode get genericFunctionType_formalParameters;
 
-  @VariantId(15, variant: LinkedNodeKind.genericFunctionType)
-  int get genericFunctionType_functionKeyword;
-
   @VariantId(17, variant: LinkedNodeKind.genericFunctionType)
   int get genericFunctionType_id;
 
-  @VariantId(16, variant: LinkedNodeKind.genericFunctionType)
-  int get genericFunctionType_question;
-
   @VariantId(7, variant: LinkedNodeKind.genericFunctionType)
   LinkedNode get genericFunctionType_returnType;
 
@@ -1650,18 +1318,12 @@
   @VariantId(6, variant: LinkedNodeKind.genericFunctionType)
   LinkedNode get genericFunctionType_typeParameters;
 
-  @VariantId(16, variant: LinkedNodeKind.genericTypeAlias)
-  int get genericTypeAlias_equals;
-
   @VariantId(7, variant: LinkedNodeKind.genericTypeAlias)
   LinkedNode get genericTypeAlias_functionType;
 
   @VariantId(6, variant: LinkedNodeKind.genericTypeAlias)
   LinkedNode get genericTypeAlias_typeParameters;
 
-  @VariantId(2, variant: LinkedNodeKind.hideCombinator)
-  List<LinkedNode> get hideCombinator_hiddenNames;
-
   @VariantId(9, variant: LinkedNodeKind.ifElement)
   LinkedNode get ifElement_elseElement;
 
@@ -1674,50 +1336,20 @@
   ])
   LinkedNode get ifMixin_condition;
 
-  @VariantId(15, variantList: [
-    LinkedNodeKind.ifElement,
-    LinkedNodeKind.ifStatement,
-  ])
-  int get ifMixin_elseKeyword;
-
-  @VariantId(16, variantList: [
-    LinkedNodeKind.ifElement,
-    LinkedNodeKind.ifStatement,
-  ])
-  int get ifMixin_ifKeyword;
-
-  @VariantId(17, variantList: [
-    LinkedNodeKind.ifElement,
-    LinkedNodeKind.ifStatement,
-  ])
-  int get ifMixin_leftParenthesis;
-
-  @VariantId(18, variantList: [
-    LinkedNodeKind.ifElement,
-    LinkedNodeKind.ifStatement,
-  ])
-  int get ifMixin_rightParenthesis;
-
   @VariantId(7, variant: LinkedNodeKind.ifStatement)
   LinkedNode get ifStatement_elseStatement;
 
   @VariantId(8, variant: LinkedNodeKind.ifStatement)
   LinkedNode get ifStatement_thenStatement;
 
-  @VariantId(15, variant: LinkedNodeKind.implementsClause)
-  int get implementsClause_implementsKeyword;
-
   @VariantId(2, variant: LinkedNodeKind.implementsClause)
   List<LinkedNode> get implementsClause_interfaces;
 
+  @VariantId(1, variant: LinkedNodeKind.importDirective)
+  String get importDirective_prefix;
+
   @VariantId(15, variant: LinkedNodeKind.importDirective)
-  int get importDirective_asKeyword;
-
-  @VariantId(16, variant: LinkedNodeKind.importDirective)
-  int get importDirective_deferredKeyword;
-
-  @VariantId(6, variant: LinkedNodeKind.importDirective)
-  LinkedNode get importDirective_prefix;
+  int get importDirective_prefixOffset;
 
   @VariantId(15, variant: LinkedNodeKind.indexExpression)
   int get indexExpression_element;
@@ -1728,15 +1360,6 @@
   @VariantId(6, variant: LinkedNodeKind.indexExpression)
   LinkedNode get indexExpression_index;
 
-  @VariantId(17, variant: LinkedNodeKind.indexExpression)
-  int get indexExpression_leftBracket;
-
-  @VariantId(16, variant: LinkedNodeKind.indexExpression)
-  int get indexExpression_period;
-
-  @VariantId(18, variant: LinkedNodeKind.indexExpression)
-  int get indexExpression_rightBracket;
-
   @VariantId(7, variant: LinkedNodeKind.indexExpression)
   LinkedNode get indexExpression_target;
 
@@ -1748,36 +1371,21 @@
   ])
   bool get inheritsCovariant;
 
-  @VariantId(6, variant: LinkedNodeKind.instanceCreationExpression)
-  LinkedNode get instanceCreationExpression_arguments;
+  @VariantId(2, variant: LinkedNodeKind.instanceCreationExpression)
+  List<LinkedNode> get instanceCreationExpression_arguments;
 
   @VariantId(7, variant: LinkedNodeKind.instanceCreationExpression)
   LinkedNode get instanceCreationExpression_constructorName;
 
-  @VariantId(15, variant: LinkedNodeKind.instanceCreationExpression)
-  int get instanceCreationExpression_keyword;
-
   @VariantId(8, variant: LinkedNodeKind.instanceCreationExpression)
   LinkedNode get instanceCreationExpression_typeArguments;
 
-  @VariantId(15, variant: LinkedNodeKind.integerLiteral)
-  int get integerLiteral_literal;
-
   @VariantId(16, variant: LinkedNodeKind.integerLiteral)
   int get integerLiteral_value;
 
   @VariantId(6, variant: LinkedNodeKind.interpolationExpression)
   LinkedNode get interpolationExpression_expression;
 
-  @VariantId(15, variant: LinkedNodeKind.interpolationExpression)
-  int get interpolationExpression_leftBracket;
-
-  @VariantId(16, variant: LinkedNodeKind.interpolationExpression)
-  int get interpolationExpression_rightBracket;
-
-  @VariantId(15, variant: LinkedNodeKind.interpolationString)
-  int get interpolationString_token;
-
   @VariantId(30, variant: LinkedNodeKind.interpolationString)
   String get interpolationString_value;
 
@@ -1802,24 +1410,12 @@
   @VariantId(6, variant: LinkedNodeKind.isExpression)
   LinkedNode get isExpression_expression;
 
-  @VariantId(15, variant: LinkedNodeKind.isExpression)
-  int get isExpression_isOperator;
-
-  @VariantId(16, variant: LinkedNodeKind.isExpression)
-  int get isExpression_notOperator;
-
   @VariantId(7, variant: LinkedNodeKind.isExpression)
   LinkedNode get isExpression_type;
 
-  @Id(1)
-  bool get isSynthetic;
-
   @Id(0)
   LinkedNodeKind get kind;
 
-  @VariantId(15, variant: LinkedNodeKind.label)
-  int get label_colon;
-
   @VariantId(6, variant: LinkedNodeKind.label)
   LinkedNode get label_label;
 
@@ -1835,48 +1431,21 @@
   @VariantId(2, variant: LinkedNodeKind.libraryIdentifier)
   List<LinkedNode> get libraryIdentifier_components;
 
-  @VariantId(2, variant: LinkedNodeKind.listLiteral)
+  @VariantId(3, variant: LinkedNodeKind.listLiteral)
   List<LinkedNode> get listLiteral_elements;
 
-  @VariantId(15, variant: LinkedNodeKind.listLiteral)
-  int get listLiteral_leftBracket;
-
-  @VariantId(16, variant: LinkedNodeKind.listLiteral)
-  int get listLiteral_rightBracket;
-
   @VariantId(6, variant: LinkedNodeKind.mapLiteralEntry)
   LinkedNode get mapLiteralEntry_key;
 
-  @VariantId(15, variant: LinkedNodeKind.mapLiteralEntry)
-  int get mapLiteralEntry_separator;
-
   @VariantId(7, variant: LinkedNodeKind.mapLiteralEntry)
   LinkedNode get mapLiteralEntry_value;
 
-  @VariantId(19, variant: LinkedNodeKind.methodDeclaration)
-  int get methodDeclaration_actualProperty;
-
   @VariantId(6, variant: LinkedNodeKind.methodDeclaration)
   LinkedNode get methodDeclaration_body;
 
-  @VariantId(15, variant: LinkedNodeKind.methodDeclaration)
-  int get methodDeclaration_externalKeyword;
-
   @VariantId(7, variant: LinkedNodeKind.methodDeclaration)
   LinkedNode get methodDeclaration_formalParameters;
 
-  @VariantId(16, variant: LinkedNodeKind.methodDeclaration)
-  int get methodDeclaration_modifierKeyword;
-
-  @VariantId(10, variant: LinkedNodeKind.methodDeclaration)
-  LinkedNode get methodDeclaration_name;
-
-  @VariantId(17, variant: LinkedNodeKind.methodDeclaration)
-  int get methodDeclaration_operatorKeyword;
-
-  @VariantId(18, variant: LinkedNodeKind.methodDeclaration)
-  int get methodDeclaration_propertyKeyword;
-
   @VariantId(8, variant: LinkedNodeKind.methodDeclaration)
   LinkedNode get methodDeclaration_returnType;
 
@@ -1886,31 +1455,17 @@
   @VariantId(6, variant: LinkedNodeKind.methodInvocation)
   LinkedNode get methodInvocation_methodName;
 
-  @VariantId(15, variant: LinkedNodeKind.methodInvocation)
-  int get methodInvocation_operator;
-
   @VariantId(7, variant: LinkedNodeKind.methodInvocation)
   LinkedNode get methodInvocation_target;
 
-  @VariantId(15, variant: LinkedNodeKind.mixinDeclaration)
-  int get mixinDeclaration_mixinKeyword;
-
   @VariantId(6, variant: LinkedNodeKind.mixinDeclaration)
   LinkedNode get mixinDeclaration_onClause;
 
   @VariantId(36, variant: LinkedNodeKind.mixinDeclaration)
   List<String> get mixinDeclaration_superInvokedNames;
 
-  @VariantId(14, variantList: [
-    LinkedNodeKind.classDeclaration,
-    LinkedNodeKind.classTypeAlias,
-    LinkedNodeKind.enumDeclaration,
-    LinkedNodeKind.functionDeclaration,
-    LinkedNodeKind.functionTypeAlias,
-    LinkedNodeKind.genericTypeAlias,
-    LinkedNodeKind.mixinDeclaration,
-  ])
-  LinkedNode get namedCompilationUnitMember_name;
+  @Id(37)
+  String get name;
 
   @VariantId(6, variant: LinkedNodeKind.namedExpression)
   LinkedNode get namedExpression_expression;
@@ -1918,6 +1473,35 @@
   @VariantId(7, variant: LinkedNodeKind.namedExpression)
   LinkedNode get namedExpression_name;
 
+  @VariantId(16, variantList: [
+    LinkedNodeKind.classDeclaration,
+    LinkedNodeKind.classTypeAlias,
+    LinkedNodeKind.constructorDeclaration,
+    LinkedNodeKind.enumConstantDeclaration,
+    LinkedNodeKind.enumDeclaration,
+    LinkedNodeKind.exportDirective,
+    LinkedNodeKind.fieldFormalParameter,
+    LinkedNodeKind.functionDeclaration,
+    LinkedNodeKind.functionTypedFormalParameter,
+    LinkedNodeKind.functionTypeAlias,
+    LinkedNodeKind.genericTypeAlias,
+    LinkedNodeKind.importDirective,
+    LinkedNodeKind.methodDeclaration,
+    LinkedNodeKind.mixinDeclaration,
+    LinkedNodeKind.partDirective,
+    LinkedNodeKind.simpleFormalParameter,
+    LinkedNodeKind.typeParameter,
+    LinkedNodeKind.variableDeclaration,
+  ])
+  int get nameOffset;
+
+  @VariantId(36, variantList: [
+    LinkedNodeKind.hideCombinator,
+    LinkedNodeKind.showCombinator,
+    LinkedNodeKind.symbolLiteral,
+  ])
+  List<String> get names;
+
   @VariantId(2, variantList: [
     LinkedNodeKind.exportDirective,
     LinkedNodeKind.importDirective,
@@ -1939,15 +1523,6 @@
   @VariantId(6, variant: LinkedNodeKind.nativeClause)
   LinkedNode get nativeClause_name;
 
-  @VariantId(15, variant: LinkedNodeKind.nativeClause)
-  int get nativeClause_nativeKeyword;
-
-  @VariantId(15, variant: LinkedNodeKind.nativeFunctionBody)
-  int get nativeFunctionBody_nativeKeyword;
-
-  @VariantId(16, variant: LinkedNodeKind.nativeFunctionBody)
-  int get nativeFunctionBody_semicolon;
-
   @VariantId(6, variant: LinkedNodeKind.nativeFunctionBody)
   LinkedNode get nativeFunctionBody_stringLiteral;
 
@@ -1958,20 +1533,6 @@
   ])
   LinkedNode get normalFormalParameter_comment;
 
-  @VariantId(19, variantList: [
-    LinkedNodeKind.fieldFormalParameter,
-    LinkedNodeKind.functionTypedFormalParameter,
-    LinkedNodeKind.simpleFormalParameter,
-  ])
-  int get normalFormalParameter_covariantKeyword;
-
-  @VariantId(12, variantList: [
-    LinkedNodeKind.fieldFormalParameter,
-    LinkedNodeKind.functionTypedFormalParameter,
-    LinkedNodeKind.simpleFormalParameter,
-  ])
-  LinkedNode get normalFormalParameter_identifier;
-
   @VariantId(4, variantList: [
     LinkedNodeKind.fieldFormalParameter,
     LinkedNodeKind.functionTypedFormalParameter,
@@ -1979,18 +1540,8 @@
   ])
   List<LinkedNode> get normalFormalParameter_metadata;
 
-  @VariantId(18, variantList: [
-    LinkedNodeKind.fieldFormalParameter,
-    LinkedNodeKind.functionTypedFormalParameter,
-    LinkedNodeKind.simpleFormalParameter,
-  ])
-  int get normalFormalParameter_requiredKeyword;
-
   @VariantId(15, variant: LinkedNodeKind.nullLiteral)
-  int get nullLiteral_literal;
-
-  @VariantId(15, variant: LinkedNodeKind.onClause)
-  int get onClause_onKeyword;
+  int get nullLiteral_fake;
 
   @VariantId(2, variant: LinkedNodeKind.onClause)
   List<LinkedNode> get onClause_superclassConstraints;
@@ -1998,18 +1549,9 @@
   @VariantId(6, variant: LinkedNodeKind.parenthesizedExpression)
   LinkedNode get parenthesizedExpression_expression;
 
-  @VariantId(15, variant: LinkedNodeKind.parenthesizedExpression)
-  int get parenthesizedExpression_leftParenthesis;
-
-  @VariantId(16, variant: LinkedNodeKind.parenthesizedExpression)
-  int get parenthesizedExpression_rightParenthesis;
-
   @VariantId(6, variant: LinkedNodeKind.partOfDirective)
   LinkedNode get partOfDirective_libraryName;
 
-  @VariantId(16, variant: LinkedNodeKind.partOfDirective)
-  int get partOfDirective_ofKeyword;
-
   @VariantId(7, variant: LinkedNodeKind.partOfDirective)
   LinkedNode get partOfDirective_uri;
 
@@ -2022,15 +1564,12 @@
   @VariantId(6, variant: LinkedNodeKind.postfixExpression)
   LinkedNode get postfixExpression_operand;
 
-  @VariantId(16, variant: LinkedNodeKind.postfixExpression)
-  int get postfixExpression_operator;
+  @VariantId(28, variant: LinkedNodeKind.postfixExpression)
+  UnlinkedTokenType get postfixExpression_operator;
 
   @VariantId(6, variant: LinkedNodeKind.prefixedIdentifier)
   LinkedNode get prefixedIdentifier_identifier;
 
-  @VariantId(15, variant: LinkedNodeKind.prefixedIdentifier)
-  int get prefixedIdentifier_period;
-
   @VariantId(7, variant: LinkedNodeKind.prefixedIdentifier)
   LinkedNode get prefixedIdentifier_prefix;
 
@@ -2043,11 +1582,11 @@
   @VariantId(6, variant: LinkedNodeKind.prefixExpression)
   LinkedNode get prefixExpression_operand;
 
-  @VariantId(16, variant: LinkedNodeKind.prefixExpression)
-  int get prefixExpression_operator;
+  @VariantId(28, variant: LinkedNodeKind.prefixExpression)
+  UnlinkedTokenType get prefixExpression_operator;
 
-  @VariantId(15, variant: LinkedNodeKind.propertyAccess)
-  int get propertyAccess_operator;
+  @VariantId(28, variant: LinkedNodeKind.propertyAccess)
+  UnlinkedTokenType get propertyAccess_operator;
 
   @VariantId(6, variant: LinkedNodeKind.propertyAccess)
   LinkedNode get propertyAccess_propertyName;
@@ -2067,48 +1606,12 @@
   @VariantId(23, variant: LinkedNodeKind.redirectingConstructorInvocation)
   LinkedNodeType get redirectingConstructorInvocation_elementType;
 
-  @VariantId(16, variant: LinkedNodeKind.redirectingConstructorInvocation)
-  int get redirectingConstructorInvocation_period;
-
-  @VariantId(17, variant: LinkedNodeKind.redirectingConstructorInvocation)
-  int get redirectingConstructorInvocation_thisKeyword;
-
-  @VariantId(15, variant: LinkedNodeKind.rethrowExpression)
-  int get rethrowExpression_rethrowKeyword;
-
   @VariantId(6, variant: LinkedNodeKind.returnStatement)
   LinkedNode get returnStatement_expression;
 
-  @VariantId(15, variant: LinkedNodeKind.returnStatement)
-  int get returnStatement_returnKeyword;
-
-  @VariantId(16, variant: LinkedNodeKind.returnStatement)
-  int get returnStatement_semicolon;
-
-  @VariantId(15, variant: LinkedNodeKind.scriptTag)
-  int get scriptTag_scriptTag;
-
-  @VariantId(2, variant: LinkedNodeKind.setOrMapLiteral)
+  @VariantId(3, variant: LinkedNodeKind.setOrMapLiteral)
   List<LinkedNode> get setOrMapLiteral_elements;
 
-  @VariantId(27, variant: LinkedNodeKind.setOrMapLiteral)
-  bool get setOrMapLiteral_isMap;
-
-  @VariantId(31, variant: LinkedNodeKind.setOrMapLiteral)
-  bool get setOrMapLiteral_isSet;
-
-  @VariantId(15, variant: LinkedNodeKind.setOrMapLiteral)
-  int get setOrMapLiteral_leftBracket;
-
-  @VariantId(16, variant: LinkedNodeKind.setOrMapLiteral)
-  int get setOrMapLiteral_rightBracket;
-
-  @VariantId(2, variant: LinkedNodeKind.showCombinator)
-  List<LinkedNode> get showCombinator_shownNames;
-
-  @VariantId(15, variant: LinkedNodeKind.simpleFormalParameter)
-  int get simpleFormalParameter_keyword;
-
   @VariantId(6, variant: LinkedNodeKind.simpleFormalParameter)
   LinkedNode get simpleFormalParameter_type;
 
@@ -2118,15 +1621,6 @@
   @VariantId(23, variant: LinkedNodeKind.simpleIdentifier)
   LinkedNodeType get simpleIdentifier_elementType;
 
-  @VariantId(27, variant: LinkedNodeKind.simpleIdentifier)
-  bool get simpleIdentifier_isDeclaration;
-
-  @VariantId(16, variant: LinkedNodeKind.simpleIdentifier)
-  int get simpleIdentifier_token;
-
-  @VariantId(15, variant: LinkedNodeKind.simpleStringLiteral)
-  int get simpleStringLiteral_token;
-
   @VariantId(20, variant: LinkedNodeKind.simpleStringLiteral)
   String get simpleStringLiteral_value;
 
@@ -2142,8 +1636,8 @@
   @VariantId(6, variant: LinkedNodeKind.spreadElement)
   LinkedNode get spreadElement_expression;
 
-  @VariantId(15, variant: LinkedNodeKind.spreadElement)
-  int get spreadElement_spreadOperator;
+  @VariantId(38, variant: LinkedNodeKind.spreadElement)
+  UnlinkedTokenType get spreadElement_spreadOperator;
 
   @VariantId(2, variant: LinkedNodeKind.stringInterpolation)
   List<LinkedNode> get stringInterpolation_elements;
@@ -2160,30 +1654,9 @@
   @VariantId(23, variant: LinkedNodeKind.superConstructorInvocation)
   LinkedNodeType get superConstructorInvocation_elementType;
 
-  @VariantId(16, variant: LinkedNodeKind.superConstructorInvocation)
-  int get superConstructorInvocation_period;
-
-  @VariantId(17, variant: LinkedNodeKind.superConstructorInvocation)
-  int get superConstructorInvocation_superKeyword;
-
-  @VariantId(15, variant: LinkedNodeKind.superExpression)
-  int get superExpression_superKeyword;
-
   @VariantId(6, variant: LinkedNodeKind.switchCase)
   LinkedNode get switchCase_expression;
 
-  @VariantId(16, variantList: [
-    LinkedNodeKind.switchCase,
-    LinkedNodeKind.switchDefault,
-  ])
-  int get switchMember_colon;
-
-  @VariantId(15, variantList: [
-    LinkedNodeKind.switchCase,
-    LinkedNodeKind.switchDefault,
-  ])
-  int get switchMember_keyword;
-
   @VariantId(3, variantList: [
     LinkedNodeKind.switchCase,
     LinkedNodeKind.switchDefault,
@@ -2199,48 +1672,18 @@
   @VariantId(7, variant: LinkedNodeKind.switchStatement)
   LinkedNode get switchStatement_expression;
 
-  @VariantId(18, variant: LinkedNodeKind.switchStatement)
-  int get switchStatement_leftBracket;
-
-  @VariantId(15, variant: LinkedNodeKind.switchStatement)
-  int get switchStatement_leftParenthesis;
-
   @VariantId(2, variant: LinkedNodeKind.switchStatement)
   List<LinkedNode> get switchStatement_members;
 
-  @VariantId(19, variant: LinkedNodeKind.switchStatement)
-  int get switchStatement_rightBracket;
-
-  @VariantId(16, variant: LinkedNodeKind.switchStatement)
-  int get switchStatement_rightParenthesis;
-
-  @VariantId(17, variant: LinkedNodeKind.switchStatement)
-  int get switchStatement_switchKeyword;
-
-  @VariantId(28, variant: LinkedNodeKind.symbolLiteral)
-  List<int> get symbolLiteral_components;
-
-  @VariantId(15, variant: LinkedNodeKind.symbolLiteral)
-  int get symbolLiteral_poundSign;
-
-  @VariantId(15, variant: LinkedNodeKind.thisExpression)
-  int get thisExpression_thisKeyword;
-
   @VariantId(6, variant: LinkedNodeKind.throwExpression)
   LinkedNode get throwExpression_expression;
 
-  @VariantId(15, variant: LinkedNodeKind.throwExpression)
-  int get throwExpression_throwKeyword;
-
   @VariantId(35, variantList: [
     LinkedNodeKind.simpleFormalParameter,
     LinkedNodeKind.variableDeclaration,
   ])
   TopLevelInferenceError get topLevelTypeInferenceError;
 
-  @VariantId(15, variant: LinkedNodeKind.topLevelVariableDeclaration)
-  int get topLevelVariableDeclaration_semicolon;
-
   @VariantId(6, variant: LinkedNodeKind.topLevelVariableDeclaration)
   LinkedNode get topLevelVariableDeclaration_variableList;
 
@@ -2253,64 +1696,29 @@
   @VariantId(7, variant: LinkedNodeKind.tryStatement)
   LinkedNode get tryStatement_finallyBlock;
 
-  @VariantId(15, variant: LinkedNodeKind.tryStatement)
-  int get tryStatement_finallyKeyword;
-
-  @VariantId(16, variant: LinkedNodeKind.tryStatement)
-  int get tryStatement_tryKeyword;
-
   @VariantId(27, variantList: [
     LinkedNodeKind.functionTypeAlias,
     LinkedNodeKind.genericTypeAlias,
   ])
   bool get typeAlias_hasSelfReference;
 
-  @VariantId(19, variantList: [
-    LinkedNodeKind.classTypeAlias,
-    LinkedNodeKind.functionTypeAlias,
-    LinkedNodeKind.genericTypeAlias,
-  ])
-  int get typeAlias_semicolon;
-
-  @VariantId(18, variantList: [
-    LinkedNodeKind.classTypeAlias,
-    LinkedNodeKind.functionTypeAlias,
-    LinkedNodeKind.genericTypeAlias,
-  ])
-  int get typeAlias_typedefKeyword;
-
   @VariantId(2, variant: LinkedNodeKind.typeArgumentList)
   List<LinkedNode> get typeArgumentList_arguments;
 
-  @VariantId(15, variant: LinkedNodeKind.typeArgumentList)
-  int get typeArgumentList_leftBracket;
-
-  @VariantId(16, variant: LinkedNodeKind.typeArgumentList)
-  int get typeArgumentList_rightBracket;
-
-  @VariantId(19, variantList: [
+  @VariantId(2, variantList: [
     LinkedNodeKind.listLiteral,
     LinkedNodeKind.setOrMapLiteral,
   ])
-  int get typedLiteral_constKeyword;
-
-  @VariantId(14, variantList: [
-    LinkedNodeKind.listLiteral,
-    LinkedNodeKind.setOrMapLiteral,
-  ])
-  LinkedNode get typedLiteral_typeArguments;
+  List<LinkedNode> get typedLiteral_typeArguments;
 
   @VariantId(6, variant: LinkedNodeKind.typeName)
   LinkedNode get typeName_name;
 
-  @VariantId(15, variant: LinkedNodeKind.typeName)
-  int get typeName_question;
-
   @VariantId(23, variant: LinkedNodeKind.typeName)
   LinkedNodeType get typeName_type;
 
-  @VariantId(7, variant: LinkedNodeKind.typeName)
-  LinkedNode get typeName_typeArguments;
+  @VariantId(2, variant: LinkedNodeKind.typeName)
+  List<LinkedNode> get typeName_typeArguments;
 
   @VariantId(6, variant: LinkedNodeKind.typeParameter)
   LinkedNode get typeParameter_bound;
@@ -2318,18 +1726,6 @@
   @VariantId(23, variant: LinkedNodeKind.typeParameter)
   LinkedNodeType get typeParameter_defaultType;
 
-  @VariantId(15, variant: LinkedNodeKind.typeParameter)
-  int get typeParameter_extendsKeyword;
-
-  @VariantId(7, variant: LinkedNodeKind.typeParameter)
-  LinkedNode get typeParameter_name;
-
-  @VariantId(15, variant: LinkedNodeKind.typeParameterList)
-  int get typeParameterList_leftBracket;
-
-  @VariantId(16, variant: LinkedNodeKind.typeParameterList)
-  int get typeParameterList_rightBracket;
-
   @VariantId(2, variant: LinkedNodeKind.typeParameterList)
   List<LinkedNode> get typeParameterList_typeParameters;
 
@@ -2357,30 +1753,15 @@
   @VariantId(32, variant: LinkedNodeKind.variableDeclaration)
   LinkedNodeVariablesDeclaration get variableDeclaration_declaration;
 
-  @VariantId(15, variant: LinkedNodeKind.variableDeclaration)
-  int get variableDeclaration_equals;
-
   @VariantId(6, variant: LinkedNodeKind.variableDeclaration)
   LinkedNode get variableDeclaration_initializer;
 
-  @VariantId(7, variant: LinkedNodeKind.variableDeclaration)
-  LinkedNode get variableDeclaration_name;
-
-  @VariantId(15, variant: LinkedNodeKind.variableDeclarationList)
-  int get variableDeclarationList_keyword;
-
-  @VariantId(16, variant: LinkedNodeKind.variableDeclarationList)
-  int get variableDeclarationList_lateKeyword;
-
   @VariantId(6, variant: LinkedNodeKind.variableDeclarationList)
   LinkedNode get variableDeclarationList_type;
 
   @VariantId(2, variant: LinkedNodeKind.variableDeclarationList)
   List<LinkedNode> get variableDeclarationList_variables;
 
-  @VariantId(15, variant: LinkedNodeKind.variableDeclarationStatement)
-  int get variableDeclarationStatement_semicolon;
-
   @VariantId(6, variant: LinkedNodeKind.variableDeclarationStatement)
   LinkedNode get variableDeclarationStatement_variables;
 
@@ -2390,32 +1771,11 @@
   @VariantId(7, variant: LinkedNodeKind.whileStatement)
   LinkedNode get whileStatement_condition;
 
-  @VariantId(15, variant: LinkedNodeKind.whileStatement)
-  int get whileStatement_leftParenthesis;
-
-  @VariantId(16, variant: LinkedNodeKind.whileStatement)
-  int get whileStatement_rightParenthesis;
-
-  @VariantId(17, variant: LinkedNodeKind.whileStatement)
-  int get whileStatement_whileKeyword;
-
   @VariantId(2, variant: LinkedNodeKind.withClause)
   List<LinkedNode> get withClause_mixinTypes;
 
-  @VariantId(15, variant: LinkedNodeKind.withClause)
-  int get withClause_withKeyword;
-
   @VariantId(6, variant: LinkedNodeKind.yieldStatement)
   LinkedNode get yieldStatement_expression;
-
-  @VariantId(17, variant: LinkedNodeKind.yieldStatement)
-  int get yieldStatement_semicolon;
-
-  @VariantId(16, variant: LinkedNodeKind.yieldStatement)
-  int get yieldStatement_star;
-
-  @VariantId(15, variant: LinkedNodeKind.yieldStatement)
-  int get yieldStatement_yieldKeyword;
 }
 
 /// Information about a group of libraries linked together, for example because
@@ -2537,7 +1897,6 @@
   redirectingConstructorInvocation,
   rethrowExpression,
   returnStatement,
-  scriptTag,
   setOrMapLiteral,
   showCombinator,
   simpleFormalParameter,
@@ -2667,6 +2026,15 @@
 
 /// Information about a single library in a [LinkedNodeLibrary].
 abstract class LinkedNodeUnit extends base.SummaryClass {
+  /// All generic function types in the unit - in generic type aliases, or used
+  /// directly as type annotations.
+  ///
+  /// They are requested in two cases: when we are reading a node that contains
+  /// them (e.g. a return type of a method), or when we run over unresolved
+  /// AST in declaration resolver.
+  @Id(5)
+  List<LinkedNode> get genericFunctionTypes;
+
   @Id(3)
   bool get isSynthetic;
 
@@ -2683,6 +2051,9 @@
 
   @Id(0)
   String get uriStr;
+
+  @Id(6)
+  bool get isNNBD;
 }
 
 /// Information about a top-level declaration, or a field declaration that
@@ -2812,6 +2183,10 @@
   @deprecated
   String get apiSignature;
 
+  /// The version 2 of the summary.
+  @Id(9)
+  LinkedNodeBundle get bundle2;
+
   /// Information about the packages this package depends on, if known.
   @Id(8)
   @informative
@@ -4769,6 +4144,10 @@
   @Id(5)
   List<UnlinkedImport> get imports;
 
+  /// Indicates whether this compilation unit is opted into NNBD.
+  @Id(21)
+  bool get isNNBD;
+
   /// Indicates whether the unit contains a "part of" declaration.
   @Id(18)
   bool get isPartOf;
diff --git a/pkg/analyzer/lib/src/summary/link.dart b/pkg/analyzer/lib/src/summary/link.dart
index 9723dd5..5bc3580 100644
--- a/pkg/analyzer/lib/src/summary/link.dart
+++ b/pkg/analyzer/lib/src/summary/link.dart
@@ -187,7 +187,10 @@
     CompilationUnitElementInBuildUnit compilationUnit,
     TypeParameterSerializationContext typeParameterContext,
     {int slot}) {
-  EntityRefBuilder result = new EntityRefBuilder(slot: slot);
+  EntityRefBuilder result = new EntityRefBuilder(
+      slot: slot,
+      nullabilitySuffix:
+          encodeNullabilitySuffix((type as TypeImpl).nullabilitySuffix));
   if (type is InterfaceType) {
     ClassElementForLink element = type.element;
     result.reference = compilationUnit.addReference(element);
@@ -1413,11 +1416,12 @@
         return DynamicTypeImpl.instance;
       }
     }
+    DartType result;
     if (entity.paramReference != 0) {
-      return context.typeParameterContext
+      result = context.typeParameterContext
           .getTypeParameterType(entity.paramReference);
     } else if (entity.entityKind == EntityRefKind.genericFunctionType) {
-      return new GenericFunctionTypeElementForLink(
+      result = new GenericFunctionTypeElementForLink(
               this,
               context,
               entity.typeParameters,
@@ -1427,13 +1431,13 @@
     } else if (entity.syntheticReturnType != null) {
       FunctionElementImpl element =
           new FunctionElementForLink_Synthetic(this, context, entity);
-      return element.type;
+      result = element.type;
     } else if (entity.implicitFunctionTypeIndices.isNotEmpty) {
       DartType type = resolveRef(entity.reference).asStaticType;
       for (int index in entity.implicitFunctionTypeIndices) {
         type = (type as FunctionType).parameters[index].type;
       }
-      return type;
+      result = type;
     } else {
       ReferenceableElementForLink element = resolveRef(entity.reference);
       bool implicitTypeArgumentsInUse = false;
@@ -1452,13 +1456,14 @@
         }
       }
 
-      var type = element.buildType(
+      result = element.buildType(
           getTypeArgument, entity.implicitFunctionTypeIndices);
       if (implicitTypeArgumentsInUse) {
-        _typesWithImplicitArguments[type] = true;
+        _typesWithImplicitArguments[result] = true;
       }
-      return type;
     }
+    var nullabilitySuffix = decodeNullabilitySuffix(entity.nullabilitySuffix);
+    return (result as TypeImpl).withNullability(nullabilitySuffix);
   }
 
   @override
@@ -2471,7 +2476,7 @@
         reportConstEvaluationErrors: false);
     var typeResolverVisitor = new TypeResolverVisitor(
         library, source, typeProvider, errorListener,
-        nameScope: nameScope);
+        featureSet: featureSet, nameScope: nameScope);
     var variableResolverVisitor = new VariableResolverVisitor(
         library, source, typeProvider, errorListener,
         nameScope: nameScope, localVariableInfo: LocalVariableInfo());
@@ -3600,6 +3605,9 @@
   }
 
   @override
+  bool get isNonNullableByDefault => _unlinkedDefiningUnit.isNNBD;
+
+  @override
   ContextForLink get context => _linker.context;
 
   @override
@@ -5390,7 +5398,6 @@
   InterfaceType _listType;
   InterfaceType _mapType;
   InterfaceType _mapObjectObjectType;
-  InterfaceType _neverType;
   InterfaceType _nullType;
   InterfaceType _numType;
   InterfaceType _objectType;
@@ -5475,8 +5482,7 @@
       _mapType ??= _buildInterfaceType(_linker.coreLibrary, 'Map');
 
   @override
-  InterfaceType get neverType =>
-      _neverType ??= _buildInterfaceType(_linker.coreLibrary, 'Never');
+  DartType get neverType => BottomTypeImpl.instance;
 
   @override
   DartObjectImpl get nullObject {
diff --git a/pkg/analyzer/lib/src/summary/resynthesize.dart b/pkg/analyzer/lib/src/summary/resynthesize.dart
index 6f8720e..fbe8c41 100644
--- a/pkg/analyzer/lib/src/summary/resynthesize.dart
+++ b/pkg/analyzer/lib/src/summary/resynthesize.dart
@@ -31,6 +31,30 @@
  */
 final _typesWithImplicitTypeArguments = new Expando();
 
+NullabilitySuffix decodeNullabilitySuffix(EntityRefNullabilitySuffix suffix) {
+  switch (suffix) {
+    case EntityRefNullabilitySuffix.none:
+      return NullabilitySuffix.none;
+    case EntityRefNullabilitySuffix.question:
+      return NullabilitySuffix.question;
+    case EntityRefNullabilitySuffix.starOrIrrelevant:
+      return NullabilitySuffix.star;
+  }
+  throw new StateError('Unrecognized nullability suffix');
+}
+
+EntityRefNullabilitySuffix encodeNullabilitySuffix(NullabilitySuffix suffix) {
+  switch (suffix) {
+    case NullabilitySuffix.none:
+      return EntityRefNullabilitySuffix.none;
+    case NullabilitySuffix.question:
+      return EntityRefNullabilitySuffix.question;
+    case NullabilitySuffix.star:
+      return EntityRefNullabilitySuffix.starOrIrrelevant;
+  }
+  throw new StateError('Unrecognized nullability suffix');
+}
+
 /// An instance of [LibraryResynthesizer] is responsible for resynthesizing the
 /// elements in a single library from that library's summary.
 abstract class LibraryResynthesizer {
@@ -329,7 +353,7 @@
       Source librarySource = _getSource(uri);
       if (serializedLibrary == null) {
         LibraryElementImpl libraryElement =
-            new LibraryElementImpl(context, session, '', -1, 0);
+            new LibraryElementImpl(context, session, '', -1, 0, true);
         libraryElement.isSynthetic = true;
         CompilationUnitElementImpl unitElement =
             new CompilationUnitElementImpl();
@@ -1343,17 +1367,18 @@
         type = refinedType;
       }
     }
+    DartType result;
     if (type.paramReference != 0) {
-      return context.typeParameterContext
+      result = context.typeParameterContext
           .getTypeParameterType(type.paramReference);
     } else if (type.entityKind == EntityRefKind.genericFunctionType) {
       GenericFunctionTypeElement element =
           new GenericFunctionTypeElementImpl.forSerialized(context, type);
-      return element.type;
+      result = element.type;
     } else if (type.syntheticReturnType != null) {
       FunctionElementImpl element =
           new FunctionElementImpl_forLUB(context, type);
-      return element.type;
+      result = element.type;
     } else {
       DartType getTypeArgument(int i) {
         if (i < type.typeArguments.length) {
@@ -1369,12 +1394,14 @@
         return DynamicTypeImpl.instance;
       }
 
-      return referenceInfo.buildType(
+      result = referenceInfo.buildType(
           instantiateToBoundsAllowed,
           type.typeArguments.length,
           getTypeArgument,
           type.implicitFunctionTypeIndices);
     }
+    var nullabilitySuffix = decodeNullabilitySuffix(type.nullabilitySuffix);
+    return (result as TypeImpl).withNullability(nullabilitySuffix);
   }
 
   @override
diff --git a/pkg/analyzer/lib/src/summary/summarize_ast.dart b/pkg/analyzer/lib/src/summary/summarize_ast.dart
index b50d8cd..3608b07 100644
--- a/pkg/analyzer/lib/src/summary/summarize_ast.dart
+++ b/pkg/analyzer/lib/src/summary/summarize_ast.dart
@@ -491,7 +491,8 @@
       unlinkedImports.add(new UnlinkedImportBuilder(isImplicit: true));
     }
     compilationUnit.declarations.accept(this);
-    UnlinkedUnitBuilder b = new UnlinkedUnitBuilder();
+    UnlinkedUnitBuilder b = new UnlinkedUnitBuilder(
+        isNNBD: compilationUnit.featureSet.isEnabled(Feature.non_nullable));
     b.lineStarts = compilationUnit.lineInfo?.lineStarts;
     b.isPartOf = isPartOf;
     b.libraryName = libraryName;
diff --git a/pkg/analyzer/lib/src/summary/summarize_elements.dart b/pkg/analyzer/lib/src/summary/summarize_elements.dart
index ba4cc40..08732d5 100644
--- a/pkg/analyzer/lib/src/summary/summarize_elements.dart
+++ b/pkg/analyzer/lib/src/summary/summarize_elements.dart
@@ -35,6 +35,8 @@
   final Map<String, UnlinkedUnitBuilder> _unlinkedUnitMap =
       <String, UnlinkedUnitBuilder>{};
 
+  LinkedNodeBundleBuilder _bundle2;
+
   void addLinkedLibrary(String uri, LinkedLibraryBuilder library) {
     _linkedLibraries.add(library);
     _linkedLibraryUris.add(uri);
@@ -60,6 +62,14 @@
         unlinkedUnitUris: _unlinkedUnitUris,
         unlinkedUnits: _unlinkedUnits,
         majorVersion: currentMajorVersion,
-        minorVersion: currentMinorVersion);
+        minorVersion: currentMinorVersion,
+        bundle2: _bundle2);
+  }
+
+  void setBundle2(LinkedNodeBundleBuilder bundle2) {
+    if (this._bundle2 != null) {
+      throw StateError('Bundle2 may be set only once.');
+    }
+    _bundle2 = bundle2;
   }
 }
diff --git a/pkg/analyzer/lib/src/summary/summary_file_builder.dart b/pkg/analyzer/lib/src/summary/summary_file_builder.dart
index c558609..7bbab6b 100644
--- a/pkg/analyzer/lib/src/summary/summary_file_builder.dart
+++ b/pkg/analyzer/lib/src/summary/summary_file_builder.dart
@@ -11,6 +11,7 @@
 import 'package:analyzer/error/listener.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/file_system/physical_file_system.dart';
+import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/scanner/reader.dart';
 import 'package:analyzer/src/dart/scanner/scanner.dart';
 import 'package:analyzer/src/dart/sdk/sdk.dart';
@@ -23,6 +24,9 @@
 import 'package:analyzer/src/summary/link.dart';
 import 'package:analyzer/src/summary/summarize_ast.dart';
 import 'package:analyzer/src/summary/summarize_elements.dart';
+import 'package:analyzer/src/summary2/link.dart' as summary2;
+import 'package:analyzer/src/summary2/linked_element_factory.dart' as summary2;
+import 'package:analyzer/src/summary2/reference.dart' as summary2;
 
 class SummaryBuilder {
   final Iterable<Source> librarySources;
@@ -73,6 +77,7 @@
 
   final Set<String> libraryUris = new Set<String>();
   final Map<String, UnlinkedUnit> unlinkedMap = <String, UnlinkedUnit>{};
+  final List<summary2.LinkInputLibrary> inputLibraries = [];
 
   final PackageBundleAssembler bundleAssembler = new PackageBundleAssembler();
 
@@ -95,6 +100,8 @@
     }, DeclaredVariables(), context.analysisOptions);
     map.forEach(bundleAssembler.addLinkedLibrary);
 
+    _link2();
+
     return bundleAssembler.assemble().toBuffer();
   }
 
@@ -103,8 +110,16 @@
     if (!libraryUris.add(uriStr)) {
       return;
     }
-    CompilationUnit unit = _addUnlinked(source);
-    for (Directive directive in unit.directives) {
+
+    var inputUnits = <summary2.LinkInputUnit>[];
+
+    CompilationUnit definingUnit = _parse(source);
+    _addUnlinked(source, definingUnit);
+    inputUnits.add(
+      summary2.LinkInputUnit(source, false, definingUnit),
+    );
+
+    for (Directive directive in definingUnit.directives) {
       if (directive is NamespaceDirective) {
         String libUri = directive.uri.stringValue;
         Source libSource = context.sourceFactory.resolveUri(source, libUri);
@@ -112,18 +127,40 @@
       } else if (directive is PartDirective) {
         String partUri = directive.uri.stringValue;
         Source partSource = context.sourceFactory.resolveUri(source, partUri);
-        _addUnlinked(partSource);
+        CompilationUnit partUnit = _parse(partSource);
+        _addUnlinked(partSource, partUnit);
+        inputUnits.add(
+          summary2.LinkInputUnit(partSource, false, partUnit),
+        );
       }
     }
+
+    inputLibraries.add(
+      summary2.LinkInputLibrary(source, inputUnits),
+    );
   }
 
-  CompilationUnit _addUnlinked(Source source) {
+  void _addUnlinked(Source source, CompilationUnit unit) {
     String uriStr = source.uri.toString();
-    CompilationUnit unit = _parse(source);
     UnlinkedUnitBuilder unlinked = serializeAstUnlinked(unit);
     unlinkedMap[uriStr] = unlinked;
     bundleAssembler.addUnlinkedUnit(source, unlinked);
-    return unit;
+  }
+
+  void _link2() {
+    var rootReference = summary2.Reference.root();
+    var dartCoreRef = rootReference.getChild('dart:core');
+    dartCoreRef.getChild('dynamic').element = DynamicElementImpl.instance;
+    dartCoreRef.getChild('Never').element = NeverElementImpl.instance;
+
+    var elementFactory = summary2.LinkedElementFactory(
+      context,
+      null,
+      rootReference,
+    );
+
+    var linkResult = summary2.link(elementFactory, inputLibraries);
+    bundleAssembler.setBundle2(linkResult.bundle);
   }
 
   CompilationUnit _parse(Source source) {
diff --git a/pkg/analyzer/lib/src/summary/summary_sdk.dart b/pkg/analyzer/lib/src/summary/summary_sdk.dart
index 28dc74a..516ca6b 100644
--- a/pkg/analyzer/lib/src/summary/summary_sdk.dart
+++ b/pkg/analyzer/lib/src/summary/summary_sdk.dart
@@ -128,7 +128,6 @@
   InterfaceType _listType;
   InterfaceType _mapType;
   InterfaceType _mapObjectObjectType;
-  InterfaceType _neverType;
   DartObjectImpl _nullObject;
   InterfaceType _nullType;
   InterfaceType _numType;
@@ -267,10 +266,7 @@
   }
 
   @override
-  InterfaceType get neverType {
-    assert(_coreLibrary != null);
-    return _neverType ??= _getType(_coreLibrary, 'Never');
-  }
+  DartType get neverType => BottomTypeImpl.instance;
 
   @override
   DartObjectImpl get nullObject {
diff --git a/pkg/analyzer/lib/src/summary2/ast_binary_flags.dart b/pkg/analyzer/lib/src/summary2/ast_binary_flags.dart
new file mode 100644
index 0000000..5f973e1
--- /dev/null
+++ b/pkg/analyzer/lib/src/summary2/ast_binary_flags.dart
@@ -0,0 +1,525 @@
+// 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';
+
+class AstBinaryFlags {
+  static final Map<Type, int> _typeBits = {};
+
+  static final _hasAwait = _checkBit(
+    0,
+    ForElement,
+    ForStatement,
+  );
+
+  static final _hasEqual = _checkBit(
+    0,
+    Configuration,
+  );
+
+  static final _hasInitializer = _checkBit(
+    0,
+    DefaultFormalParameter,
+    VariableDeclaration,
+  );
+
+  static final _hasNot = _checkBit(
+    0,
+    IsExpression,
+  );
+
+  static final _hasPeriod = _checkBit(
+    0,
+    IndexExpression,
+    MethodInvocation,
+  );
+
+  static final _hasPeriod2 = _checkBit(
+    1,
+    MethodInvocation,
+  );
+
+  static final _hasQuestion = _checkBit(
+    1,
+    GenericFunctionType,
+    TypeName,
+  );
+
+  static final _hasSeparatorColon = _checkBit(
+    0,
+    ConstructorDeclaration,
+  );
+
+  static final _hasSeparatorEquals = _checkBit(
+    2,
+    ConstructorDeclaration,
+  );
+
+  static final _hasThis = _checkBit(
+    0,
+    ConstructorFieldInitializer,
+    RedirectingConstructorInvocation,
+  );
+
+  static final _hasTypeArguments = _checkBit(
+    0,
+    TypedLiteral,
+    TypeName,
+  );
+
+  static final _isAbstract = _checkBit(
+    1,
+    ClassDeclaration,
+    ClassTypeAlias,
+    ConstructorDeclaration,
+    MethodDeclaration,
+  );
+
+  static final _isAsync = _checkBit(
+    2,
+    BlockFunctionBody,
+    EmptyFunctionBody,
+    FunctionExpression,
+    MethodDeclaration,
+  );
+
+  static final _isConst = _checkBit(
+    3,
+    ConstructorDeclaration,
+    DeclaredIdentifier,
+    InstanceCreationExpression,
+    NormalFormalParameter,
+    TypedLiteral,
+    VariableDeclarationList,
+  );
+
+  static final _isCovariant = _checkBit(
+    2,
+    FieldDeclaration,
+    NormalFormalParameter,
+  );
+
+  static final _isDeclaration = _checkBit(
+    0,
+    SimpleIdentifier,
+  );
+
+  static final _isDeferred = _checkBit(
+    0,
+    ImportDirective,
+  );
+
+  static final _isDelimiterCurly = _checkBit(
+    0,
+    FormalParameterList,
+  );
+
+  static final _isDelimiterSquare = _checkBit(
+    1,
+    FormalParameterList,
+  );
+
+  static final _isExternal = _checkBit(
+    7,
+    ConstructorDeclaration,
+    FunctionDeclaration,
+    MethodDeclaration,
+  );
+
+  static final _isFactory = _checkBit(
+    4,
+    ConstructorDeclaration,
+  );
+
+  static final _isFinal = _checkBit(
+    4,
+    DeclaredIdentifier,
+    NormalFormalParameter,
+    VariableDeclarationList,
+  );
+
+  static final _isGenerator = _checkBit(
+    3,
+    FunctionExpression,
+    MethodDeclaration,
+  );
+
+  static final _isGet = _checkBit(
+    4,
+    FunctionDeclaration,
+    MethodDeclaration,
+  );
+
+  static final _isLate = _checkBit(
+    0,
+    VariableDeclarationList,
+  );
+
+  static final _isMap = _checkBit(
+    1,
+    TypedLiteral,
+  );
+
+  static final _isNew = _checkBit(
+    0,
+    InstanceCreationExpression,
+  );
+
+  static final _isOperator = _checkBit(
+    0,
+    MethodDeclaration,
+  );
+
+  static final _isRequired = _checkBit(
+    0,
+    NormalFormalParameter,
+  );
+
+  static final _isSet = _checkBit(
+    5,
+    FunctionDeclaration,
+    MethodDeclaration,
+    TypedLiteral,
+  );
+
+  static final _isStar = _checkBit(
+    0,
+    BlockFunctionBody,
+    YieldStatement,
+  );
+
+  static final _isStatic = _checkBit(
+    6,
+    FieldDeclaration,
+    MethodDeclaration,
+  );
+
+  static final _isStringInterpolationIdentifier = _checkBit(
+    0,
+    InterpolationExpression,
+  );
+
+  static final _isSync = _checkBit(
+    3,
+    BlockFunctionBody,
+    ExpressionFunctionBody,
+  );
+
+  static final _isVar = _checkBit(
+    1,
+    DeclaredIdentifier,
+    NormalFormalParameter,
+    VariableDeclarationList,
+  );
+
+  static int encode({
+    bool hasAwait: false,
+    bool hasEqual: false,
+    bool hasInitializer: false,
+    bool hasNot: false,
+    bool hasPeriod: false,
+    bool hasPeriod2: false,
+    bool hasQuestion: false,
+    bool hasSeparatorColon: false,
+    bool hasSeparatorEquals: false,
+    bool hasThis: false,
+    bool hasTypeArguments: false,
+    bool isAbstract: false,
+    bool isAsync: false,
+    bool isConst: false,
+    bool isCovariant: false,
+    bool isDeclaration: false,
+    bool isDeferred: false,
+    bool isDelimiterCurly: false,
+    bool isDelimiterSquare: false,
+    bool isExternal: false,
+    bool isFactory: false,
+    bool isFinal: false,
+    bool isGenerator: false,
+    bool isGet: false,
+    bool isLate: false,
+    bool isMap: false,
+    bool isNew: false,
+    bool isOperator: false,
+    bool isRequired: false,
+    bool isSet: false,
+    bool isStar: false,
+    bool isStatic: false,
+    bool isStringInterpolationIdentifier: false,
+    bool isSync: false,
+    bool isVar: false,
+  }) {
+    var result = 0;
+    if (hasAwait) {
+      result |= _hasAwait;
+    }
+    if (hasEqual) {
+      result |= _hasEqual;
+    }
+    if (hasInitializer) {
+      result |= _hasInitializer;
+    }
+    if (hasNot) {
+      result |= _hasNot;
+    }
+    if (hasPeriod) {
+      result |= _hasPeriod;
+    }
+    if (hasPeriod2) {
+      result |= _hasPeriod2;
+    }
+    if (hasQuestion) {
+      result |= _hasQuestion;
+    }
+    if (hasSeparatorColon) {
+      result |= _hasSeparatorColon;
+    }
+    if (hasSeparatorEquals) {
+      result |= _hasSeparatorEquals;
+    }
+    if (hasThis) {
+      result |= _hasThis;
+    }
+    if (hasTypeArguments) {
+      result |= _hasTypeArguments;
+    }
+    if (isAbstract) {
+      result |= _isAbstract;
+    }
+    if (isAsync) {
+      result |= _isAsync;
+    }
+    if (isCovariant) {
+      result |= _isCovariant;
+    }
+    if (isDeclaration) {
+      result |= _isDeclaration;
+    }
+    if (isDeferred) {
+      result |= _isDeferred;
+    }
+    if (isDelimiterCurly) {
+      result |= _isDelimiterCurly;
+    }
+    if (isDelimiterSquare) {
+      result |= _isDelimiterSquare;
+    }
+    if (isConst) {
+      result |= _isConst;
+    }
+    if (isExternal) {
+      result |= _isExternal;
+    }
+    if (isFactory) {
+      result |= _isFactory;
+    }
+    if (isFinal) {
+      result |= _isFinal;
+    }
+    if (isGenerator) {
+      result |= _isGenerator;
+    }
+    if (isGet) {
+      result |= _isGet;
+    }
+    if (isLate) {
+      result |= _isLate;
+    }
+    if (isMap) {
+      result |= _isMap;
+    }
+    if (isNew) {
+      result |= _isNew;
+    }
+    if (isOperator) {
+      result |= _isOperator;
+    }
+    if (isRequired) {
+      result |= _isRequired;
+    }
+    if (isSet) {
+      result |= _isSet;
+    }
+    if (isStar) {
+      result |= _isStar;
+    }
+    if (isStatic) {
+      result |= _isStatic;
+    }
+    if (isStringInterpolationIdentifier) {
+      result |= _isStringInterpolationIdentifier;
+    }
+    if (isSync) {
+      result |= _isSync;
+    }
+    if (isVar) {
+      result |= _isVar;
+    }
+    return result;
+  }
+
+  static bool hasAwait(int flags) {
+    return (flags & _hasAwait) != 0;
+  }
+
+  static bool hasEqual(int flags) {
+    return (flags & _hasEqual) != 0;
+  }
+
+  static bool hasInitializer(int flags) {
+    return (flags & _hasInitializer) != 0;
+  }
+
+  static bool hasNot(int flags) {
+    return (flags & _hasNot) != 0;
+  }
+
+  static bool hasPeriod(int flags) {
+    return (flags & _hasPeriod) != 0;
+  }
+
+  static bool hasPeriod2(int flags) {
+    return (flags & _hasPeriod2) != 0;
+  }
+
+  static bool hasQuestion(int flags) {
+    return (flags & _isStringInterpolationIdentifier) != 0;
+  }
+
+  static bool hasSeparatorColon(int flags) {
+    return (flags & _hasSeparatorColon) != 0;
+  }
+
+  static bool hasSeparatorEquals(int flags) {
+    return (flags & _hasSeparatorEquals) != 0;
+  }
+
+  static bool hasThis(int flags) {
+    return (flags & _hasThis) != 0;
+  }
+
+  static bool hasTypeArguments(int flags) {
+    return (flags & _hasTypeArguments) != 0;
+  }
+
+  static bool isAbstract(int flags) {
+    return (flags & _isAbstract) != 0;
+  }
+
+  static bool isAsync(int flags) {
+    return (flags & _isAsync) != 0;
+  }
+
+  static bool isConst(int flags) {
+    return (flags & _isConst) != 0;
+  }
+
+  static bool isCovariant(int flags) {
+    return (flags & _isCovariant) != 0;
+  }
+
+  static bool isDeclaration(int flags) {
+    return (flags & _isDeclaration) != 0;
+  }
+
+  static bool isDeferred(int flags) {
+    return (flags & _isDeferred) != 0;
+  }
+
+  static bool isDelimiterCurly(int flags) {
+    return (flags & _isDelimiterCurly) != 0;
+  }
+
+  static bool isDelimiterSquare(int flags) {
+    return (flags & _isDelimiterSquare) != 0;
+  }
+
+  static bool isExternal(int flags) {
+    return (flags & _isExternal) != 0;
+  }
+
+  static bool isFactory(int flags) {
+    return (flags & _isFactory) != 0;
+  }
+
+  static bool isFinal(int flags) {
+    return (flags & _isFinal) != 0;
+  }
+
+  static bool isGenerator(int flags) {
+    return (flags & _isGenerator) != 0;
+  }
+
+  static bool isGet(int flags) {
+    return (flags & _isGet) != 0;
+  }
+
+  static bool isLate(int flags) {
+    return (flags & _isLate) != 0;
+  }
+
+  static bool isMap(int flags) {
+    return (flags & _isMap) != 0;
+  }
+
+  static bool isNew(int flags) {
+    return (flags & _isNew) != 0;
+  }
+
+  static bool isOperator(int flags) {
+    return (flags & _isOperator) != 0;
+  }
+
+  static bool isRequired(int flags) {
+    return (flags & _isRequired) != 0;
+  }
+
+  static bool isSet(int flags) {
+    return (flags & _isSet) != 0;
+  }
+
+  static bool isStar(int flags) {
+    return (flags & _isStar) != 0;
+  }
+
+  static bool isStatic(int flags) {
+    return (flags & _isStatic) != 0;
+  }
+
+  static bool isStringInterpolationIdentifier(int flags) {
+    return (flags & _isStringInterpolationIdentifier) != 0;
+  }
+
+  static bool isSync(int flags) {
+    return (flags & _isSync) != 0;
+  }
+
+  static bool isVar(int flags) {
+    return (flags & _isVar) != 0;
+  }
+
+  /// Check the bit for its uniqueness for the given types.
+  static int _checkBit(int shift, Type type1,
+      [Type type2, Type type3, Type type4, Type type5, Type type6]) {
+    _checkBit0(shift, type1);
+    _checkBit0(shift, type2);
+    _checkBit0(shift, type3);
+    _checkBit0(shift, type4);
+    _checkBit0(shift, type5);
+    _checkBit0(shift, type6);
+    return 1 << shift;
+  }
+
+  /// Check the bit for its uniqueness for the [type].
+  static void _checkBit0(int shift, Type type) {
+    if (type != null) {
+      var currentBits = _typeBits[type] ?? 0;
+      var bit = 1 << shift;
+      if ((currentBits & bit) != 0) {
+        throw StateError('1 << $shift is already used for $type');
+      }
+      _typeBits[type] = currentBits | bit;
+    }
+  }
+}
diff --git a/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart b/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
index 4927499..9de3d22 100644
--- a/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
+++ b/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
@@ -9,10 +9,22 @@
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/dart/ast/ast.dart';
 import 'package:analyzer/src/dart/element/member.dart';
+import 'package:analyzer/src/generated/testing/ast_test_factory.dart';
+import 'package:analyzer/src/generated/testing/token_factory.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart';
 import 'package:analyzer/src/summary/idl.dart';
+import 'package:analyzer/src/summary2/ast_binary_flags.dart';
 import 'package:analyzer/src/summary2/lazy_ast.dart';
 import 'package:analyzer/src/summary2/linked_unit_context.dart';
+import 'package:analyzer/src/summary2/tokens_context.dart';
+
+var timerAstBinaryReader = Stopwatch();
+var timerAstBinaryReaderClass = Stopwatch();
+var timerAstBinaryReaderDirective = Stopwatch();
+var timerAstBinaryReaderFunctionBody = Stopwatch();
+var timerAstBinaryReaderFunctionDeclaration = Stopwatch();
+var timerAstBinaryReaderMixin = Stopwatch();
+var timerAstBinaryReaderTopLevelVar = Stopwatch();
 
 /// Deserializer of fully resolved ASTs from flat buffers.
 class AstBinaryReader {
@@ -23,21 +35,97 @@
 
   AstBinaryReader(this._unitContext);
 
-  AstNode readNode(LinkedNode data) {
-    var node = _readNode(data);
-    if (node == null) return null;
+  InterfaceType get _boolType => _unitContext.typeProvider.boolType;
 
-    if (!isLazy) {
-      _unitContext.tokensContext.linkTokens(node.beginToken, node.endToken);
+  InterfaceType get _doubleType => _unitContext.typeProvider.doubleType;
+
+  InterfaceType get _intType => _unitContext.typeProvider.intType;
+
+  DartType get _nullType => _unitContext.typeProvider.nullType;
+
+  InterfaceType get _stringType => _unitContext.typeProvider.stringType;
+
+  /// This method is invoked by [LinkedUnitContext] to finish reading.
+  void readGenericFunctionTypeFinish(
+    LinkedNode data,
+    GenericFunctionType node,
+  ) {
+    var typeParameterListData = data.genericFunctionType_typeParameters;
+    if (typeParameterListData != null) {
+      var dataList = typeParameterListData.typeParameterList_typeParameters;
+      var typeParameters = node.typeParameters.typeParameters;
+      for (var i = 0; i < dataList.length; ++i) {
+        var data = dataList[i];
+        var node = typeParameters[i];
+        node.bound = _readNode(data.typeParameter_bound);
+      }
+    }
+    node.returnType = readNode(data.genericFunctionType_returnType);
+    node.parameters = _readNode(data.genericFunctionType_formalParameters);
+  }
+
+  /// This method is invoked by [LinkedUnitContext] to perform shallow reading.
+  ///
+  /// It reads [TypeParameter] names, and creates [GenericFunctionType] node,
+  /// so that [LinkedUnitContext] can create elements for these nodes.
+  ///
+  /// But we cannot read the return type and formal parameters yet, until the
+  /// corresponding elements are created.
+  GenericFunctionType readGenericFunctionTypeShallow(LinkedNode data) {
+    TypeParameterList typeParameterList;
+    var typeParameterListData = data.genericFunctionType_typeParameters;
+    if (typeParameterListData != null) {
+      var dataList = typeParameterListData.typeParameterList_typeParameters;
+      var typeParameters = List<TypeParameter>(dataList.length);
+      for (var i = 0; i < dataList.length; ++i) {
+        var data = dataList[i];
+        typeParameters[i] = astFactory.typeParameter(
+          _readNode(data.annotatedNode_comment),
+          _readNodeList(data.annotatedNode_metadata),
+          _declaredIdentifier(data),
+          data.typeParameter_bound != null ? _Tokens.EXTENDS : null,
+          null,
+        );
+      }
+      typeParameterList = astFactory.typeParameterList(
+        _Tokens.LT,
+        typeParameters,
+        _Tokens.GT,
+      );
     }
 
+    GenericFunctionTypeImpl node = astFactory.genericFunctionType(
+      null,
+      _Tokens.FUNCTION,
+      typeParameterList,
+      null,
+      question:
+          AstBinaryFlags.hasQuestion(data.flags) ? _Tokens.QUESTION : null,
+    );
+    node.type = _readType(data.genericFunctionType_type);
     return node;
   }
 
+  AstNode readNode(LinkedNode data) {
+    timerAstBinaryReader.start();
+    try {
+      return _readNode(data);
+    } finally {
+      timerAstBinaryReader.stop();
+    }
+  }
+
   DartType readType(LinkedNodeType data) {
     return _readType(data);
   }
 
+  SimpleIdentifier _declaredIdentifier(LinkedNode data) {
+    return astFactory.simpleIdentifier(
+      TokenFactory.tokenFromString(data.name)..offset = data.nameOffset,
+      isDeclaration: true,
+    );
+  }
+
   Element _elementOfComponents(
     int rawElementIndex,
     LinkedNodeType definingTypeNode,
@@ -62,30 +150,17 @@
     return bundleContext.elementOfIndex(index);
   }
 
-  Token _getToken(int index) {
-    return _unitContext.tokensContext.tokenOfIndex(index);
-  }
-
-  List<Token> _getTokens(List<int> indexList) {
-    var result = List<Token>(indexList.length);
-    for (var i = 0; i < indexList.length; ++i) {
-      var index = indexList[i];
-      result[i] = _getToken(index);
-    }
-    return result;
-  }
-
   AdjacentStrings _read_adjacentStrings(LinkedNode data) {
     return astFactory.adjacentStrings(
       _readNodeList(data.adjacentStrings_strings),
-    )..staticType = _readType(data.expression_type);
+    )..staticType = _stringType;
   }
 
   Annotation _read_annotation(LinkedNode data) {
     return astFactory.annotation(
-      _getToken(data.annotation_atSign),
+      _Tokens.AT,
       _readNode(data.annotation_name),
-      _getToken(data.annotation_period),
+      _Tokens.PERIOD,
       _readNode(data.annotation_constructorName),
       _readNode(data.annotation_arguments),
     )..element = _elementOfComponents(
@@ -96,47 +171,47 @@
 
   ArgumentList _read_argumentList(LinkedNode data) {
     return astFactory.argumentList(
-      _getToken(data.argumentList_leftParenthesis),
+      _Tokens.OPEN_PAREN,
       _readNodeList(data.argumentList_arguments),
-      _getToken(data.argumentList_rightParenthesis),
+      _Tokens.CLOSE_PAREN,
     );
   }
 
   AsExpression _read_asExpression(LinkedNode data) {
     return astFactory.asExpression(
       _readNode(data.asExpression_expression),
-      _getToken(data.asExpression_asOperator),
+      _Tokens.AS,
       _readNode(data.asExpression_type),
     )..staticType = _readType(data.expression_type);
   }
 
   AssertInitializer _read_assertInitializer(LinkedNode data) {
     return astFactory.assertInitializer(
-      _getToken(data.assertInitializer_assertKeyword),
-      _getToken(data.assertInitializer_leftParenthesis),
+      _Tokens.ASSERT,
+      _Tokens.OPEN_PAREN,
       _readNode(data.assertInitializer_condition),
-      _getToken(data.assertInitializer_comma),
+      _Tokens.COMMA,
       _readNode(data.assertInitializer_message),
-      _getToken(data.assertInitializer_rightParenthesis),
+      _Tokens.CLOSE_PAREN,
     );
   }
 
   AssertStatement _read_assertStatement(LinkedNode data) {
     return astFactory.assertStatement(
-      _getToken(data.assertStatement_assertKeyword),
-      _getToken(data.assertStatement_leftParenthesis),
+      _Tokens.AS,
+      _Tokens.OPEN_PAREN,
       _readNode(data.assertStatement_condition),
-      _getToken(data.assertStatement_comma),
+      _Tokens.COMMA,
       _readNode(data.assertStatement_message),
-      _getToken(data.assertStatement_rightParenthesis),
-      _getToken(data.assertStatement_semicolon),
+      _Tokens.CLOSE_PAREN,
+      _Tokens.SEMICOLON,
     );
   }
 
   AssignmentExpression _read_assignmentExpression(LinkedNode data) {
     return astFactory.assignmentExpression(
       _readNode(data.assignmentExpression_leftHandSide),
-      _getToken(data.assignmentExpression_operator),
+      _Tokens.fromType(data.assignmentExpression_operator),
       _readNode(data.assignmentExpression_rightHandSide),
     )
       ..staticElement = _elementOfComponents(
@@ -148,7 +223,7 @@
 
   AwaitExpression _read_awaitExpression(LinkedNode data) {
     return astFactory.awaitExpression(
-      _getToken(data.awaitExpression_awaitKeyword),
+      _Tokens.AWAIT,
       _readNode(data.awaitExpression_expression),
     )..staticType = _readType(data.expression_type);
   }
@@ -156,7 +231,7 @@
   BinaryExpression _read_binaryExpression(LinkedNode data) {
     return astFactory.binaryExpression(
       _readNode(data.binaryExpression_leftOperand),
-      _getToken(data.binaryExpression_operator),
+      _Tokens.fromType(data.binaryExpression_operator),
       _readNode(data.binaryExpression_rightOperand),
     )
       ..staticElement = _elementOfComponents(
@@ -168,32 +243,40 @@
 
   Block _read_block(LinkedNode data) {
     return astFactory.block(
-      _getToken(data.block_leftBracket),
+      _Tokens.OPEN_CURLY_BRACKET,
       _readNodeList(data.block_statements),
-      _getToken(data.block_rightBracket),
+      _Tokens.CLOSE_CURLY_BRACKET,
     );
   }
 
   BlockFunctionBody _read_blockFunctionBody(LinkedNode data) {
-    return astFactory.blockFunctionBody(
-      _getToken(data.blockFunctionBody_keyword),
-      _getToken(data.blockFunctionBody_star),
-      _readNode(data.blockFunctionBody_block),
-    );
+    timerAstBinaryReaderFunctionBody.start();
+    try {
+      return astFactory.blockFunctionBody(
+        _Tokens.choose(
+          AstBinaryFlags.isAsync(data.flags),
+          _Tokens.ASYNC,
+          AstBinaryFlags.isSync(data.flags),
+          _Tokens.SYNC,
+        ),
+        AstBinaryFlags.isStar(data.flags) ? _Tokens.STAR : null,
+        _readNode(data.blockFunctionBody_block),
+      );
+    } finally {
+      timerAstBinaryReaderFunctionBody.stop();
+    }
   }
 
   BooleanLiteral _read_booleanLiteral(LinkedNode data) {
-    return astFactory.booleanLiteral(
-      _getToken(data.booleanLiteral_literal),
-      data.booleanLiteral_value,
-    )..staticType = _readType(data.expression_type);
+    return AstTestFactory.booleanLiteral(data.booleanLiteral_value)
+      ..staticType = _boolType;
   }
 
   BreakStatement _read_breakStatement(LinkedNode data) {
     return astFactory.breakStatement(
-      _getToken(data.breakStatement_breakKeyword),
+      _Tokens.BREAK,
       _readNode(data.breakStatement_label),
-      _getToken(data.breakStatement_semicolon),
+      _Tokens.SEMICOLON,
     );
   }
 
@@ -205,59 +288,74 @@
   }
 
   CatchClause _read_catchClause(LinkedNode data) {
+    var exceptionType = _readNode(data.catchClause_exceptionType);
+    var exceptionParameter = _readNode(data.catchClause_exceptionParameter);
+    var stackTraceParameter = _readNode(data.catchClause_stackTraceParameter);
     return astFactory.catchClause(
-      _getToken(data.catchClause_onKeyword),
-      _readNode(data.catchClause_exceptionType),
-      _getToken(data.catchClause_catchKeyword),
-      _getToken(data.catchClause_leftParenthesis),
-      _readNode(data.catchClause_exceptionParameter),
-      _getToken(data.catchClause_comma),
-      _readNode(data.catchClause_stackTraceParameter),
-      _getToken(data.catchClause_rightParenthesis),
+      exceptionType != null ? _Tokens.ON : null,
+      exceptionType,
+      exceptionParameter != null ? _Tokens.CATCH : null,
+      exceptionParameter != null ? _Tokens.OPEN_PAREN : null,
+      exceptionParameter,
+      stackTraceParameter != null ? _Tokens.COMMA : null,
+      stackTraceParameter,
+      exceptionParameter != null ? _Tokens.CLOSE_PAREN : null,
       _readNode(data.catchClause_body),
     );
   }
 
   ClassDeclaration _read_classDeclaration(LinkedNode data) {
-    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),
-      _readNodeLazy(data.classDeclaration_extendsClause),
-      _readNodeLazy(data.classDeclaration_withClause),
-      _readNodeLazy(data.classOrMixinDeclaration_implementsClause),
-      _getToken(data.classOrMixinDeclaration_leftBracket),
-      _readNodeListLazy(data.classOrMixinDeclaration_members),
-      _getToken(data.classOrMixinDeclaration_rightBracket),
-    );
-    node.nativeClause = _readNodeLazy(data.classDeclaration_nativeClause);
-    LazyClassDeclaration.setData(node, data);
-    return node;
+    timerAstBinaryReaderClass.start();
+    try {
+      var node = astFactory.classDeclaration(
+        _readNodeLazy(data.annotatedNode_comment),
+        _readNodeListLazy(data.annotatedNode_metadata),
+        AstBinaryFlags.isAbstract(data.flags) ? _Tokens.ABSTRACT : null,
+        _Tokens.CLASS,
+        _declaredIdentifier(data),
+        _readNode(data.classOrMixinDeclaration_typeParameters),
+        _readNodeLazy(data.classDeclaration_extendsClause),
+        _readNodeLazy(data.classDeclaration_withClause),
+        _readNodeLazy(data.classOrMixinDeclaration_implementsClause),
+        _Tokens.OPEN_CURLY_BRACKET,
+        _readNodeListLazy(data.classOrMixinDeclaration_members),
+        _Tokens.CLOSE_CURLY_BRACKET,
+      );
+      node.nativeClause = _readNodeLazy(data.classDeclaration_nativeClause);
+      LazyClassDeclaration.setData(node, data);
+      return node;
+    } finally {
+      timerAstBinaryReaderClass.stop();
+    }
   }
 
   ClassTypeAlias _read_classTypeAlias(LinkedNode data) {
-    var node = astFactory.classTypeAlias(
-      _readNodeLazy(data.annotatedNode_comment),
-      _readNodeListLazy(data.annotatedNode_metadata),
-      _getToken(data.typeAlias_typedefKeyword),
-      _readNode(data.namedCompilationUnitMember_name),
-      _readNode(data.classTypeAlias_typeParameters),
-      _getToken(data.classTypeAlias_equals),
-      _getToken(data.classTypeAlias_abstractKeyword),
-      _readNodeLazy(data.classTypeAlias_superclass),
-      _readNodeLazy(data.classTypeAlias_withClause),
-      _readNodeLazy(data.classTypeAlias_implementsClause),
-      _getToken(data.typeAlias_semicolon),
-    );
-    LazyClassTypeAlias.setData(node, data);
-    return node;
+    timerAstBinaryReaderClass.start();
+    try {
+      var node = astFactory.classTypeAlias(
+        _readNodeLazy(data.annotatedNode_comment),
+        _readNodeListLazy(data.annotatedNode_metadata),
+        _Tokens.CLASS,
+        _declaredIdentifier(data),
+        _readNode(data.classTypeAlias_typeParameters),
+        _Tokens.EQ,
+        AstBinaryFlags.isAbstract(data.flags) ? _Tokens.ABSTRACT : null,
+        _readNodeLazy(data.classTypeAlias_superclass),
+        _readNodeLazy(data.classTypeAlias_withClause),
+        _readNodeLazy(data.classTypeAlias_implementsClause),
+        _Tokens.SEMICOLON,
+      );
+      LazyClassTypeAlias.setData(node, data);
+      return node;
+    } finally {
+      timerAstBinaryReaderClass.stop();
+    }
   }
 
   Comment _read_comment(LinkedNode data) {
-    var tokens = _getTokens(data.comment_tokens);
+    var tokens = data.comment_tokens
+        .map((lexeme) => TokenFactory.tokenFromString(lexeme))
+        .toList();
     switch (data.comment_type) {
       case LinkedNodeCommentType.block:
         return astFactory.endOfLineComment(
@@ -279,39 +377,39 @@
 
   CommentReference _read_commentReference(LinkedNode data) {
     return astFactory.commentReference(
-      _getToken(data.commentReference_newKeyword),
+      AstBinaryFlags.isNew(data.flags) ? _Tokens.NEW : null,
       _readNode(data.commentReference_identifier),
     );
   }
 
   CompilationUnit _read_compilationUnit(LinkedNode data) {
     return astFactory.compilationUnit2(
-        beginToken: _getToken(data.compilationUnit_beginToken),
+        beginToken: null,
         scriptTag: _readNode(data.compilationUnit_scriptTag),
         directives: _readNodeList(data.compilationUnit_directives),
         declarations: _readNodeList(data.compilationUnit_declarations),
-        endToken: _getToken(data.compilationUnit_endToken),
+        endToken: null,
         featureSet: null);
   }
 
   ConditionalExpression _read_conditionalExpression(LinkedNode data) {
     return astFactory.conditionalExpression(
       _readNode(data.conditionalExpression_condition),
-      _getToken(data.conditionalExpression_question),
+      _Tokens.QUESTION,
       _readNode(data.conditionalExpression_thenExpression),
-      _getToken(data.conditionalExpression_colon),
+      _Tokens.COLON,
       _readNode(data.conditionalExpression_elseExpression),
     )..staticType = _readType(data.expression_type);
   }
 
   Configuration _read_configuration(LinkedNode data) {
     return astFactory.configuration(
-      _getToken(data.configuration_ifKeyword),
-      _getToken(data.configuration_leftParenthesis),
+      _Tokens.IF,
+      _Tokens.OPEN_PAREN,
       _readNode(data.configuration_name),
-      _getToken(data.configuration_equalToken),
+      AstBinaryFlags.hasEqual(data.flags) ? _Tokens.EQ : null,
       _readNode(data.configuration_value),
-      _getToken(data.configuration_rightParenthesis),
+      _Tokens.CLOSE_PAREN,
       _readNode(data.configuration_uri),
     );
   }
@@ -320,14 +418,19 @@
     var node = astFactory.constructorDeclaration(
       _readNodeLazy(data.annotatedNode_comment),
       _readNodeListLazy(data.annotatedNode_metadata),
-      _getToken(data.constructorDeclaration_externalKeyword),
-      _getToken(data.constructorDeclaration_constKeyword),
-      _getToken(data.constructorDeclaration_factoryKeyword),
+      AstBinaryFlags.isExternal(data.flags) ? _Tokens.EXTERNAL : null,
+      AstBinaryFlags.isConst(data.flags) ? _Tokens.CONST : null,
+      AstBinaryFlags.isFactory(data.flags) ? _Tokens.FACTORY : null,
       _readNode(data.constructorDeclaration_returnType),
-      _getToken(data.constructorDeclaration_period),
-      _readNode(data.constructorDeclaration_name),
+      data.name.isNotEmpty ? _Tokens.PERIOD : null,
+      _declaredIdentifier(data),
       _readNodeLazy(data.constructorDeclaration_parameters),
-      _getToken(data.constructorDeclaration_separator),
+      _Tokens.choose(
+        AstBinaryFlags.hasSeparatorColon(data.flags),
+        _Tokens.COLON,
+        AstBinaryFlags.hasSeparatorEquals(data.flags),
+        _Tokens.EQ,
+      ),
       _readNodeListLazy(data.constructorDeclaration_initializers),
       _readNodeLazy(data.constructorDeclaration_redirectedConstructor),
       _readNodeLazy(data.constructorDeclaration_body),
@@ -338,11 +441,12 @@
 
   ConstructorFieldInitializer _read_constructorFieldInitializer(
       LinkedNode data) {
+    var hasThis = AstBinaryFlags.hasThis(data.flags);
     return astFactory.constructorFieldInitializer(
-      _getToken(data.constructorFieldInitializer_thisKeyword),
-      _getToken(data.constructorFieldInitializer_period),
+      hasThis ? _Tokens.THIS : null,
+      hasThis ? _Tokens.PERIOD : null,
       _readNode(data.constructorFieldInitializer_fieldName),
-      _getToken(data.constructorFieldInitializer_equals),
+      _Tokens.EQ,
       _readNode(data.constructorFieldInitializer_expression),
     );
   }
@@ -350,7 +454,7 @@
   ConstructorName _read_constructorName(LinkedNode data) {
     return astFactory.constructorName(
       _readNode(data.constructorName_type),
-      _getToken(data.constructorName_period),
+      data.constructorName_name != null ? _Tokens.PERIOD : null,
       _readNode(data.constructorName_name),
     )..staticElement = _elementOfComponents(
         data.constructorName_element,
@@ -360,9 +464,9 @@
 
   ContinueStatement _read_continueStatement(LinkedNode data) {
     return astFactory.continueStatement(
-      _getToken(data.continueStatement_continueKeyword),
+      _Tokens.CONTINUE,
       _readNode(data.continueStatement_label),
-      _getToken(data.continueStatement_semicolon),
+      _Tokens.SEMICOLON,
     );
   }
 
@@ -370,7 +474,14 @@
     return astFactory.declaredIdentifier(
       _readNode(data.annotatedNode_comment),
       _readNodeList(data.annotatedNode_metadata),
-      _getToken(data.declaredIdentifier_keyword),
+      _Tokens.choose(
+        AstBinaryFlags.isConst(data.flags),
+        _Tokens.CONST,
+        AstBinaryFlags.isFinal(data.flags),
+        _Tokens.FINAL,
+        AstBinaryFlags.isVar(data.flags),
+        _Tokens.VAR,
+      ),
       _readNode(data.declaredIdentifier_type),
       _readNode(data.declaredIdentifier_identifier),
     );
@@ -380,7 +491,7 @@
     var node = astFactory.defaultFormalParameter(
       _readNode(data.defaultFormalParameter_parameter),
       _toParameterKind(data.defaultFormalParameter_kind),
-      _getToken(data.defaultFormalParameter_separator),
+      data.defaultFormalParameter_defaultValue != null ? _Tokens.COLON : null,
       _readNodeLazy(data.defaultFormalParameter_defaultValue),
     );
     LazyFormalParameter.setData(node, data);
@@ -389,13 +500,13 @@
 
   DoStatement _read_doStatement(LinkedNode data) {
     return astFactory.doStatement(
-      _getToken(data.doStatement_doKeyword),
+      _Tokens.DO,
       _readNode(data.doStatement_body),
-      _getToken(data.doStatement_whileKeyword),
-      _getToken(data.doStatement_leftParenthesis),
+      _Tokens.WHILE,
+      _Tokens.OPEN_PAREN,
       _readNode(data.doStatement_condition),
-      _getToken(data.doStatement_rightParenthesis),
-      _getToken(data.doStatement_semicolon),
+      _Tokens.CLOSE_PAREN,
+      _Tokens.SEMICOLON,
     );
   }
 
@@ -406,21 +517,19 @@
   }
 
   DoubleLiteral _read_doubleLiteral(LinkedNode data) {
-    return astFactory.doubleLiteral(
-      _getToken(data.doubleLiteral_literal),
-      data.doubleLiteral_value,
-    )..staticType = _readType(data.expression_type);
+    return AstTestFactory.doubleLiteral(data.doubleLiteral_value)
+      ..staticType = _doubleType;
   }
 
   EmptyFunctionBody _read_emptyFunctionBody(LinkedNode data) {
     return astFactory.emptyFunctionBody(
-      _getToken(data.emptyFunctionBody_semicolon),
+      _Tokens.SEMICOLON,
     );
   }
 
   EmptyStatement _read_emptyStatement(LinkedNode data) {
     return astFactory.emptyStatement(
-      _getToken(data.emptyStatement_semicolon),
+      _Tokens.SEMICOLON,
     );
   }
 
@@ -428,7 +537,7 @@
     var node = astFactory.enumConstantDeclaration(
       _readNodeLazy(data.annotatedNode_comment),
       _readNodeListLazy(data.annotatedNode_metadata),
-      _readNode(data.enumConstantDeclaration_name),
+      _declaredIdentifier(data),
     );
     LazyEnumConstantDeclaration.setData(node, data);
     return node;
@@ -438,49 +547,64 @@
     var node = astFactory.enumDeclaration(
       _readNodeLazy(data.annotatedNode_comment),
       _readNodeListLazy(data.annotatedNode_metadata),
-      _getToken(data.enumDeclaration_enumKeyword),
-      _readNode(data.namedCompilationUnitMember_name),
-      _getToken(data.enumDeclaration_leftBracket),
+      _Tokens.ENUM,
+      _declaredIdentifier(data),
+      _Tokens.OPEN_CURLY_BRACKET,
       _readNodeListLazy(data.enumDeclaration_constants),
-      _getToken(data.enumDeclaration_rightBracket),
+      _Tokens.CLOSE_CURLY_BRACKET,
     );
     LazyEnumDeclaration.setData(node, data);
     return node;
   }
 
   ExportDirective _read_exportDirective(LinkedNode data) {
-    var node = astFactory.exportDirective(
-      _readNode(data.annotatedNode_comment),
-      _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;
+    timerAstBinaryReaderDirective.start();
+    try {
+      var node = astFactory.exportDirective(
+        _readNode(data.annotatedNode_comment),
+        _readNodeListLazy(data.annotatedNode_metadata),
+        _Tokens.EXPORT,
+        _readNode(data.uriBasedDirective_uri),
+        _readNodeList(data.namespaceDirective_configurations),
+        _readNodeList(data.namespaceDirective_combinators),
+        _Tokens.SEMICOLON,
+      );
+      LazyDirective.setData(node, data);
+      return node;
+    } finally {
+      timerAstBinaryReaderDirective.stop();
+    }
   }
 
   ExpressionFunctionBody _read_expressionFunctionBody(LinkedNode data) {
-    return astFactory.expressionFunctionBody(
-      _getToken(data.expressionFunctionBody_keyword),
-      _getToken(data.expressionFunctionBody_arrow),
-      _readNode(data.expressionFunctionBody_expression),
-      _getToken(data.expressionFunctionBody_semicolon),
-    );
+    timerAstBinaryReaderFunctionBody.start();
+    try {
+      return astFactory.expressionFunctionBody(
+        _Tokens.choose(
+          AstBinaryFlags.isAsync(data.flags),
+          _Tokens.ASYNC,
+          AstBinaryFlags.isSync(data.flags),
+          _Tokens.SYNC,
+        ),
+        _Tokens.ARROW,
+        _readNode(data.expressionFunctionBody_expression),
+        _Tokens.SEMICOLON,
+      );
+    } finally {
+      timerAstBinaryReaderFunctionBody.stop();
+    }
   }
 
   ExpressionStatement _read_expressionStatement(LinkedNode data) {
     return astFactory.expressionStatement(
       _readNode(data.expressionStatement_expression),
-      _getToken(data.expressionStatement_semicolon),
+      _Tokens.SEMICOLON,
     );
   }
 
   ExtendsClause _read_extendsClause(LinkedNode data) {
     return astFactory.extendsClause(
-      _getToken(data.extendsClause_extendsKeyword),
+      _Tokens.EXTENDS,
       _readNode(data.extendsClause_superclass),
     );
   }
@@ -488,11 +612,13 @@
   FieldDeclaration _read_fieldDeclaration(LinkedNode data) {
     var node = astFactory.fieldDeclaration2(
       comment: _readNodeLazy(data.annotatedNode_comment),
-      covariantKeyword: _getToken(data.fieldDeclaration_covariantKeyword),
+      covariantKeyword:
+          AstBinaryFlags.isCovariant(data.flags) ? _Tokens.COVARIANT : null,
       fieldList: _readNode(data.fieldDeclaration_fields),
       metadata: _readNodeListLazy(data.annotatedNode_metadata),
-      semicolon: _getToken(data.fieldDeclaration_semicolon),
-      staticKeyword: _getToken(data.fieldDeclaration_staticKeyword),
+      semicolon: _Tokens.SEMICOLON,
+      staticKeyword:
+          AstBinaryFlags.isStatic(data.flags) ? _Tokens.STATIC : null,
     );
     LazyFieldDeclaration.setData(node, data);
     return node;
@@ -500,17 +626,26 @@
 
   FieldFormalParameter _read_fieldFormalParameter(LinkedNode data) {
     var node = astFactory.fieldFormalParameter2(
-      identifier: _readNode(data.normalFormalParameter_identifier),
-      period: _getToken(data.fieldFormalParameter_period),
-      thisKeyword: _getToken(data.fieldFormalParameter_thisKeyword),
-      covariantKeyword: _getToken(data.normalFormalParameter_covariantKeyword),
+      identifier: _declaredIdentifier(data),
+      period: _Tokens.PERIOD,
+      thisKeyword: _Tokens.THIS,
+      covariantKeyword:
+          AstBinaryFlags.isCovariant(data.flags) ? _Tokens.COVARIANT : null,
       typeParameters: _readNode(data.fieldFormalParameter_typeParameters),
-      keyword: _getToken(data.fieldFormalParameter_keyword),
+      keyword: _Tokens.choose(
+        AstBinaryFlags.isConst(data.flags),
+        _Tokens.CONST,
+        AstBinaryFlags.isFinal(data.flags),
+        _Tokens.FINAL,
+        AstBinaryFlags.isVar(data.flags),
+        _Tokens.VAR,
+      ),
       metadata: _readNodeList(data.normalFormalParameter_metadata),
       comment: _readNode(data.normalFormalParameter_comment),
       type: _readNode(data.fieldFormalParameter_type),
       parameters: _readNode(data.fieldFormalParameter_formalParameters),
-      requiredKeyword: _getToken(data.normalFormalParameter_requiredKeyword),
+      requiredKeyword:
+          AstBinaryFlags.isRequired(data.flags) ? _Tokens.REQUIRED : null,
     );
     LazyFormalParameter.setData(node, data);
     return node;
@@ -519,7 +654,7 @@
   ForEachPartsWithDeclaration _read_forEachPartsWithDeclaration(
       LinkedNode data) {
     return astFactory.forEachPartsWithDeclaration(
-      inKeyword: _getToken(data.forEachParts_inKeyword),
+      inKeyword: _Tokens.IN,
       iterable: _readNode(data.forEachParts_iterable),
       loopVariable: _readNode(data.forEachPartsWithDeclaration_loopVariable),
     );
@@ -527,7 +662,7 @@
 
   ForEachPartsWithIdentifier _read_forEachPartsWithIdentifier(LinkedNode data) {
     return astFactory.forEachPartsWithIdentifier(
-      inKeyword: _getToken(data.forEachParts_inKeyword),
+      inKeyword: _Tokens.IN,
       iterable: _readNode(data.forEachParts_iterable),
       identifier: _readNode(data.forEachPartsWithIdentifier_identifier),
     );
@@ -535,30 +670,40 @@
 
   ForElement _read_forElement(LinkedNode data) {
     return astFactory.forElement(
-      awaitKeyword: _getToken(data.forMixin_awaitKeyword),
+      awaitKeyword: AstBinaryFlags.hasAwait(data.flags) ? _Tokens.AWAIT : null,
       body: _readNode(data.forElement_body),
-      forKeyword: _getToken(data.forMixin_forKeyword),
+      forKeyword: _Tokens.FOR,
       forLoopParts: _readNode(data.forMixin_forLoopParts),
-      leftParenthesis: _getToken(data.forMixin_leftParenthesis),
-      rightParenthesis: _getToken(data.forMixin_rightParenthesis),
+      leftParenthesis: _Tokens.OPEN_PAREN,
+      rightParenthesis: _Tokens.CLOSE_PAREN,
     );
   }
 
   FormalParameterList _read_formalParameterList(LinkedNode data) {
     return astFactory.formalParameterList(
-      _getToken(data.formalParameterList_leftParenthesis),
+      _Tokens.OPEN_PAREN,
       _readNodeList(data.formalParameterList_parameters),
-      _getToken(data.formalParameterList_leftDelimiter),
-      _getToken(data.formalParameterList_rightDelimiter),
-      _getToken(data.formalParameterList_rightParenthesis),
+      _Tokens.choose(
+        AstBinaryFlags.isDelimiterCurly(data.flags),
+        _Tokens.OPEN_CURLY_BRACKET,
+        AstBinaryFlags.isDelimiterSquare(data.flags),
+        _Tokens.OPEN_SQUARE_BRACKET,
+      ),
+      _Tokens.choose(
+        AstBinaryFlags.isDelimiterCurly(data.flags),
+        _Tokens.CLOSE_CURLY_BRACKET,
+        AstBinaryFlags.isDelimiterSquare(data.flags),
+        _Tokens.CLOSE_SQUARE_BRACKET,
+      ),
+      _Tokens.CLOSE_PAREN,
     );
   }
 
   ForPartsWithDeclarations _read_forPartsWithDeclarations(LinkedNode data) {
     return astFactory.forPartsWithDeclarations(
       condition: _readNode(data.forParts_condition),
-      leftSeparator: _getToken(data.forParts_leftSeparator),
-      rightSeparator: _getToken(data.forParts_rightSeparator),
+      leftSeparator: _Tokens.SEMICOLON,
+      rightSeparator: _Tokens.SEMICOLON,
       updaters: _readNodeList(data.forParts_updaters),
       variables: _readNode(data.forPartsWithDeclarations_variables),
     );
@@ -568,35 +713,45 @@
     return astFactory.forPartsWithExpression(
       condition: _readNode(data.forParts_condition),
       initialization: _readNode(data.forPartsWithExpression_initialization),
-      leftSeparator: _getToken(data.forParts_leftSeparator),
-      rightSeparator: _getToken(data.forParts_rightSeparator),
+      leftSeparator: _Tokens.SEMICOLON,
+      rightSeparator: _Tokens.SEMICOLON,
       updaters: _readNodeList(data.forParts_updaters),
     );
   }
 
   ForStatement _read_forStatement(LinkedNode data) {
     return astFactory.forStatement(
-      awaitKeyword: _getToken(data.forMixin_awaitKeyword),
-      forKeyword: _getToken(data.forMixin_forKeyword),
-      leftParenthesis: _getToken(data.forMixin_leftParenthesis),
+      awaitKeyword: AstBinaryFlags.hasAwait(data.flags) ? _Tokens.AWAIT : null,
+      forKeyword: _Tokens.FOR,
+      leftParenthesis: _Tokens.OPEN_PAREN,
       forLoopParts: _readNode(data.forMixin_forLoopParts),
-      rightParenthesis: _getToken(data.forMixin_rightParenthesis),
+      rightParenthesis: _Tokens.CLOSE_PAREN,
       body: _readNode(data.forStatement_body),
     );
   }
 
   FunctionDeclaration _read_functionDeclaration(LinkedNode data) {
-    var node = astFactory.functionDeclaration(
-      _readNodeLazy(data.annotatedNode_comment),
-      _readNodeListLazy(data.annotatedNode_metadata),
-      _getToken(data.functionDeclaration_externalKeyword),
-      _readNodeLazy(data.functionDeclaration_returnType),
-      _getToken(data.functionDeclaration_propertyKeyword),
-      _readNode(data.namedCompilationUnitMember_name),
-      _readNodeLazy(data.functionDeclaration_functionExpression),
-    );
-    LazyFunctionDeclaration.setData(node, data);
-    return node;
+    timerAstBinaryReaderFunctionDeclaration.start();
+    try {
+      var node = astFactory.functionDeclaration(
+        _readNodeLazy(data.annotatedNode_comment),
+        _readNodeListLazy(data.annotatedNode_metadata),
+        AstBinaryFlags.isExternal(data.flags) ? _Tokens.EXTERNAL : null,
+        _readNodeLazy(data.functionDeclaration_returnType),
+        _Tokens.choose(
+          AstBinaryFlags.isGet(data.flags),
+          _Tokens.GET,
+          AstBinaryFlags.isSet(data.flags),
+          _Tokens.SET,
+        ),
+        _declaredIdentifier(data),
+        _readNodeLazy(data.functionDeclaration_functionExpression),
+      );
+      LazyFunctionDeclaration.setData(node, data);
+      return node;
+    } finally {
+      timerAstBinaryReaderFunctionDeclaration.stop();
+    }
   }
 
   FunctionDeclarationStatement _read_functionDeclarationStatement(
@@ -629,12 +784,12 @@
     var node = astFactory.functionTypeAlias(
       _readNodeLazy(data.annotatedNode_comment),
       _readNodeListLazy(data.annotatedNode_metadata),
-      _getToken(data.typeAlias_typedefKeyword),
+      _Tokens.TYPEDEF,
       _readNodeLazy(data.functionTypeAlias_returnType),
-      _readNode(data.namedCompilationUnitMember_name),
+      _declaredIdentifier(data),
       _readNode(data.functionTypeAlias_typeParameters),
       _readNodeLazy(data.functionTypeAlias_formalParameters),
-      _getToken(data.typeAlias_semicolon),
+      _Tokens.SEMICOLON,
     );
     LazyFunctionTypeAlias.setData(node, data);
     LazyFunctionTypeAlias.setHasSelfReference(
@@ -648,13 +803,15 @@
       LinkedNode data) {
     var node = astFactory.functionTypedFormalParameter2(
       comment: _readNodeLazy(data.normalFormalParameter_comment),
-      covariantKeyword: _getToken(data.normalFormalParameter_covariantKeyword),
-      identifier: _readNode(data.normalFormalParameter_identifier),
+      covariantKeyword:
+          AstBinaryFlags.isCovariant(data.flags) ? _Tokens.COVARIANT : null,
+      identifier: _declaredIdentifier(data),
       metadata: _readNodeListLazy(data.normalFormalParameter_metadata),
       parameters: _readNodeLazy(
         data.functionTypedFormalParameter_formalParameters,
       ),
-      requiredKeyword: _getToken(data.normalFormalParameter_requiredKeyword),
+      requiredKeyword:
+          AstBinaryFlags.isRequired(data.flags) ? _Tokens.REQUIRED : null,
       returnType: _readNodeLazy(data.functionTypedFormalParameter_returnType),
       typeParameters: _readNode(
         data.functionTypedFormalParameter_typeParameters,
@@ -665,29 +822,20 @@
   }
 
   GenericFunctionType _read_genericFunctionType(LinkedNode data) {
-    GenericFunctionTypeImpl node = astFactory.genericFunctionType(
-      _readNodeLazy(data.genericFunctionType_returnType),
-      _getToken(data.genericFunctionType_functionKeyword),
-      _readNode(data.genericFunctionType_typeParameters),
-      _readNodeLazy(data.genericFunctionType_formalParameters),
-      question: _getToken(data.genericFunctionType_question),
-    );
-    node.type = _readType(data.genericFunctionType_type);
-    LazyGenericFunctionType.setData(node, data);
-    _unitContext.addGenericFunctionType(data.genericFunctionType_id, node);
-    return node;
+    var id = data.genericFunctionType_id;
+    return _unitContext.getGenericFunctionType(id);
   }
 
   GenericTypeAlias _read_genericTypeAlias(LinkedNode data) {
     var node = astFactory.genericTypeAlias(
       _readNodeLazy(data.annotatedNode_comment),
       _readNodeListLazy(data.annotatedNode_metadata),
-      _getToken(data.typeAlias_typedefKeyword),
-      _readNode(data.namedCompilationUnitMember_name),
+      _Tokens.TYPEDEF,
+      _declaredIdentifier(data),
       _readNode(data.genericTypeAlias_typeParameters),
-      _getToken(data.genericTypeAlias_equals),
+      _Tokens.EQ,
       _readNodeLazy(data.genericTypeAlias_functionType),
-      _getToken(data.typeAlias_semicolon),
+      _Tokens.SEMICOLON,
     );
     LazyGenericTypeAlias.setData(node, data);
     LazyGenericTypeAlias.setHasSelfReference(
@@ -699,67 +847,83 @@
 
   HideCombinator _read_hideCombinator(LinkedNode data) {
     return astFactory.hideCombinator(
-      _getToken(data.combinator_keyword),
-      _readNodeList(data.hideCombinator_hiddenNames),
+      _Tokens.HIDE,
+      data.names.map((name) => AstTestFactory.identifier3(name)).toList(),
     );
   }
 
   IfElement _read_ifElement(LinkedNode data) {
+    var elseElement = _readNode(data.ifElement_elseElement);
     return astFactory.ifElement(
       condition: _readNode(data.ifMixin_condition),
-      elseElement: _readNode(data.ifElement_elseElement),
-      elseKeyword: _getToken(data.ifMixin_elseKeyword),
-      ifKeyword: _getToken(data.ifMixin_ifKeyword),
-      leftParenthesis: _getToken(data.ifMixin_leftParenthesis),
-      rightParenthesis: _getToken(data.ifMixin_rightParenthesis),
+      elseElement: elseElement,
+      elseKeyword: elseElement != null ? _Tokens.ELSE : null,
+      ifKeyword: _Tokens.IF,
+      leftParenthesis: _Tokens.OPEN_PAREN,
+      rightParenthesis: _Tokens.CLOSE_PAREN,
       thenElement: _readNode(data.ifElement_thenElement),
     );
   }
 
   IfStatement _read_ifStatement(LinkedNode data) {
+    var elseStatement = _readNode(data.ifStatement_elseStatement);
     return astFactory.ifStatement(
-      _getToken(data.ifMixin_ifKeyword),
-      _getToken(data.ifMixin_leftParenthesis),
+      _Tokens.IF,
+      _Tokens.OPEN_PAREN,
       _readNode(data.ifMixin_condition),
-      _getToken(data.ifMixin_rightParenthesis),
+      _Tokens.CLOSE_PAREN,
       _readNode(data.ifStatement_thenStatement),
-      _getToken(data.ifMixin_elseKeyword),
-      _readNode(data.ifStatement_elseStatement),
+      elseStatement != null ? _Tokens.ELSE : null,
+      elseStatement,
     );
   }
 
   ImplementsClause _read_implementsClause(LinkedNode data) {
     return astFactory.implementsClause(
-      _getToken(data.implementsClause_implementsKeyword),
+      _Tokens.IMPLEMENTS,
       _readNodeList(data.implementsClause_interfaces),
     );
   }
 
   ImportDirective _read_importDirective(LinkedNode data) {
-    var node = astFactory.importDirective(
-      _readNode(data.annotatedNode_comment),
-      _readNodeListLazy(data.annotatedNode_metadata),
-      _getToken(data.directive_keyword),
-      _readNode(data.uriBasedDirective_uri),
-      _readNodeList(data.namespaceDirective_configurations),
-      _getToken(data.importDirective_deferredKeyword),
-      _getToken(data.importDirective_asKeyword),
-      _readNode(data.importDirective_prefix),
-      _readNodeList(data.namespaceDirective_combinators),
-      _getToken(data.directive_semicolon),
-    );
-    LazyDirective.setData(node, data);
-    return node;
+    timerAstBinaryReaderDirective.start();
+    try {
+      SimpleIdentifier prefix;
+      if (data.importDirective_prefix.isNotEmpty) {
+        prefix = astFactory.simpleIdentifier(
+          TokenFactory.tokenFromString(data.importDirective_prefix)
+            ..offset = data.importDirective_prefixOffset,
+        );
+      }
+
+      var node = astFactory.importDirective(
+        _readNode(data.annotatedNode_comment),
+        _readNodeListLazy(data.annotatedNode_metadata),
+        _Tokens.IMPORT,
+        _readNode(data.uriBasedDirective_uri),
+        _readNodeList(data.namespaceDirective_configurations),
+        AstBinaryFlags.isDeferred(data.flags) ? _Tokens.DEFERRED : null,
+        _Tokens.AS,
+        prefix,
+        _readNodeList(data.namespaceDirective_combinators),
+        _Tokens.SEMICOLON,
+      );
+      LazyDirective.setData(node, data);
+      return node;
+    } finally {
+      timerAstBinaryReaderDirective.stop();
+    }
   }
 
   IndexExpression _read_indexExpression(LinkedNode data) {
     return astFactory.indexExpressionForTarget(
       _readNode(data.indexExpression_target),
-      _getToken(data.indexExpression_leftBracket),
+      _Tokens.OPEN_SQUARE_BRACKET,
       _readNode(data.indexExpression_index),
-      _getToken(data.indexExpression_rightBracket),
+      _Tokens.CLOSE_SQUARE_BRACKET,
     )
-      ..period = _getToken(data.indexExpression_period)
+      ..period =
+          AstBinaryFlags.hasPeriod(data.flags) ? _Tokens.PERIOD_PERIOD : null
       ..staticElement = _elementOfComponents(
         data.indexExpression_element,
         data.indexExpression_elementType,
@@ -769,9 +933,20 @@
 
   InstanceCreationExpression _read_instanceCreationExpression(LinkedNode data) {
     var node = astFactory.instanceCreationExpression(
-      _getToken(data.instanceCreationExpression_keyword),
+      _Tokens.choose(
+        AstBinaryFlags.isConst(data.flags),
+        _Tokens.CONST,
+        AstBinaryFlags.isNew(data.flags),
+        _Tokens.NEW,
+      ),
       _readNode(data.instanceCreationExpression_constructorName),
-      _readNode(data.instanceCreationExpression_arguments),
+      astFactory.argumentList(
+        _Tokens.OPEN_PAREN,
+        _readNodeList(
+          data.instanceCreationExpression_arguments,
+        ),
+        _Tokens.CLOSE_PAREN,
+      ),
       typeArguments: _readNode(data.instanceCreationExpression_typeArguments),
     );
     node.staticElement = node.constructorName.staticElement;
@@ -780,23 +955,25 @@
   }
 
   IntegerLiteral _read_integerLiteral(LinkedNode data) {
-    return astFactory.integerLiteral(
-      _getToken(data.integerLiteral_literal),
-      data.integerLiteral_value,
-    )..staticType = _readType(data.expression_type);
+    return AstTestFactory.integer(data.integerLiteral_value)
+      ..staticType = _intType;
   }
 
   InterpolationExpression _read_interpolationExpression(LinkedNode data) {
+    var isIdentifier =
+        AstBinaryFlags.isStringInterpolationIdentifier(data.flags);
     return astFactory.interpolationExpression(
-      _getToken(data.interpolationExpression_leftBracket),
+      isIdentifier
+          ? _Tokens.OPEN_CURLY_BRACKET
+          : _Tokens.STRING_INTERPOLATION_EXPRESSION,
       _readNode(data.interpolationExpression_expression),
-      _getToken(data.interpolationExpression_rightBracket),
+      isIdentifier ? null : _Tokens.CLOSE_CURLY_BRACKET,
     );
   }
 
   InterpolationString _read_interpolationString(LinkedNode data) {
     return astFactory.interpolationString(
-      _getToken(data.interpolationString_token),
+      TokenFactory.tokenFromString(data.interpolationString_value),
       data.interpolationString_value,
     );
   }
@@ -804,16 +981,16 @@
   IsExpression _read_isExpression(LinkedNode data) {
     return astFactory.isExpression(
       _readNode(data.isExpression_expression),
-      _getToken(data.isExpression_isOperator),
-      _getToken(data.isExpression_notOperator),
+      _Tokens.IS,
+      AstBinaryFlags.hasNot(data.flags) ? _Tokens.BANG : null,
       _readNode(data.isExpression_type),
-    )..staticType = _readType(data.expression_type);
+    )..staticType = _boolType;
   }
 
   Label _read_label(LinkedNode data) {
     return astFactory.label(
       _readNode(data.label_label),
-      _getToken(data.label_colon),
+      _Tokens.COLON,
     );
   }
 
@@ -825,15 +1002,20 @@
   }
 
   LibraryDirective _read_libraryDirective(LinkedNode data) {
-    var node = astFactory.libraryDirective(
-      _readNode(data.annotatedNode_comment),
-      _readNodeListLazy(data.annotatedNode_metadata),
-      _getToken(data.directive_keyword),
-      _readNode(data.libraryDirective_name),
-      _getToken(data.directive_semicolon),
-    );
-    LazyDirective.setData(node, data);
-    return node;
+    timerAstBinaryReaderDirective.start();
+    try {
+      var node = astFactory.libraryDirective(
+        _readNode(data.annotatedNode_comment),
+        _readNodeListLazy(data.annotatedNode_metadata),
+        _Tokens.LIBRARY,
+        _readNode(data.libraryDirective_name),
+        _Tokens.SEMICOLON,
+      );
+      LazyDirective.setData(node, data);
+      return node;
+    } finally {
+      timerAstBinaryReaderDirective.stop();
+    }
   }
 
   LibraryIdentifier _read_libraryIdentifier(LinkedNode data) {
@@ -844,18 +1026,24 @@
 
   ListLiteral _read_listLiteral(LinkedNode data) {
     return astFactory.listLiteral(
-      _getToken(data.typedLiteral_constKeyword),
-      _readNode(data.typedLiteral_typeArguments),
-      _getToken(data.listLiteral_leftBracket),
+      AstBinaryFlags.isConst(data.flags) ? _Tokens.CONST : null,
+      AstBinaryFlags.hasTypeArguments(data.flags)
+          ? astFactory.typeArgumentList(
+              _Tokens.LT,
+              _readNodeList(data.typedLiteral_typeArguments),
+              _Tokens.GT,
+            )
+          : null,
+      _Tokens.OPEN_SQUARE_BRACKET,
       _readNodeList(data.listLiteral_elements),
-      _getToken(data.listLiteral_rightBracket),
+      _Tokens.CLOSE_SQUARE_BRACKET,
     )..staticType = _readType(data.expression_type);
   }
 
   MapLiteralEntry _read_mapLiteralEntry(LinkedNode data) {
     return astFactory.mapLiteralEntry(
       _readNode(data.mapLiteralEntry_key),
-      _getToken(data.mapLiteralEntry_separator),
+      _Tokens.COLON,
       _readNode(data.mapLiteralEntry_value),
     );
   }
@@ -864,15 +1052,22 @@
     var node = astFactory.methodDeclaration(
       _readNodeLazy(data.annotatedNode_comment),
       _readNodeListLazy(data.annotatedNode_metadata),
-      _getToken(data.methodDeclaration_externalKeyword),
-      _getToken(data.methodDeclaration_modifierKeyword),
+      AstBinaryFlags.isExternal(data.flags) ? _Tokens.EXTERNAL : null,
+      AstBinaryFlags.isStatic(data.flags) ? _Tokens.STATIC : null,
       _readNodeLazy(data.methodDeclaration_returnType),
-      _getToken(data.methodDeclaration_propertyKeyword),
-      _getToken(data.methodDeclaration_operatorKeyword),
-      _readNode(data.methodDeclaration_name),
+      _Tokens.choose(
+        AstBinaryFlags.isGet(data.flags),
+        _Tokens.GET,
+        AstBinaryFlags.isSet(data.flags),
+        _Tokens.SET,
+      ),
+      AstBinaryFlags.isOperator(data.flags) ? _Tokens.OPERATOR : null,
+      _declaredIdentifier(data),
       _readNode(data.methodDeclaration_typeParameters),
       _readNodeLazy(data.methodDeclaration_formalParameters),
-      _readNodeLazy(data.methodDeclaration_body),
+      AstBinaryFlags.isAbstract(data.flags)
+          ? AstTestFactory.emptyFunctionBody()
+          : AstTestFactory.blockFunctionBody(AstTestFactory.block()),
     );
     LazyMethodDeclaration.setData(node, data);
     return node;
@@ -881,7 +1076,12 @@
   MethodInvocation _read_methodInvocation(LinkedNode data) {
     return astFactory.methodInvocation(
       _readNode(data.methodInvocation_target),
-      _getToken(data.methodInvocation_operator),
+      _Tokens.choose(
+        AstBinaryFlags.hasPeriod(data.flags),
+        _Tokens.PERIOD,
+        AstBinaryFlags.hasPeriod2(data.flags),
+        _Tokens.PERIOD_PERIOD,
+      ),
       _readNode(data.methodInvocation_methodName),
       _readNode(data.invocationExpression_typeArguments),
       _readNode(data.invocationExpression_arguments),
@@ -889,95 +1089,111 @@
   }
 
   MixinDeclaration _read_mixinDeclaration(LinkedNode data) {
-    var node = astFactory.mixinDeclaration(
-      _readNodeLazy(data.annotatedNode_comment),
-      _readNodeListLazy(data.annotatedNode_metadata),
-      _getToken(data.mixinDeclaration_mixinKeyword),
-      _readNode(data.namedCompilationUnitMember_name),
-      _readNode(data.classOrMixinDeclaration_typeParameters),
-      _readNodeLazy(data.mixinDeclaration_onClause),
-      _readNodeLazy(data.classOrMixinDeclaration_implementsClause),
-      _getToken(data.classOrMixinDeclaration_leftBracket),
-      _readNodeListLazy(data.classOrMixinDeclaration_members),
-      _getToken(data.classOrMixinDeclaration_rightBracket),
-    );
-    LazyMixinDeclaration(node, data);
-    return node;
+    timerAstBinaryReaderMixin.start();
+    try {
+      var node = astFactory.mixinDeclaration(
+        _readNodeLazy(data.annotatedNode_comment),
+        _readNodeListLazy(data.annotatedNode_metadata),
+        _Tokens.MIXIN,
+        _declaredIdentifier(data),
+        _readNode(data.classOrMixinDeclaration_typeParameters),
+        _readNodeLazy(data.mixinDeclaration_onClause),
+        _readNodeLazy(data.classOrMixinDeclaration_implementsClause),
+        _Tokens.OPEN_CURLY_BRACKET,
+        _readNodeListLazy(data.classOrMixinDeclaration_members),
+        _Tokens.CLOSE_CURLY_BRACKET,
+      );
+      LazyMixinDeclaration(node, data);
+      return node;
+    } finally {
+      timerAstBinaryReaderMixin.stop();
+    }
   }
 
   NamedExpression _read_namedExpression(LinkedNode data) {
+    Expression expression = _readNode(data.namedExpression_expression);
     return astFactory.namedExpression(
       _readNode(data.namedExpression_name),
-      _readNode(data.namedExpression_expression),
-    )..staticType = _readType(data.expression_type);
+      expression,
+    )..staticType = expression.staticType;
   }
 
   NativeClause _read_nativeClause(LinkedNode data) {
     return astFactory.nativeClause(
-      _getToken(data.nativeClause_nativeKeyword),
+      _Tokens.NATIVE,
       _readNode(data.nativeClause_name),
     );
   }
 
   NativeFunctionBody _read_nativeFunctionBody(LinkedNode data) {
     return astFactory.nativeFunctionBody(
-      _getToken(data.nativeFunctionBody_nativeKeyword),
+      _Tokens.NATIVE,
       _readNode(data.nativeFunctionBody_stringLiteral),
-      _getToken(data.nativeFunctionBody_semicolon),
+      _Tokens.SEMICOLON,
     );
   }
 
   NullLiteral _read_nullLiteral(LinkedNode data) {
     return astFactory.nullLiteral(
-      _getToken(data.nullLiteral_literal),
-    )..staticType = _readType(data.expression_type);
+      _Tokens.NULL,
+    )..staticType = _nullType;
   }
 
   OnClause _read_onClause(LinkedNode data) {
     return astFactory.onClause(
-      _getToken(data.onClause_onKeyword),
+      _Tokens.ON,
       _readNodeList(data.onClause_superclassConstraints),
     );
   }
 
   ParenthesizedExpression _read_parenthesizedExpression(LinkedNode data) {
     return astFactory.parenthesizedExpression(
-      _getToken(data.parenthesizedExpression_leftParenthesis),
+      _Tokens.OPEN_PAREN,
       _readNode(data.parenthesizedExpression_expression),
-      _getToken(data.parenthesizedExpression_rightParenthesis),
+      _Tokens.CLOSE_PAREN,
     )..staticType = _readType(data.expression_type);
   }
 
   PartDirective _read_partDirective(LinkedNode data) {
-    var node = astFactory.partDirective(
-      _readNode(data.annotatedNode_comment),
-      _readNodeListLazy(data.annotatedNode_metadata),
-      _getToken(data.directive_keyword),
-      _readNode(data.uriBasedDirective_uri),
-      _getToken(data.directive_semicolon),
-    );
-    LazyDirective.setData(node, data);
-    return node;
+    timerAstBinaryReaderDirective.start();
+    try {
+      var node = astFactory.partDirective(
+        _readNode(data.annotatedNode_comment),
+        _readNodeListLazy(data.annotatedNode_metadata),
+        _Tokens.PART,
+        _readNode(data.uriBasedDirective_uri),
+        _Tokens.SEMICOLON,
+      );
+      LazyDirective.setData(node, data);
+      return node;
+    } finally {
+      timerAstBinaryReaderDirective.stop();
+    }
   }
 
   PartOfDirective _read_partOfDirective(LinkedNode data) {
-    var node = astFactory.partOfDirective(
-      _readNode(data.annotatedNode_comment),
-      _readNodeListLazy(data.annotatedNode_metadata),
-      _getToken(data.directive_keyword),
-      _getToken(data.partOfDirective_ofKeyword),
-      _readNode(data.partOfDirective_uri),
-      _readNode(data.partOfDirective_libraryName),
-      _getToken(data.directive_semicolon),
-    );
-    LazyDirective.setData(node, data);
-    return node;
+    timerAstBinaryReaderDirective.start();
+    try {
+      var node = astFactory.partOfDirective(
+        _readNode(data.annotatedNode_comment),
+        _readNodeListLazy(data.annotatedNode_metadata),
+        _Tokens.PART,
+        _Tokens.OF,
+        _readNode(data.partOfDirective_uri),
+        _readNode(data.partOfDirective_libraryName),
+        _Tokens.SEMICOLON,
+      );
+      LazyDirective.setData(node, data);
+      return node;
+    } finally {
+      timerAstBinaryReaderDirective.stop();
+    }
   }
 
   PostfixExpression _read_postfixExpression(LinkedNode data) {
     return astFactory.postfixExpression(
       _readNode(data.postfixExpression_operand),
-      _getToken(data.postfixExpression_operator),
+      _Tokens.fromType(data.postfixExpression_operator),
     )
       ..staticElement = _elementOfComponents(
         data.postfixExpression_element,
@@ -989,14 +1205,14 @@
   PrefixedIdentifier _read_prefixedIdentifier(LinkedNode data) {
     return astFactory.prefixedIdentifier(
       _readNode(data.prefixedIdentifier_prefix),
-      _getToken(data.prefixedIdentifier_period),
+      _Tokens.PERIOD,
       _readNode(data.prefixedIdentifier_identifier),
     )..staticType = _readType(data.expression_type);
   }
 
   PrefixExpression _read_prefixExpression(LinkedNode data) {
     return astFactory.prefixExpression(
-      _getToken(data.prefixExpression_operator),
+      _Tokens.fromType(data.prefixExpression_operator),
       _readNode(data.prefixExpression_operand),
     )
       ..staticElement = _elementOfComponents(
@@ -1009,16 +1225,17 @@
   PropertyAccess _read_propertyAccess(LinkedNode data) {
     return astFactory.propertyAccess(
       _readNode(data.propertyAccess_target),
-      _getToken(data.propertyAccess_operator),
+      _Tokens.fromType(data.propertyAccess_operator),
       _readNode(data.propertyAccess_propertyName),
     )..staticType = _readType(data.expression_type);
   }
 
   RedirectingConstructorInvocation _read_redirectingConstructorInvocation(
       LinkedNode data) {
+    var hasThis = AstBinaryFlags.hasThis(data.flags);
     return astFactory.redirectingConstructorInvocation(
-      _getToken(data.redirectingConstructorInvocation_thisKeyword),
-      _getToken(data.redirectingConstructorInvocation_period),
+      hasThis ? _Tokens.THIS : null,
+      hasThis ? _Tokens.PERIOD : null,
       _readNode(data.redirectingConstructorInvocation_constructorName),
       _readNode(data.redirectingConstructorInvocation_arguments),
     )..staticElement = _elementOfComponents(
@@ -1029,35 +1246,35 @@
 
   RethrowExpression _read_rethrowExpression(LinkedNode data) {
     return astFactory.rethrowExpression(
-      _getToken(data.rethrowExpression_rethrowKeyword),
+      _Tokens.RETHROW,
     )..staticType = _readType(data.expression_type);
   }
 
   ReturnStatement _read_returnStatement(LinkedNode data) {
     return astFactory.returnStatement(
-      _getToken(data.returnStatement_returnKeyword),
+      _Tokens.RETURN,
       _readNode(data.returnStatement_expression),
-      _getToken(data.returnStatement_semicolon),
-    );
-  }
-
-  ScriptTag _read_scriptTag(LinkedNode data) {
-    return astFactory.scriptTag(
-      _getToken(data.scriptTag_scriptTag),
+      _Tokens.SEMICOLON,
     );
   }
 
   SetOrMapLiteral _read_setOrMapLiteral(LinkedNode data) {
     SetOrMapLiteralImpl node = astFactory.setOrMapLiteral(
-      constKeyword: _getToken(data.typedLiteral_constKeyword),
+      constKeyword: AstBinaryFlags.isConst(data.flags) ? _Tokens.CONST : null,
       elements: _readNodeList(data.setOrMapLiteral_elements),
-      leftBracket: _getToken(data.setOrMapLiteral_leftBracket),
-      typeArguments: _readNode(data.typedLiteral_typeArguments),
-      rightBracket: _getToken(data.setOrMapLiteral_rightBracket),
+      leftBracket: _Tokens.OPEN_CURLY_BRACKET,
+      typeArguments: AstBinaryFlags.hasTypeArguments(data.flags)
+          ? astFactory.typeArgumentList(
+              _Tokens.LT,
+              _readNodeList(data.typedLiteral_typeArguments),
+              _Tokens.GT,
+            )
+          : null,
+      rightBracket: _Tokens.CLOSE_CURLY_BRACKET,
     )..staticType = _readType(data.expression_type);
-    if (data.setOrMapLiteral_isMap) {
+    if (AstBinaryFlags.isMap(data.flags)) {
       node.becomeMap();
-    } else if (data.setOrMapLiteral_isSet) {
+    } else if (AstBinaryFlags.isSet(data.flags)) {
       node.becomeSet();
     }
     return node;
@@ -1065,20 +1282,29 @@
 
   ShowCombinator _read_showCombinator(LinkedNode data) {
     return astFactory.showCombinator(
-      _getToken(data.combinator_keyword),
-      _readNodeList(data.showCombinator_shownNames),
+      _Tokens.SHOW,
+      data.names.map((name) => AstTestFactory.identifier3(name)).toList(),
     );
   }
 
   SimpleFormalParameter _read_simpleFormalParameter(LinkedNode data) {
     SimpleFormalParameterImpl node = astFactory.simpleFormalParameter2(
-      identifier: _readNode(data.normalFormalParameter_identifier),
+      identifier: _declaredIdentifier(data),
       type: _readNode(data.simpleFormalParameter_type),
-      covariantKeyword: _getToken(data.normalFormalParameter_covariantKeyword),
+      covariantKeyword:
+          AstBinaryFlags.isCovariant(data.flags) ? _Tokens.COVARIANT : null,
       comment: _readNode(data.normalFormalParameter_comment),
       metadata: _readNodeList(data.normalFormalParameter_metadata),
-      keyword: _getToken(data.simpleFormalParameter_keyword),
-      requiredKeyword: _getToken(data.normalFormalParameter_requiredKeyword),
+      keyword: _Tokens.choose(
+        AstBinaryFlags.isConst(data.flags),
+        _Tokens.CONST,
+        AstBinaryFlags.isFinal(data.flags),
+        _Tokens.FINAL,
+        AstBinaryFlags.isVar(data.flags),
+        _Tokens.VAR,
+      ),
+      requiredKeyword:
+          AstBinaryFlags.isRequired(data.flags) ? _Tokens.REQUIRED : null,
     );
     LazyFormalParameter.setData(node, data);
     LazyAst.setInheritsCovariant(node, data.inheritsCovariant);
@@ -1087,8 +1313,8 @@
 
   SimpleIdentifier _read_simpleIdentifier(LinkedNode data) {
     return astFactory.simpleIdentifier(
-      _getToken(data.simpleIdentifier_token),
-      isDeclaration: data.simpleIdentifier_isDeclaration,
+      TokenFactory.tokenFromString(data.name),
+      isDeclaration: AstBinaryFlags.isDeclaration(data.flags),
     )
       ..staticElement = _elementOfComponents(
         data.simpleIdentifier_element,
@@ -1098,15 +1324,15 @@
   }
 
   SimpleStringLiteral _read_simpleStringLiteral(LinkedNode data) {
-    return astFactory.simpleStringLiteral(
-      _getToken(data.simpleStringLiteral_token),
-      data.simpleStringLiteral_value,
-    )..staticType = _readType(data.expression_type);
+    // TODO(scheglov) restore staticType
+    return AstTestFactory.string2(data.simpleStringLiteral_value)
+//      ..staticType = _stringType
+        ;
   }
 
   SpreadElement _read_spreadElement(LinkedNode data) {
     return astFactory.spreadElement(
-      spreadOperator: _getToken(data.spreadElement_spreadOperator),
+      spreadOperator: _Tokens.fromType(data.spreadElement_spreadOperator),
       expression: _readNode(data.spreadElement_expression),
     );
   }
@@ -1114,13 +1340,13 @@
   StringInterpolation _read_stringInterpolation(LinkedNode data) {
     return astFactory.stringInterpolation(
       _readNodeList(data.stringInterpolation_elements),
-    )..staticType = _readType(data.expression_type);
+    )..staticType = _stringType;
   }
 
   SuperConstructorInvocation _read_superConstructorInvocation(LinkedNode data) {
     return astFactory.superConstructorInvocation(
-      _getToken(data.superConstructorInvocation_superKeyword),
-      _getToken(data.superConstructorInvocation_period),
+      _Tokens.SUPER,
+      _Tokens.PERIOD,
       _readNode(data.superConstructorInvocation_constructorName),
       _readNode(data.superConstructorInvocation_arguments),
     )..staticElement = _elementOfComponents(
@@ -1131,16 +1357,16 @@
 
   SuperExpression _read_superExpression(LinkedNode data) {
     return astFactory.superExpression(
-      _getToken(data.superExpression_superKeyword),
+      _Tokens.SUPER,
     )..staticType = _readType(data.expression_type);
   }
 
   SwitchCase _read_switchCase(LinkedNode data) {
     return astFactory.switchCase(
       _readNodeList(data.switchMember_labels),
-      _getToken(data.switchMember_keyword),
+      _Tokens.CASE,
       _readNode(data.switchCase_expression),
-      _getToken(data.switchMember_colon),
+      _Tokens.COLON,
       _readNodeList(data.switchMember_statements),
     );
   }
@@ -1148,79 +1374,91 @@
   SwitchDefault _read_switchDefault(LinkedNode data) {
     return astFactory.switchDefault(
       _readNodeList(data.switchMember_labels),
-      _getToken(data.switchMember_keyword),
-      _getToken(data.switchMember_colon),
+      _Tokens.DEFAULT,
+      _Tokens.COLON,
       _readNodeList(data.switchMember_statements),
     );
   }
 
   SwitchStatement _read_switchStatement(LinkedNode data) {
     return astFactory.switchStatement(
-      _getToken(data.switchStatement_switchKeyword),
-      _getToken(data.switchStatement_leftParenthesis),
+      _Tokens.SWITCH,
+      _Tokens.OPEN_PAREN,
       _readNode(data.switchStatement_expression),
-      _getToken(data.switchStatement_rightParenthesis),
-      _getToken(data.switchStatement_leftBracket),
+      _Tokens.CLOSE_PAREN,
+      _Tokens.OPEN_CURLY_BRACKET,
       _readNodeList(data.switchStatement_members),
-      _getToken(data.switchStatement_rightBracket),
+      _Tokens.CLOSE_CURLY_BRACKET,
     );
   }
 
   SymbolLiteral _read_symbolLiteral(LinkedNode data) {
     return astFactory.symbolLiteral(
-      _getToken(data.symbolLiteral_poundSign),
-      _getTokens(data.symbolLiteral_components),
+      _Tokens.HASH,
+      data.names.map((lexeme) => TokenFactory.tokenFromString(lexeme)).toList(),
     )..staticType = _readType(data.expression_type);
   }
 
   ThisExpression _read_thisExpression(LinkedNode data) {
     return astFactory.thisExpression(
-      _getToken(data.thisExpression_thisKeyword),
+      _Tokens.THIS,
     )..staticType = _readType(data.expression_type);
   }
 
   ThrowExpression _read_throwExpression(LinkedNode data) {
     return astFactory.throwExpression(
-      _getToken(data.throwExpression_throwKeyword),
+      _Tokens.THROW,
       _readNode(data.throwExpression_expression),
     )..staticType = _readType(data.expression_type);
   }
 
   TopLevelVariableDeclaration _read_topLevelVariableDeclaration(
       LinkedNode data) {
-    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;
+    timerAstBinaryReaderTopLevelVar.start();
+    try {
+      var node = astFactory.topLevelVariableDeclaration(
+        _readNodeLazy(data.annotatedNode_comment),
+        _readNodeListLazy(data.annotatedNode_metadata),
+        _readNode(data.topLevelVariableDeclaration_variableList),
+        _Tokens.SEMICOLON,
+      );
+      LazyTopLevelVariableDeclaration.setData(node, data);
+      return node;
+    } finally {
+      timerAstBinaryReaderTopLevelVar.stop();
+    }
   }
 
   TryStatement _read_tryStatement(LinkedNode data) {
     return astFactory.tryStatement(
-      _getToken(data.tryStatement_tryKeyword),
+      _Tokens.TRY,
       _readNode(data.tryStatement_body),
       _readNodeList(data.tryStatement_catchClauses),
-      _getToken(data.tryStatement_finallyKeyword),
+      _Tokens.FINALLY,
       _readNode(data.tryStatement_finallyBlock),
     );
   }
 
   TypeArgumentList _read_typeArgumentList(LinkedNode data) {
     return astFactory.typeArgumentList(
-      _getToken(data.typeArgumentList_leftBracket),
+      _Tokens.LT,
       _readNodeList(data.typeArgumentList_arguments),
-      _getToken(data.typeArgumentList_rightBracket),
+      _Tokens.GT,
     );
   }
 
   TypeName _read_typeName(LinkedNode data) {
     return astFactory.typeName(
       _readNode(data.typeName_name),
-      _readNode(data.typeName_typeArguments),
-      question: _getToken(data.typeName_question),
+      AstBinaryFlags.hasTypeArguments(data.flags)
+          ? astFactory.typeArgumentList(
+              _Tokens.LT,
+              _readNodeList(data.typeName_typeArguments),
+              _Tokens.GT,
+            )
+          : null,
+      question:
+          AstBinaryFlags.hasQuestion(data.flags) ? _Tokens.QUESTION : null,
     )..type = _readType(data.typeName_type);
   }
 
@@ -1228,8 +1466,8 @@
     var node = astFactory.typeParameter(
       _readNodeLazy(data.annotatedNode_comment),
       _readNodeListLazy(data.annotatedNode_metadata),
-      _readNode(data.typeParameter_name),
-      _getToken(data.typeParameter_extendsKeyword),
+      _declaredIdentifier(data),
+      _Tokens.EXTENDS,
       _readNodeLazy(data.typeParameter_bound),
     );
     LazyTypeParameter.setData(node, data);
@@ -1238,16 +1476,16 @@
 
   TypeParameterList _read_typeParameterList(LinkedNode data) {
     return astFactory.typeParameterList(
-      _getToken(data.typeParameterList_leftBracket),
+      _Tokens.LT,
       _readNodeList(data.typeParameterList_typeParameters),
-      _getToken(data.typeParameterList_rightBracket),
+      _Tokens.GT,
     );
   }
 
   VariableDeclaration _read_variableDeclaration(LinkedNode data) {
     var node = astFactory.variableDeclaration(
-      _readNode(data.variableDeclaration_name),
-      _getToken(data.variableDeclaration_equals),
+      _declaredIdentifier(data),
+      _Tokens.EQ,
       _readNodeLazy(data.variableDeclaration_initializer),
     );
     LazyVariableDeclaration.setData(node, data);
@@ -1258,8 +1496,15 @@
   VariableDeclarationList _read_variableDeclarationList(LinkedNode data) {
     var node = astFactory.variableDeclarationList2(
       comment: _readNodeLazy(data.annotatedNode_comment),
-      keyword: _getToken(data.variableDeclarationList_keyword),
-      lateKeyword: _getToken(data.variableDeclarationList_lateKeyword),
+      keyword: _Tokens.choose(
+        AstBinaryFlags.isConst(data.flags),
+        _Tokens.CONST,
+        AstBinaryFlags.isFinal(data.flags),
+        _Tokens.FINAL,
+        AstBinaryFlags.isVar(data.flags),
+        _Tokens.VAR,
+      ),
+      lateKeyword: AstBinaryFlags.isLate(data.flags) ? _Tokens.LATE : null,
       metadata: _readNodeListLazy(data.annotatedNode_metadata),
       type: _readNodeLazy(data.variableDeclarationList_type),
       variables: _readNodeList(data.variableDeclarationList_variables),
@@ -1272,33 +1517,33 @@
       LinkedNode data) {
     return astFactory.variableDeclarationStatement(
       _readNode(data.variableDeclarationStatement_variables),
-      _getToken(data.variableDeclarationStatement_semicolon),
+      _Tokens.SEMICOLON,
     );
   }
 
   WhileStatement _read_whileStatement(LinkedNode data) {
     return astFactory.whileStatement(
-      _getToken(data.whileStatement_whileKeyword),
-      _getToken(data.whileStatement_leftParenthesis),
+      _Tokens.WHILE,
+      _Tokens.OPEN_PAREN,
       _readNode(data.whileStatement_condition),
-      _getToken(data.whileStatement_rightParenthesis),
+      _Tokens.CLOSE_PAREN,
       _readNode(data.whileStatement_body),
     );
   }
 
   WithClause _read_withClause(LinkedNode data) {
     return astFactory.withClause(
-      _getToken(data.withClause_withKeyword),
+      _Tokens.WITH,
       _readNodeList(data.withClause_mixinTypes),
     );
   }
 
   YieldStatement _read_yieldStatement(LinkedNode data) {
     return astFactory.yieldStatement(
-      _getToken(data.yieldStatement_yieldKeyword),
-      _getToken(data.yieldStatement_star),
+      _Tokens.YIELD,
+      AstBinaryFlags.isStar(data.flags) ? _Tokens.STAR : null,
       _readNode(data.yieldStatement_expression),
-      _getToken(data.yieldStatement_semicolon),
+      _Tokens.SEMICOLON,
     );
   }
 
@@ -1488,8 +1733,6 @@
         return _read_rethrowExpression(data);
       case LinkedNodeKind.returnStatement:
         return _read_returnStatement(data);
-      case LinkedNodeKind.scriptTag:
-        return _read_scriptTag(data);
       case LinkedNodeKind.setOrMapLiteral:
         return _read_setOrMapLiteral(data);
       case LinkedNodeKind.showCombinator:
@@ -1591,3 +1834,106 @@
     }
   }
 }
+
+class _Tokens {
+  static final ABSTRACT = TokenFactory.tokenFromKeyword(Keyword.ABSTRACT);
+  static final ARROW = TokenFactory.tokenFromType(TokenType.FUNCTION);
+  static final AS = TokenFactory.tokenFromKeyword(Keyword.AS);
+  static final ASSERT = TokenFactory.tokenFromKeyword(Keyword.ASSERT);
+  static final AT = TokenFactory.tokenFromType(TokenType.AT);
+  static final ASYNC = TokenFactory.tokenFromKeyword(Keyword.ASYNC);
+  static final AWAIT = TokenFactory.tokenFromKeyword(Keyword.AWAIT);
+  static final BANG = TokenFactory.tokenFromType(TokenType.BANG);
+  static final BREAK = TokenFactory.tokenFromKeyword(Keyword.BREAK);
+  static final CASE = TokenFactory.tokenFromKeyword(Keyword.CASE);
+  static final CATCH = TokenFactory.tokenFromKeyword(Keyword.CATCH);
+  static final CLASS = TokenFactory.tokenFromKeyword(Keyword.CLASS);
+  static final CLOSE_CURLY_BRACKET =
+      TokenFactory.tokenFromType(TokenType.CLOSE_CURLY_BRACKET);
+  static final CLOSE_PAREN = TokenFactory.tokenFromType(TokenType.CLOSE_PAREN);
+  static final CLOSE_SQUARE_BRACKET =
+      TokenFactory.tokenFromType(TokenType.CLOSE_SQUARE_BRACKET);
+  static final COLON = TokenFactory.tokenFromType(TokenType.COLON);
+  static final COMMA = TokenFactory.tokenFromType(TokenType.COMMA);
+  static final CONST = TokenFactory.tokenFromKeyword(Keyword.CONST);
+  static final CONTINUE = TokenFactory.tokenFromKeyword(Keyword.CONTINUE);
+  static final COVARIANT = TokenFactory.tokenFromKeyword(Keyword.COVARIANT);
+  static final DEFERRED = TokenFactory.tokenFromKeyword(Keyword.DEFERRED);
+  static final ELSE = TokenFactory.tokenFromKeyword(Keyword.ELSE);
+  static final EXTERNAL = TokenFactory.tokenFromKeyword(Keyword.EXTERNAL);
+  static final FACTORY = TokenFactory.tokenFromKeyword(Keyword.FACTORY);
+  static final DEFAULT = TokenFactory.tokenFromKeyword(Keyword.DEFAULT);
+  static final DO = TokenFactory.tokenFromKeyword(Keyword.DO);
+  static final ENUM = TokenFactory.tokenFromKeyword(Keyword.ENUM);
+  static final EQ = TokenFactory.tokenFromType(TokenType.EQ);
+  static final EXPORT = TokenFactory.tokenFromKeyword(Keyword.EXPORT);
+  static final EXTENDS = TokenFactory.tokenFromKeyword(Keyword.EXTENDS);
+  static final FINAL = TokenFactory.tokenFromKeyword(Keyword.FINAL);
+  static final FINALLY = TokenFactory.tokenFromKeyword(Keyword.FINALLY);
+  static final FOR = TokenFactory.tokenFromKeyword(Keyword.FOR);
+  static final FUNCTION = TokenFactory.tokenFromKeyword(Keyword.FUNCTION);
+  static final GET = TokenFactory.tokenFromKeyword(Keyword.GET);
+  static final GT = TokenFactory.tokenFromType(TokenType.GT);
+  static final HASH = TokenFactory.tokenFromType(TokenType.HASH);
+  static final HIDE = TokenFactory.tokenFromKeyword(Keyword.HIDE);
+  static final IF = TokenFactory.tokenFromKeyword(Keyword.IF);
+  static final IMPLEMENTS = TokenFactory.tokenFromKeyword(Keyword.IMPORT);
+  static final IMPORT = TokenFactory.tokenFromKeyword(Keyword.IMPLEMENTS);
+  static final IN = TokenFactory.tokenFromKeyword(Keyword.IN);
+  static final IS = TokenFactory.tokenFromKeyword(Keyword.IS);
+  static final LATE = TokenFactory.tokenFromKeyword(Keyword.LATE);
+  static final LIBRARY = TokenFactory.tokenFromKeyword(Keyword.LIBRARY);
+  static final LT = TokenFactory.tokenFromType(TokenType.LT);
+  static final MIXIN = TokenFactory.tokenFromKeyword(Keyword.MIXIN);
+  static final NATIVE = TokenFactory.tokenFromKeyword(Keyword.NATIVE);
+  static final NEW = TokenFactory.tokenFromKeyword(Keyword.NEW);
+  static final NULL = TokenFactory.tokenFromKeyword(Keyword.NULL);
+  static final OF = TokenFactory.tokenFromKeyword(Keyword.OF);
+  static final ON = TokenFactory.tokenFromKeyword(Keyword.ON);
+  static final OPEN_CURLY_BRACKET =
+      TokenFactory.tokenFromType(TokenType.OPEN_CURLY_BRACKET);
+  static final OPEN_PAREN = TokenFactory.tokenFromType(TokenType.OPEN_PAREN);
+  static final OPEN_SQUARE_BRACKET =
+      TokenFactory.tokenFromType(TokenType.OPEN_SQUARE_BRACKET);
+  static final OPERATOR = TokenFactory.tokenFromKeyword(Keyword.OPERATOR);
+  static final PART = TokenFactory.tokenFromKeyword(Keyword.PART);
+  static final PERIOD = TokenFactory.tokenFromType(TokenType.PERIOD);
+  static final PERIOD_PERIOD =
+      TokenFactory.tokenFromType(TokenType.PERIOD_PERIOD);
+  static final QUESTION = TokenFactory.tokenFromType(TokenType.QUESTION);
+  static final REQUIRED = TokenFactory.tokenFromKeyword(Keyword.REQUIRED);
+  static final RETHROW = TokenFactory.tokenFromKeyword(Keyword.RETHROW);
+  static final RETURN = TokenFactory.tokenFromKeyword(Keyword.RETURN);
+  static final SEMICOLON = TokenFactory.tokenFromType(TokenType.SEMICOLON);
+  static final SET = TokenFactory.tokenFromKeyword(Keyword.SET);
+  static final SHOW = TokenFactory.tokenFromKeyword(Keyword.SHOW);
+  static final STAR = TokenFactory.tokenFromType(TokenType.STAR);
+  static final STATIC = TokenFactory.tokenFromKeyword(Keyword.STATIC);
+  static final STRING_INTERPOLATION_EXPRESSION =
+      TokenFactory.tokenFromType(TokenType.STRING_INTERPOLATION_EXPRESSION);
+  static final SUPER = TokenFactory.tokenFromKeyword(Keyword.SUPER);
+  static final SWITCH = TokenFactory.tokenFromKeyword(Keyword.SWITCH);
+  static final SYNC = TokenFactory.tokenFromKeyword(Keyword.SYNC);
+  static final THIS = TokenFactory.tokenFromKeyword(Keyword.THIS);
+  static final THROW = TokenFactory.tokenFromKeyword(Keyword.THROW);
+  static final TRY = TokenFactory.tokenFromKeyword(Keyword.TRY);
+  static final TYPEDEF = TokenFactory.tokenFromKeyword(Keyword.TYPEDEF);
+  static final VAR = TokenFactory.tokenFromKeyword(Keyword.VAR);
+  static final WITH = TokenFactory.tokenFromKeyword(Keyword.WITH);
+  static final WHILE = TokenFactory.tokenFromKeyword(Keyword.WHILE);
+  static final YIELD = TokenFactory.tokenFromKeyword(Keyword.YIELD);
+
+  static Token choose(bool if1, Token then1, bool if2, Token then2,
+      [bool if3, Token then3]) {
+    if (if1) return then1;
+    if (if2) return then2;
+    if (if2 == true) return then3;
+    return null;
+  }
+
+  static Token fromType(UnlinkedTokenType type) {
+    return TokenFactory.tokenFromType(
+      TokensContext.binaryToAstTokenType(type),
+    );
+  }
+}
diff --git a/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart b/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart
index 2cc58d4..ce98e5d 100644
--- a/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart
+++ b/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart
@@ -11,23 +11,36 @@
 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/ast_binary_flags.dart';
 import 'package:analyzer/src/summary2/lazy_ast.dart';
 import 'package:analyzer/src/summary2/linking_bundle_context.dart';
 import 'package:analyzer/src/summary2/tokens_writer.dart';
 
+var timerAstBinaryWriter = Stopwatch();
+var timerAstBinaryWriterClass = Stopwatch();
+var timerAstBinaryWriterDirective = Stopwatch();
+var timerAstBinaryWriterFunctionBody = Stopwatch();
+var timerAstBinaryWriterMixin = Stopwatch();
+var timerAstBinaryWriterTopVar = Stopwatch();
+var timerAstBinaryWriterTypedef = Stopwatch();
+
 /// Serializer of fully resolved ASTs into flat buffers.
 class AstBinaryWriter extends ThrowingAstVisitor<LinkedNodeBuilder> {
   final LinkingBundleContext _linkingContext;
-  final _tokensWriter = TokensWriter();
+
+  /// The list stored [GenericFunctionType]s, as visited in depth-first order.
+  final List<LinkedNodeBuilder> genericFunctionTypes = [];
 
   /// This field is set temporary while visiting [FieldDeclaration] or
   /// [TopLevelVariableDeclaration] to store data shared among all variables
   /// in these declarations.
   LinkedNodeVariablesDeclarationBuilder _variablesDeclaration;
 
-  AstBinaryWriter(this._linkingContext);
+  /// Is `true` if the current [ClassDeclaration] has a const constructor,
+  /// so initializers of final fields should be written.
+  bool _hasConstConstructor = false;
 
-  UnlinkedTokensBuilder get tokensBuilder => _tokensWriter.tokensBuilder;
+  AstBinaryWriter(this._linkingContext);
 
   @override
   LinkedNodeBuilder visitAdjacentStrings(AdjacentStrings node) {
@@ -41,12 +54,10 @@
     var elementComponents = _componentsOfElement(node.element);
     return LinkedNodeBuilder.annotation(
       annotation_arguments: node.arguments?.accept(this),
-      annotation_atSign: _getToken(node.atSign),
       annotation_constructorName: node.constructorName?.accept(this),
       annotation_element: elementComponents.rawElement,
       annotation_elementType: elementComponents.definingType,
       annotation_name: node.name?.accept(this),
-      annotation_period: _getToken(node.period),
     );
   }
 
@@ -54,15 +65,12 @@
   LinkedNodeBuilder visitArgumentList(ArgumentList node) {
     return LinkedNodeBuilder.argumentList(
       argumentList_arguments: _writeNodeList(node.arguments),
-      argumentList_leftParenthesis: _getToken(node.leftParenthesis),
-      argumentList_rightParenthesis: _getToken(node.rightParenthesis),
     );
   }
 
   @override
   LinkedNodeBuilder visitAsExpression(AsExpression node) {
     return LinkedNodeBuilder.asExpression(
-      asExpression_asOperator: _getToken(node.asOperator),
       asExpression_expression: node.expression.accept(this),
       asExpression_type: node.type.accept(this),
     );
@@ -71,25 +79,16 @@
   @override
   LinkedNodeBuilder visitAssertInitializer(AssertInitializer node) {
     return LinkedNodeBuilder.assertInitializer(
-      assertInitializer_assertKeyword: _getToken(node.assertKeyword),
-      assertInitializer_comma: _getToken(node.comma),
       assertInitializer_condition: node.condition.accept(this),
-      assertInitializer_leftParenthesis: _getToken(node.leftParenthesis),
       assertInitializer_message: node.message?.accept(this),
-      assertInitializer_rightParenthesis: _getToken(node.rightParenthesis),
     );
   }
 
   @override
   LinkedNodeBuilder visitAssertStatement(AssertStatement node) {
     var builder = LinkedNodeBuilder.assertStatement(
-      assertStatement_assertKeyword: _getToken(node.assertKeyword),
-      assertStatement_comma: _getToken(node.comma),
       assertStatement_condition: node.condition.accept(this),
-      assertStatement_leftParenthesis: _getToken(node.leftParenthesis),
       assertStatement_message: node.message?.accept(this),
-      assertStatement_rightParenthesis: _getToken(node.rightParenthesis),
-      assertStatement_semicolon: _getToken(node.semicolon),
     );
     _storeStatement(builder, node);
     return builder;
@@ -102,7 +101,9 @@
       assignmentExpression_element: elementComponents.rawElement,
       assignmentExpression_elementType: elementComponents.definingType,
       assignmentExpression_leftHandSide: node.leftHandSide.accept(this),
-      assignmentExpression_operator: _getToken(node.operator),
+      assignmentExpression_operator: TokensWriter.astToBinaryTokenType(
+        node.operator.type,
+      ),
       assignmentExpression_rightHandSide: node.rightHandSide.accept(this),
       expression_type: _writeType(node.staticType),
     );
@@ -111,7 +112,6 @@
   @override
   LinkedNodeBuilder visitAwaitExpression(AwaitExpression node) {
     return LinkedNodeBuilder.awaitExpression(
-      awaitExpression_awaitKeyword: _getToken(node.awaitKeyword),
       awaitExpression_expression: node.expression.accept(this),
       expression_type: _writeType(node.staticType),
     );
@@ -124,7 +124,9 @@
       binaryExpression_element: elementComponents.rawElement,
       binaryExpression_elementType: elementComponents.definingType,
       binaryExpression_leftOperand: node.leftOperand.accept(this),
-      binaryExpression_operator: _getToken(node.operator),
+      binaryExpression_operator: TokensWriter.astToBinaryTokenType(
+        node.operator.type,
+      ),
       binaryExpression_rightOperand: node.rightOperand.accept(this),
       expression_type: _writeType(node.staticType),
     );
@@ -133,25 +135,31 @@
   @override
   LinkedNodeBuilder visitBlock(Block node) {
     return LinkedNodeBuilder.block(
-      block_leftBracket: _getToken(node.leftBracket),
-      block_rightBracket: _getToken(node.rightBracket),
       block_statements: _writeNodeList(node.statements),
     );
   }
 
   @override
   LinkedNodeBuilder visitBlockFunctionBody(BlockFunctionBody node) {
-    return LinkedNodeBuilder.blockFunctionBody(
-      blockFunctionBody_block: node.block.accept(this),
-      blockFunctionBody_keyword: _getToken(node.keyword),
-      blockFunctionBody_star: _getToken(node.star),
-    );
+    timerAstBinaryWriterFunctionBody.start();
+    try {
+      var builder = LinkedNodeBuilder.blockFunctionBody(
+        blockFunctionBody_block: node.block.accept(this),
+      );
+      builder.flags = AstBinaryFlags.encode(
+        isAsync: node.keyword?.keyword == Keyword.ASYNC,
+        isStar: node.star != null,
+        isSync: node.keyword?.keyword == Keyword.SYNC,
+      );
+      return builder;
+    } finally {
+      timerAstBinaryWriterFunctionBody.stop();
+    }
   }
 
   @override
   LinkedNodeBuilder visitBooleanLiteral(BooleanLiteral node) {
     return LinkedNodeBuilder.booleanLiteral(
-      booleanLiteral_literal: _getToken(node.literal),
       booleanLiteral_value: node.value,
     );
   }
@@ -159,9 +167,7 @@
   @override
   LinkedNodeBuilder visitBreakStatement(BreakStatement node) {
     var builder = LinkedNodeBuilder.breakStatement(
-      breakStatement_breakKeyword: _getToken(node.breakKeyword),
       breakStatement_label: node.label?.accept(this),
-      breakStatement_semicolon: _getToken(node.semicolon),
     );
     _storeStatement(builder, node);
     return builder;
@@ -181,43 +187,59 @@
   LinkedNodeBuilder visitCatchClause(CatchClause node) {
     return LinkedNodeBuilder.catchClause(
       catchClause_body: node.body.accept(this),
-      catchClause_catchKeyword: _getToken(node.catchKeyword),
-      catchClause_comma: _getToken(node.comma),
       catchClause_exceptionParameter: node.exceptionParameter?.accept(this),
       catchClause_exceptionType: node.exceptionType?.accept(this),
-      catchClause_leftParenthesis: _getToken(node.leftParenthesis),
-      catchClause_onKeyword: _getToken(node.onKeyword),
-      catchClause_rightParenthesis: _getToken(node.rightParenthesis),
       catchClause_stackTraceParameter: node.stackTraceParameter?.accept(this),
     );
   }
 
   @override
   LinkedNodeBuilder visitClassDeclaration(ClassDeclaration node) {
-    var builder = LinkedNodeBuilder.classDeclaration(
-      classDeclaration_abstractKeyword: _getToken(node.abstractKeyword),
-      classDeclaration_classKeyword: _getToken(node.classKeyword),
-      classDeclaration_extendsClause: node.extendsClause?.accept(this),
-      classDeclaration_nativeClause: node.nativeClause?.accept(this),
-      classDeclaration_withClause: node.withClause?.accept(this),
-    );
-    _storeClassOrMixinDeclaration(builder, node);
-    return builder;
+    try {
+      timerAstBinaryWriterClass.start();
+
+      _hasConstConstructor = false;
+      for (var member in node.members) {
+        if (member is ConstructorDeclaration && member.constKeyword != null) {
+          _hasConstConstructor = true;
+          break;
+        }
+      }
+
+      var builder = LinkedNodeBuilder.classDeclaration(
+        classDeclaration_extendsClause: node.extendsClause?.accept(this),
+        classDeclaration_nativeClause: node.nativeClause?.accept(this),
+        classDeclaration_withClause: node.withClause?.accept(this),
+      );
+      builder.flags = AstBinaryFlags.encode(
+        isAbstract: node.abstractKeyword != null,
+      );
+      _storeClassOrMixinDeclaration(builder, node);
+      return builder;
+    } finally {
+      timerAstBinaryWriterClass.stop();
+    }
   }
 
   @override
   LinkedNodeBuilder visitClassTypeAlias(ClassTypeAlias node) {
-    var builder = LinkedNodeBuilder.classTypeAlias(
-      classTypeAlias_abstractKeyword: _getToken(node.abstractKeyword),
-      classTypeAlias_equals: _getToken(node.equals),
-      classTypeAlias_implementsClause: node.implementsClause?.accept(this),
-      classTypeAlias_superclass: node.superclass.accept(this),
-      classTypeAlias_typeParameters: node.typeParameters?.accept(this),
-      classTypeAlias_withClause: node.withClause.accept(this),
-    );
-    _storeTypeAlias(builder, node);
-    _storeIsSimpleBounded(builder, node);
-    return builder;
+    timerAstBinaryWriterClass.start();
+    try {
+      var builder = LinkedNodeBuilder.classTypeAlias(
+        classTypeAlias_implementsClause: node.implementsClause?.accept(this),
+        classTypeAlias_superclass: node.superclass.accept(this),
+        classTypeAlias_typeParameters: node.typeParameters?.accept(this),
+        classTypeAlias_withClause: node.withClause.accept(this),
+      );
+      builder.flags = AstBinaryFlags.encode(
+        isAbstract: node.abstractKeyword != null,
+      );
+      _storeTypeAlias(builder, node);
+      _storeIsSimpleBounded(builder, node);
+      return builder;
+    } finally {
+      timerAstBinaryWriterClass.stop();
+    }
   }
 
   @override
@@ -232,33 +254,33 @@
     }
 
     return LinkedNodeBuilder.comment(
-      comment_tokens: _getTokens(node.tokens),
+      comment_tokens: node.tokens.map((t) => t.lexeme).toList(),
       comment_type: type,
-      comment_references: _writeNodeList(node.references),
+      // TODO(scheglov) restore
+//      comment_references: _writeNodeList(node.references),
     );
   }
 
   @override
   LinkedNodeBuilder visitCommentReference(CommentReference node) {
-    var identifier = node.identifier;
-    _tokensWriter.writeTokens(
-      node.newKeyword ?? identifier.beginToken,
-      identifier.endToken,
-    );
-
-    return LinkedNodeBuilder.commentReference(
-      commentReference_identifier: identifier.accept(this),
-      commentReference_newKeyword: _getToken(node.newKeyword),
-    );
+//    var identifier = node.identifier;
+//    _tokensWriter.writeTokens(
+//      node.newKeyword ?? identifier.beginToken,
+//      identifier.endToken,
+//    );
+//
+//    return LinkedNodeBuilder.commentReference(
+//      commentReference_identifier: identifier.accept(this),
+//      commentReference_newKeyword: _getToken(node.newKeyword),
+//    );
+    return null;
   }
 
   @override
   LinkedNodeBuilder visitCompilationUnit(CompilationUnit node) {
     var builder = LinkedNodeBuilder.compilationUnit(
-      compilationUnit_beginToken: _getToken(node.beginToken),
       compilationUnit_declarations: _writeNodeList(node.declarations),
       compilationUnit_directives: _writeNodeList(node.directives),
-      compilationUnit_endToken: _getToken(node.endToken),
       compilationUnit_scriptTag: node.scriptTag?.accept(this),
     );
     _storeCodeOffsetLength(builder, node);
@@ -268,10 +290,8 @@
   @override
   LinkedNodeBuilder visitConditionalExpression(ConditionalExpression node) {
     var builder = LinkedNodeBuilder.conditionalExpression(
-      conditionalExpression_colon: _getToken(node.colon),
       conditionalExpression_condition: node.condition.accept(this),
       conditionalExpression_elseExpression: node.elseExpression.accept(this),
-      conditionalExpression_question: _getToken(node.question),
       conditionalExpression_thenExpression: node.thenExpression.accept(this),
     );
     _storeExpression(builder, node);
@@ -280,33 +300,41 @@
 
   @override
   LinkedNodeBuilder visitConfiguration(Configuration node) {
-    return LinkedNodeBuilder.configuration(
-      configuration_equalToken: _getToken(node.equalToken),
-      configuration_ifKeyword: _getToken(node.ifKeyword),
-      configuration_leftParenthesis: _getToken(node.leftParenthesis),
+    var builder = LinkedNodeBuilder.configuration(
       configuration_name: node.name?.accept(this),
-      configuration_rightParenthesis: _getToken(node.rightParenthesis),
       configuration_value: node.value?.accept(this),
       configuration_uri: node.uri?.accept(this),
     );
+    builder.flags = AstBinaryFlags.encode(
+      hasEqual: node.equalToken != null,
+    );
+    return builder;
   }
 
   @override
   LinkedNodeBuilder visitConstructorDeclaration(ConstructorDeclaration node) {
     var builder = LinkedNodeBuilder.constructorDeclaration(
-      constructorDeclaration_body: node.body?.accept(this),
-      constructorDeclaration_constKeyword: _getToken(node.constKeyword),
-      constructorDeclaration_externalKeyword: _getToken(node.externalKeyword),
-      constructorDeclaration_factoryKeyword: _getToken(node.factoryKeyword),
       constructorDeclaration_initializers: _writeNodeList(node.initializers),
-      constructorDeclaration_name: node.name?.accept(this),
       constructorDeclaration_parameters: node.parameters.accept(this),
-      constructorDeclaration_period: _getToken(node.period),
       constructorDeclaration_redirectedConstructor:
           node.redirectedConstructor?.accept(this),
       constructorDeclaration_returnType: node.returnType.accept(this),
-      constructorDeclaration_separator: _getToken(node.separator),
     );
+    builder.flags = AstBinaryFlags.encode(
+      hasSeparatorColon: node.separator?.type == TokenType.COLON,
+      hasSeparatorEquals: node.separator?.type == TokenType.EQ,
+      isAbstract: node.body is EmptyFunctionBody,
+      isConst: node.constKeyword != null,
+      isExternal: node.externalKeyword != null,
+      isFactory: node.factoryKeyword != null,
+    );
+    if (node.name != null) {
+      builder
+        ..name = node.name.name
+        ..nameOffset = node.name.offset;
+    } else {
+      builder..nameOffset = node.returnType.offset;
+    }
     _storeClassMember(builder, node);
     _storeCodeOffsetLength(builder, node);
     return builder;
@@ -316,11 +344,11 @@
   LinkedNodeBuilder visitConstructorFieldInitializer(
       ConstructorFieldInitializer node) {
     var builder = LinkedNodeBuilder.constructorFieldInitializer(
-      constructorFieldInitializer_equals: _getToken(node.equals),
       constructorFieldInitializer_expression: node.expression.accept(this),
       constructorFieldInitializer_fieldName: node.fieldName.accept(this),
-      constructorFieldInitializer_period: _getToken(node.period),
-      constructorFieldInitializer_thisKeyword: _getToken(node.thisKeyword),
+    );
+    builder.flags = AstBinaryFlags.encode(
+      hasThis: node.thisKeyword != null,
     );
     _storeConstructorInitializer(builder, node);
     return builder;
@@ -333,7 +361,6 @@
       constructorName_element: elementComponents.rawElement,
       constructorName_elementType: elementComponents.definingType,
       constructorName_name: node.name?.accept(this),
-      constructorName_period: _getToken(node.period),
       constructorName_type: node.type.accept(this),
     );
   }
@@ -341,9 +368,7 @@
   @override
   LinkedNodeBuilder visitContinueStatement(ContinueStatement node) {
     var builder = LinkedNodeBuilder.continueStatement(
-      continueStatement_continueKeyword: _getToken(node.continueKeyword),
       continueStatement_label: node.label?.accept(this),
-      continueStatement_semicolon: _getToken(node.semicolon),
     );
     _storeStatement(builder, node);
     return builder;
@@ -353,9 +378,13 @@
   LinkedNodeBuilder visitDeclaredIdentifier(DeclaredIdentifier node) {
     var builder = LinkedNodeBuilder.declaredIdentifier(
       declaredIdentifier_identifier: node.identifier.accept(this),
-      declaredIdentifier_keyword: _getToken(node.keyword),
       declaredIdentifier_type: node.type?.accept(this),
     );
+    builder.flags = AstBinaryFlags.encode(
+      isConst: node.keyword?.keyword == Keyword.CONST,
+      isFinal: node.keyword?.keyword == Keyword.FINAL,
+      isVar: node.keyword?.keyword == Keyword.VAR,
+    );
     _storeDeclaration(builder, node);
     return builder;
   }
@@ -366,7 +395,9 @@
       defaultFormalParameter_defaultValue: node.defaultValue?.accept(this),
       defaultFormalParameter_kind: _toParameterKind(node),
       defaultFormalParameter_parameter: node.parameter.accept(this),
-      defaultFormalParameter_separator: _getToken(node.separator),
+    );
+    builder.flags = AstBinaryFlags.encode(
+      hasInitializer: node.defaultValue != null,
     );
     _storeCodeOffsetLength(builder, node);
     return builder;
@@ -377,11 +408,6 @@
     return LinkedNodeBuilder.doStatement(
       doStatement_body: node.body.accept(this),
       doStatement_condition: node.condition.accept(this),
-      doStatement_doKeyword: _getToken(node.doKeyword),
-      doStatement_leftParenthesis: _getToken(node.leftParenthesis),
-      doStatement_rightParenthesis: _getToken(node.rightParenthesis),
-      doStatement_semicolon: _getToken(node.semicolon),
-      doStatement_whileKeyword: _getToken(node.whileKeyword),
     );
   }
 
@@ -395,33 +421,28 @@
   @override
   LinkedNodeBuilder visitDoubleLiteral(DoubleLiteral node) {
     return LinkedNodeBuilder.doubleLiteral(
-      doubleLiteral_literal: _getToken(node.literal),
       doubleLiteral_value: node.value,
-      expression_type: _writeType(node.staticType),
     );
   }
 
   @override
   LinkedNodeBuilder visitEmptyFunctionBody(EmptyFunctionBody node) {
-    var builder = LinkedNodeBuilder.emptyFunctionBody(
-      emptyFunctionBody_semicolon: _getToken(node.semicolon),
-    );
+    var builder = LinkedNodeBuilder.emptyFunctionBody();
     _storeFunctionBody(builder, node);
     return builder;
   }
 
   @override
   LinkedNodeBuilder visitEmptyStatement(EmptyStatement node) {
-    return LinkedNodeBuilder.emptyStatement(
-      emptyStatement_semicolon: _getToken(node.semicolon),
-    );
+    return LinkedNodeBuilder.emptyStatement();
   }
 
   @override
   LinkedNodeBuilder visitEnumConstantDeclaration(EnumConstantDeclaration node) {
     var builder = LinkedNodeBuilder.enumConstantDeclaration(
-      enumConstantDeclaration_name: node.name.accept(this),
+      nameOffset: node.name.offset,
     );
+    builder..name = node.name.name;
     _storeDeclaration(builder, node);
     return builder;
   }
@@ -430,9 +451,6 @@
   LinkedNodeBuilder visitEnumDeclaration(EnumDeclaration node) {
     var builder = LinkedNodeBuilder.enumDeclaration(
       enumDeclaration_constants: _writeNodeList(node.constants),
-      enumDeclaration_enumKeyword: _getToken(node.enumKeyword),
-      enumDeclaration_leftBracket: _getToken(node.leftBracket),
-      enumDeclaration_rightBracket: _getToken(node.rightBracket),
     );
     _storeNamedCompilationUnitMember(builder, node);
     return builder;
@@ -440,33 +458,43 @@
 
   @override
   LinkedNodeBuilder visitExportDirective(ExportDirective node) {
-    var builder = LinkedNodeBuilder.exportDirective();
-    _storeNamespaceDirective(builder, node);
-    return builder;
+    timerAstBinaryWriterDirective.start();
+    try {
+      var builder = LinkedNodeBuilder.exportDirective();
+      _storeNamespaceDirective(builder, node);
+      return builder;
+    } finally {
+      timerAstBinaryWriterDirective.stop();
+    }
   }
 
   @override
   LinkedNodeBuilder visitExpressionFunctionBody(ExpressionFunctionBody node) {
-    return LinkedNodeBuilder.expressionFunctionBody(
-      expressionFunctionBody_arrow: _getToken(node.functionDefinition),
-      expressionFunctionBody_expression: node.expression.accept(this),
-      expressionFunctionBody_keyword: _getToken(node.keyword),
-      expressionFunctionBody_semicolon: _getToken(node.semicolon),
-    );
+    timerAstBinaryWriterFunctionBody.start();
+    try {
+      var builder = LinkedNodeBuilder.expressionFunctionBody(
+        expressionFunctionBody_expression: node.expression.accept(this),
+      );
+      builder.flags = AstBinaryFlags.encode(
+        isAsync: node.keyword?.keyword == Keyword.ASYNC,
+        isSync: node.keyword?.keyword == Keyword.SYNC,
+      );
+      return builder;
+    } finally {
+      timerAstBinaryWriterFunctionBody.stop();
+    }
   }
 
   @override
   LinkedNodeBuilder visitExpressionStatement(ExpressionStatement node) {
     return LinkedNodeBuilder.expressionStatement(
       expressionStatement_expression: node.expression.accept(this),
-      expressionStatement_semicolon: _getToken(node.semicolon),
     );
   }
 
   @override
   LinkedNodeBuilder visitExtendsClause(ExtendsClause node) {
     return LinkedNodeBuilder.extendsClause(
-      extendsClause_extendsKeyword: _getToken(node.extendsKeyword),
       extendsClause_superclass: node.superclass.accept(this),
     );
   }
@@ -479,10 +507,11 @@
     );
 
     var builder = LinkedNodeBuilder.fieldDeclaration(
-      fieldDeclaration_covariantKeyword: _getToken(node.covariantKeyword),
       fieldDeclaration_fields: node.fields.accept(this),
-      fieldDeclaration_semicolon: _getToken(node.semicolon),
-      fieldDeclaration_staticKeyword: _getToken(node.staticKeyword),
+    );
+    builder.flags = AstBinaryFlags.encode(
+      isCovariant: node.covariantKeyword != null,
+      isStatic: node.staticKeyword != null,
     );
     _storeClassMember(builder, node);
 
@@ -496,13 +525,10 @@
   LinkedNodeBuilder visitFieldFormalParameter(FieldFormalParameter node) {
     var builder = LinkedNodeBuilder.fieldFormalParameter(
       fieldFormalParameter_formalParameters: node.parameters?.accept(this),
-      fieldFormalParameter_keyword: _getToken(node.keyword),
-      fieldFormalParameter_period: _getToken(node.period),
-      fieldFormalParameter_thisKeyword: _getToken(node.thisKeyword),
       fieldFormalParameter_type: node.type?.accept(this),
       fieldFormalParameter_typeParameters: node.typeParameters?.accept(this),
     );
-    _storeNormalFormalParameter(builder, node);
+    _storeNormalFormalParameter(builder, node, node.keyword);
     return builder;
   }
 
@@ -537,13 +563,16 @@
 
   @override
   LinkedNodeBuilder visitFormalParameterList(FormalParameterList node) {
-    return LinkedNodeBuilder.formalParameterList(
-      formalParameterList_leftDelimiter: _getToken(node.leftDelimiter),
-      formalParameterList_leftParenthesis: _getToken(node.leftParenthesis),
+    var builder = LinkedNodeBuilder.formalParameterList(
       formalParameterList_parameters: _writeNodeList(node.parameters),
-      formalParameterList_rightDelimiter: _getToken(node.rightDelimiter),
-      formalParameterList_rightParenthesis: _getToken(node.rightParenthesis),
     );
+    builder.flags = AstBinaryFlags.encode(
+      isDelimiterCurly:
+          node.leftDelimiter?.type == TokenType.OPEN_CURLY_BRACKET,
+      isDelimiterSquare:
+          node.leftDelimiter?.type == TokenType.OPEN_SQUARE_BRACKET,
+    );
+    return builder;
   }
 
   @override
@@ -577,11 +606,14 @@
   @override
   LinkedNodeBuilder visitFunctionDeclaration(FunctionDeclaration node) {
     var builder = LinkedNodeBuilder.functionDeclaration(
-      functionDeclaration_externalKeyword: _getToken(node.externalKeyword),
+      functionDeclaration_returnType: node.returnType?.accept(this),
       functionDeclaration_functionExpression:
           node.functionExpression?.accept(this),
-      functionDeclaration_propertyKeyword: _getToken(node.propertyKeyword),
-      functionDeclaration_returnType: node.returnType?.accept(this),
+    );
+    builder.flags = AstBinaryFlags.encode(
+      isExternal: node.externalKeyword != null,
+      isGet: node.isGetter,
+      isSet: node.isSetter,
     );
     _storeNamedCompilationUnitMember(builder, node);
     _writeActualReturnType(builder, node);
@@ -599,11 +631,20 @@
 
   @override
   LinkedNodeBuilder visitFunctionExpression(FunctionExpression node) {
-    return LinkedNodeBuilder.functionExpression(
-      functionExpression_body: node.body?.accept(this),
+    var bodyToStore = node.body;
+    if (node.parent.parent is CompilationUnit) {
+      bodyToStore = null;
+    }
+    var builder = LinkedNodeBuilder.functionExpression(
+      functionExpression_body: bodyToStore?.accept(this),
       functionExpression_formalParameters: node.parameters?.accept(this),
       functionExpression_typeParameters: node.typeParameters?.accept(this),
     );
+    builder.flags = AstBinaryFlags.encode(
+      isAsync: node.body?.isAsynchronous ?? false,
+      isGenerator: node.body?.isGenerator ?? false,
+    );
+    return builder;
   }
 
   @override
@@ -618,17 +659,22 @@
 
   @override
   LinkedNodeBuilder visitFunctionTypeAlias(FunctionTypeAlias node) {
-    var builder = LinkedNodeBuilder.functionTypeAlias(
-      functionTypeAlias_formalParameters: node.parameters.accept(this),
-      functionTypeAlias_returnType: node.returnType?.accept(this),
-      functionTypeAlias_typeParameters: node.typeParameters?.accept(this),
-      typeAlias_hasSelfReference:
-          LazyFunctionTypeAlias.getHasSelfReference(node),
-    );
-    _storeTypeAlias(builder, node);
-    _writeActualReturnType(builder, node);
-    _storeIsSimpleBounded(builder, node);
-    return builder;
+    timerAstBinaryWriterTypedef.start();
+    try {
+      var builder = LinkedNodeBuilder.functionTypeAlias(
+        functionTypeAlias_formalParameters: node.parameters.accept(this),
+        functionTypeAlias_returnType: node.returnType?.accept(this),
+        functionTypeAlias_typeParameters: node.typeParameters?.accept(this),
+        typeAlias_hasSelfReference:
+            LazyFunctionTypeAlias.getHasSelfReference(node),
+      );
+      _storeTypeAlias(builder, node);
+      _writeActualReturnType(builder, node);
+      _storeIsSimpleBounded(builder, node);
+      return builder;
+    } finally {
+      timerAstBinaryWriterTypedef.stop();
+    }
   }
 
   @override
@@ -641,58 +687,69 @@
       functionTypedFormalParameter_typeParameters:
           node.typeParameters?.accept(this),
     );
-    _storeNormalFormalParameter(builder, node);
+    _storeNormalFormalParameter(builder, node, null);
     return builder;
   }
 
   @override
   LinkedNodeBuilder visitGenericFunctionType(GenericFunctionType node) {
+    var id = LazyAst.getGenericFunctionTypeId(node);
+    assert(id != null);
+    assert(genericFunctionTypes.length == id);
+    genericFunctionTypes.add(null);
+
     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),
     );
+    builder.flags = AstBinaryFlags.encode(
+      hasQuestion: node.question != null,
+    );
     _writeActualReturnType(builder, node);
 
-    var id = LazyAst.getGenericFunctionTypeId(node);
     builder.genericFunctionType_id = id;
+    genericFunctionTypes[id] = builder;
 
-    return builder;
+    return LinkedNodeBuilder.genericFunctionType(
+      genericFunctionType_id: id,
+    );
   }
 
   @override
   LinkedNodeBuilder visitGenericTypeAlias(GenericTypeAlias node) {
-    var builder = LinkedNodeBuilder.genericTypeAlias(
-      genericTypeAlias_equals: _getToken(node.equals),
-      genericTypeAlias_functionType: node.functionType?.accept(this),
-      genericTypeAlias_typeParameters: node.typeParameters?.accept(this),
-      typeAlias_hasSelfReference:
-          LazyGenericTypeAlias.getHasSelfReference(node),
-    );
-    _storeTypeAlias(builder, node);
-    _storeIsSimpleBounded(builder, node);
-    return builder;
+    timerAstBinaryWriterTypedef.start();
+    try {
+      var builder = LinkedNodeBuilder.genericTypeAlias(
+        genericTypeAlias_typeParameters: node.typeParameters?.accept(this),
+        genericTypeAlias_functionType: node.functionType?.accept(this),
+        typeAlias_hasSelfReference:
+            LazyGenericTypeAlias.getHasSelfReference(node),
+      );
+      _storeTypeAlias(builder, node);
+      _storeIsSimpleBounded(builder, node);
+      return builder;
+    } finally {
+      timerAstBinaryWriterTypedef.stop();
+    }
   }
 
   @override
   LinkedNodeBuilder visitHideCombinator(HideCombinator node) {
     var builder = LinkedNodeBuilder.hideCombinator(
-      hideCombinator_hiddenNames: _writeNodeList(node.hiddenNames),
+      names: node.hiddenNames.map((id) => id.name).toList(),
     );
-    _storeCombinator(builder, node);
     return builder;
   }
 
   @override
   LinkedNodeBuilder visitIfElement(IfElement node) {
     var builder = LinkedNodeBuilder.ifElement(
+      ifMixin_condition: node.condition.accept(this),
       ifElement_elseElement: node.elseElement?.accept(this),
       ifElement_thenElement: node.thenElement.accept(this),
     );
-    _storeIfMixin(builder, node as IfElementImpl);
     return builder;
   }
 
@@ -700,72 +757,78 @@
   LinkedNodeBuilder visitIfStatement(IfStatement node) {
     var builder = LinkedNodeBuilder.ifStatement(
       ifMixin_condition: node.condition.accept(this),
-      ifMixin_elseKeyword: _getToken(node.elseKeyword),
       ifStatement_elseStatement: node.elseStatement?.accept(this),
-      ifMixin_ifKeyword: _getToken(node.ifKeyword),
-      ifMixin_leftParenthesis: _getToken(node.leftParenthesis),
-      ifMixin_rightParenthesis: _getToken(node.rightParenthesis),
       ifStatement_thenStatement: node.thenStatement.accept(this),
     );
-    _storeIfMixin(builder, node as IfStatementImpl);
     return builder;
   }
 
   @override
   LinkedNodeBuilder visitImplementsClause(ImplementsClause node) {
     return LinkedNodeBuilder.implementsClause(
-      implementsClause_implementsKeyword: _getToken(node.implementsKeyword),
       implementsClause_interfaces: _writeNodeList(node.interfaces),
     );
   }
 
   @override
   LinkedNodeBuilder visitImportDirective(ImportDirective node) {
-    var builder = LinkedNodeBuilder.importDirective(
-      importDirective_asKeyword: _getToken(node.asKeyword),
-      importDirective_deferredKeyword: _getToken(node.deferredKeyword),
-      importDirective_prefix: node.prefix?.accept(this),
-    );
-    _storeNamespaceDirective(builder, node);
-    return builder;
+    timerAstBinaryWriterDirective.start();
+    try {
+      var builder = LinkedNodeBuilder.importDirective(
+        importDirective_prefix: node.prefix?.name,
+        importDirective_prefixOffset: node.prefix?.offset ?? 0,
+      );
+      builder.flags = AstBinaryFlags.encode(
+        isDeferred: node.deferredKeyword != null,
+      );
+      _storeNamespaceDirective(builder, node);
+      return builder;
+    } finally {
+      timerAstBinaryWriterDirective.stop();
+    }
   }
 
   @override
   LinkedNodeBuilder visitIndexExpression(IndexExpression node) {
     var elementComponents = _componentsOfElement(node.staticElement);
-    return LinkedNodeBuilder.indexExpression(
+    var builder = LinkedNodeBuilder.indexExpression(
       indexExpression_element: elementComponents.rawElement,
       indexExpression_elementType: elementComponents.definingType,
       indexExpression_index: node.index.accept(this),
-      indexExpression_leftBracket: _getToken(node.leftBracket),
-      indexExpression_period: _getToken(node.period),
-      indexExpression_rightBracket: _getToken(node.rightBracket),
       indexExpression_target: node.target?.accept(this),
       expression_type: _writeType(node.staticType),
     );
+    builder.flags = AstBinaryFlags.encode(
+      hasPeriod: node.period != null,
+    );
+    return builder;
   }
 
   @override
   LinkedNodeBuilder visitInstanceCreationExpression(
       InstanceCreationExpression node) {
     InstanceCreationExpressionImpl nodeImpl = node;
-    return LinkedNodeBuilder.instanceCreationExpression(
-      instanceCreationExpression_arguments: node.argumentList.accept(this),
+    var builder = LinkedNodeBuilder.instanceCreationExpression(
+      instanceCreationExpression_arguments: _writeNodeList(
+        node.argumentList.arguments,
+      ),
       instanceCreationExpression_constructorName:
           node.constructorName.accept(this),
-      instanceCreationExpression_keyword: _getToken(node.keyword),
       instanceCreationExpression_typeArguments:
           nodeImpl.typeArguments?.accept(this),
       expression_type: _writeType(node.staticType),
     );
+    builder.flags = AstBinaryFlags.encode(
+      isConst: node.keyword?.type == Keyword.CONST,
+      isNew: node.keyword?.type == Keyword.NEW,
+    );
+    return builder;
   }
 
   @override
   LinkedNodeBuilder visitIntegerLiteral(IntegerLiteral node) {
     return LinkedNodeBuilder.integerLiteral(
-      integerLiteral_literal: _getToken(node.literal),
       integerLiteral_value: node.value,
-      expression_type: _writeType(node.staticType),
     );
   }
 
@@ -773,15 +836,15 @@
   LinkedNodeBuilder visitInterpolationExpression(InterpolationExpression node) {
     return LinkedNodeBuilder.interpolationExpression(
       interpolationExpression_expression: node.expression.accept(this),
-      interpolationExpression_leftBracket: _getToken(node.leftBracket),
-      interpolationExpression_rightBracket: _getToken(node.rightBracket),
-    );
+    )..flags = AstBinaryFlags.encode(
+        isStringInterpolationIdentifier:
+            node.leftBracket.type == TokenType.STRING_INTERPOLATION_IDENTIFIER,
+      );
   }
 
   @override
   LinkedNodeBuilder visitInterpolationString(InterpolationString node) {
     return LinkedNodeBuilder.interpolationString(
-      interpolationString_token: _getToken(node.contents),
       interpolationString_value: node.value,
     );
   }
@@ -790,11 +853,11 @@
   LinkedNodeBuilder visitIsExpression(IsExpression node) {
     var builder = LinkedNodeBuilder.isExpression(
       isExpression_expression: node.expression.accept(this),
-      isExpression_isOperator: _getToken(node.isOperator),
-      isExpression_notOperator: _getToken(node.notOperator),
       isExpression_type: node.type.accept(this),
     );
-    _storeExpression(builder, node);
+    builder.flags = AstBinaryFlags.encode(
+      hasNot: node.notOperator != null,
+    );
     return builder;
   }
 
@@ -802,7 +865,6 @@
   LinkedNodeBuilder visitLabel(Label node) {
     return LinkedNodeBuilder.label(
       label_label: node.label.accept(this),
-      label_colon: _getToken(node.colon),
     );
   }
 
@@ -816,12 +878,16 @@
 
   @override
   LinkedNodeBuilder visitLibraryDirective(LibraryDirective node) {
-    var builder = LinkedNodeBuilder.libraryDirective(
-      libraryDirective_name: node.name.accept(this),
-      directive_semicolon: _getToken(node.semicolon),
-    );
-    _storeDirective(builder, node);
-    return builder;
+    timerAstBinaryWriterDirective.start();
+    try {
+      var builder = LinkedNodeBuilder.libraryDirective(
+        libraryDirective_name: node.name.accept(this),
+      );
+      _storeDirective(builder, node);
+      return builder;
+    } finally {
+      timerAstBinaryWriterDirective.stop();
+    }
   }
 
   @override
@@ -835,8 +901,6 @@
   LinkedNodeBuilder visitListLiteral(ListLiteral node) {
     var builder = LinkedNodeBuilder.listLiteral(
       listLiteral_elements: _writeNodeList(node.elements),
-      listLiteral_leftBracket: _getToken(node.leftBracket),
-      listLiteral_rightBracket: _getToken(node.rightBracket),
     );
     _storeTypedLiteral(builder, node);
     return builder;
@@ -846,7 +910,6 @@
   LinkedNodeBuilder visitMapLiteralEntry(MapLiteralEntry node) {
     return LinkedNodeBuilder.mapLiteralEntry(
       mapLiteralEntry_key: node.key.accept(this),
-      mapLiteralEntry_separator: _getToken(node.separator),
       mapLiteralEntry_value: node.value.accept(this),
     );
   }
@@ -854,16 +917,23 @@
   @override
   LinkedNodeBuilder visitMethodDeclaration(MethodDeclaration node) {
     var builder = LinkedNodeBuilder.methodDeclaration(
-      methodDeclaration_body: node.body?.accept(this),
-      methodDeclaration_externalKeyword: _getToken(node.externalKeyword),
       methodDeclaration_formalParameters: node.parameters?.accept(this),
-      methodDeclaration_modifierKeyword: _getToken(node.modifierKeyword),
-      methodDeclaration_name: node.name.accept(this),
-      methodDeclaration_operatorKeyword: _getToken(node.operatorKeyword),
-      methodDeclaration_propertyKeyword: _getToken(node.propertyKeyword),
       methodDeclaration_returnType: node.returnType?.accept(this),
       methodDeclaration_typeParameters: node.typeParameters?.accept(this),
     );
+    builder
+      ..name = node.name.name
+      ..nameOffset = node.name.offset;
+    builder.flags = AstBinaryFlags.encode(
+      isAbstract: node.body is EmptyFunctionBody,
+      isAsync: node.body?.isAsynchronous ?? false,
+      isExternal: node.externalKeyword != null,
+      isGenerator: node.body?.isGenerator ?? false,
+      isGet: node.isGetter,
+      isOperator: node.operatorKeyword != null,
+      isSet: node.isSetter,
+      isStatic: node.isStatic,
+    );
     _storeClassMember(builder, node);
     _storeCodeOffsetLength(builder, node);
     _writeActualReturnType(builder, node);
@@ -874,22 +944,29 @@
   LinkedNodeBuilder visitMethodInvocation(MethodInvocation node) {
     var builder = LinkedNodeBuilder.methodInvocation(
       methodInvocation_methodName: node.methodName?.accept(this),
-      methodInvocation_operator: _getToken(node.operator),
       methodInvocation_target: node.target?.accept(this),
     );
+    builder.flags = AstBinaryFlags.encode(
+      hasPeriod: node.operator?.type == TokenType.PERIOD,
+      hasPeriod2: node.operator?.type == TokenType.PERIOD_PERIOD,
+    );
     _storeInvocationExpression(builder, node);
     return builder;
   }
 
   @override
   LinkedNodeBuilder visitMixinDeclaration(MixinDeclaration node) {
-    var builder = LinkedNodeBuilder.mixinDeclaration(
-      mixinDeclaration_mixinKeyword: _getToken(node.mixinKeyword),
-      mixinDeclaration_onClause: node.onClause?.accept(this),
-    );
-    _storeClassOrMixinDeclaration(builder, node);
-    LazyMixinDeclaration.get(node).put(builder);
-    return builder;
+    timerAstBinaryWriterMixin.start();
+    try {
+      var builder = LinkedNodeBuilder.mixinDeclaration(
+        mixinDeclaration_onClause: node.onClause?.accept(this),
+      );
+      _storeClassOrMixinDeclaration(builder, node);
+      LazyMixinDeclaration.get(node).put(builder);
+      return builder;
+    } finally {
+      timerAstBinaryWriterMixin.stop();
+    }
   }
 
   @override
@@ -903,7 +980,6 @@
   @override
   LinkedNodeBuilder visitNativeClause(NativeClause node) {
     return LinkedNodeBuilder.nativeClause(
-      nativeClause_nativeKeyword: _getToken(node.nativeKeyword),
       nativeClause_name: node.name.accept(this),
     );
   }
@@ -911,25 +987,18 @@
   @override
   LinkedNodeBuilder visitNativeFunctionBody(NativeFunctionBody node) {
     return LinkedNodeBuilder.nativeFunctionBody(
-      nativeFunctionBody_nativeKeyword: _getToken(node.nativeKeyword),
-      nativeFunctionBody_semicolon: _getToken(node.semicolon),
       nativeFunctionBody_stringLiteral: node.stringLiteral?.accept(this),
     );
   }
 
   @override
   LinkedNodeBuilder visitNullLiteral(NullLiteral node) {
-    var builder = LinkedNodeBuilder.nullLiteral(
-      nullLiteral_literal: _getToken(node.literal),
-    );
-    _storeExpression(builder, node);
-    return builder;
+    return LinkedNodeBuilder.nullLiteral();
   }
 
   @override
   LinkedNodeBuilder visitOnClause(OnClause node) {
     return LinkedNodeBuilder.onClause(
-      onClause_onKeyword: _getToken(node.onKeyword),
       onClause_superclassConstraints:
           _writeNodeList(node.superclassConstraints),
     );
@@ -939,9 +1008,6 @@
   LinkedNodeBuilder visitParenthesizedExpression(ParenthesizedExpression node) {
     var builder = LinkedNodeBuilder.parenthesizedExpression(
       parenthesizedExpression_expression: node.expression.accept(this),
-      parenthesizedExpression_leftParenthesis: _getToken(node.leftParenthesis),
-      parenthesizedExpression_rightParenthesis:
-          _getToken(node.rightParenthesis),
     );
     _storeExpression(builder, node);
     return builder;
@@ -949,23 +1015,29 @@
 
   @override
   LinkedNodeBuilder visitPartDirective(PartDirective node) {
-    var builder = LinkedNodeBuilder.partDirective(
-      directive_semicolon: _getToken(node.semicolon),
-    );
-    _storeUriBasedDirective(builder, node);
-    return builder;
+    timerAstBinaryWriterDirective.start();
+    try {
+      var builder = LinkedNodeBuilder.partDirective();
+      _storeUriBasedDirective(builder, node);
+      return builder;
+    } finally {
+      timerAstBinaryWriterDirective.stop();
+    }
   }
 
   @override
   LinkedNodeBuilder visitPartOfDirective(PartOfDirective node) {
-    var builder = LinkedNodeBuilder.partOfDirective(
-      partOfDirective_libraryName: node.libraryName?.accept(this),
-      partOfDirective_ofKeyword: _getToken(node.ofKeyword),
-      directive_semicolon: _getToken(node.semicolon),
-      partOfDirective_uri: node.uri?.accept(this),
-    );
-    _storeDirective(builder, node);
-    return builder;
+    timerAstBinaryWriterDirective.start();
+    try {
+      var builder = LinkedNodeBuilder.partOfDirective(
+        partOfDirective_libraryName: node.libraryName?.accept(this),
+        partOfDirective_uri: node.uri?.accept(this),
+      );
+      _storeDirective(builder, node);
+      return builder;
+    } finally {
+      timerAstBinaryWriterDirective.stop();
+    }
   }
 
   @override
@@ -976,7 +1048,9 @@
       postfixExpression_element: elementComponents.rawElement,
       postfixExpression_elementType: elementComponents.definingType,
       postfixExpression_operand: node.operand.accept(this),
-      postfixExpression_operator: _getToken(node.operator),
+      postfixExpression_operator: TokensWriter.astToBinaryTokenType(
+        node.operator.type,
+      ),
     );
   }
 
@@ -984,7 +1058,6 @@
   LinkedNodeBuilder visitPrefixedIdentifier(PrefixedIdentifier node) {
     return LinkedNodeBuilder.prefixedIdentifier(
       prefixedIdentifier_identifier: node.identifier.accept(this),
-      prefixedIdentifier_period: _getToken(node.period),
       prefixedIdentifier_prefix: node.prefix.accept(this),
       expression_type: _writeType(node.staticType),
     );
@@ -998,14 +1071,18 @@
       prefixExpression_element: elementComponents.rawElement,
       prefixExpression_elementType: elementComponents.definingType,
       prefixExpression_operand: node.operand.accept(this),
-      prefixExpression_operator: _getToken(node.operator),
+      prefixExpression_operator: TokensWriter.astToBinaryTokenType(
+        node.operator.type,
+      ),
     );
   }
 
   @override
   LinkedNodeBuilder visitPropertyAccess(PropertyAccess node) {
     var builder = LinkedNodeBuilder.propertyAccess(
-      propertyAccess_operator: _getToken(node.operator),
+      propertyAccess_operator: TokensWriter.astToBinaryTokenType(
+        node.operator.type,
+      ),
       propertyAccess_propertyName: node.propertyName.accept(this),
       propertyAccess_target: node.target?.accept(this),
     );
@@ -1025,8 +1102,9 @@
       redirectingConstructorInvocation_element: elementComponents.rawElement,
       redirectingConstructorInvocation_elementType:
           elementComponents.definingType,
-      redirectingConstructorInvocation_period: _getToken(node.period),
-      redirectingConstructorInvocation_thisKeyword: _getToken(node.thisKeyword),
+    );
+    builder.flags = AstBinaryFlags.encode(
+      hasThis: node.thisKeyword != null,
     );
     _storeConstructorInitializer(builder, node);
     return builder;
@@ -1034,59 +1112,47 @@
 
   @override
   LinkedNodeBuilder visitRethrowExpression(RethrowExpression node) {
-    var builder = LinkedNodeBuilder.rethrowExpression(
-      rethrowExpression_rethrowKeyword: _getToken(node.rethrowKeyword),
+    return LinkedNodeBuilder.rethrowExpression(
+      expression_type: _writeType(node.staticType),
     );
-    _storeExpression(builder, node);
-    return builder;
   }
 
   @override
   LinkedNodeBuilder visitReturnStatement(ReturnStatement node) {
     return LinkedNodeBuilder.returnStatement(
       returnStatement_expression: node.expression?.accept(this),
-      returnStatement_returnKeyword: _getToken(node.returnKeyword),
-      returnStatement_semicolon: _getToken(node.semicolon),
     );
   }
 
   @override
   LinkedNodeBuilder visitScriptTag(ScriptTag node) {
-    return LinkedNodeBuilder.scriptTag(
-      scriptTag_scriptTag: _getToken(node.scriptTag),
-    );
+    return null;
   }
 
   @override
   LinkedNodeBuilder visitSetOrMapLiteral(SetOrMapLiteral node) {
     var builder = LinkedNodeBuilder.setOrMapLiteral(
       setOrMapLiteral_elements: _writeNodeList(node.elements),
-      setOrMapLiteral_isMap: node.isMap,
-      setOrMapLiteral_isSet: node.isSet,
-      setOrMapLiteral_leftBracket: _getToken(node.leftBracket),
-      setOrMapLiteral_rightBracket: _getToken(node.rightBracket),
     );
-    _storeTypedLiteral(builder, node);
+    _storeTypedLiteral(builder, node, isMap: node.isMap, isSet: node.isSet);
     return builder;
   }
 
   @override
   LinkedNodeBuilder visitShowCombinator(ShowCombinator node) {
     var builder = LinkedNodeBuilder.showCombinator(
-      showCombinator_shownNames: _writeNodeList(node.shownNames),
+      names: node.shownNames.map((id) => id.name).toList(),
     );
-    _storeCombinator(builder, node);
     return builder;
   }
 
   @override
   LinkedNodeBuilder visitSimpleFormalParameter(SimpleFormalParameter node) {
     var builder = LinkedNodeBuilder.simpleFormalParameter(
-      simpleFormalParameter_keyword: _getToken(node.keyword),
       simpleFormalParameter_type: node.type?.accept(this),
     );
     builder.topLevelTypeInferenceError = LazyAst.getTypeInferenceError(node);
-    _storeNormalFormalParameter(builder, node);
+    _storeNormalFormalParameter(builder, node, node.keyword);
     _storeInheritsCovariant(builder, node);
     return builder;
   }
@@ -1102,22 +1168,23 @@
     }
 
     var elementComponents = _componentsOfElement(element);
-    return LinkedNodeBuilder.simpleIdentifier(
+    var builder = LinkedNodeBuilder.simpleIdentifier(
       simpleIdentifier_element: elementComponents.rawElement,
       simpleIdentifier_elementType: elementComponents.definingType,
-      simpleIdentifier_isDeclaration: node is DeclaredSimpleIdentifier,
-      simpleIdentifier_token: _getToken(node.token),
       expression_type: _writeType(node.staticType),
     );
+    builder.flags = AstBinaryFlags.encode(
+      isDeclaration: node is DeclaredSimpleIdentifier,
+    );
+    builder.name = node.name;
+    return builder;
   }
 
   @override
   LinkedNodeBuilder visitSimpleStringLiteral(SimpleStringLiteral node) {
     var builder = LinkedNodeBuilder.simpleStringLiteral(
-      simpleStringLiteral_token: _getToken(node.literal),
       simpleStringLiteral_value: node.value,
     );
-    _storeExpression(builder, node);
     return builder;
   }
 
@@ -1125,7 +1192,9 @@
   LinkedNodeBuilder visitSpreadElement(SpreadElement node) {
     return LinkedNodeBuilder.spreadElement(
       spreadElement_expression: node.expression.accept(this),
-      spreadElement_spreadOperator: _getToken(node.spreadOperator),
+      spreadElement_spreadOperator: TokensWriter.astToBinaryTokenType(
+        node.spreadOperator.type,
+      ),
     );
   }
 
@@ -1133,7 +1202,6 @@
   LinkedNodeBuilder visitStringInterpolation(StringInterpolation node) {
     return LinkedNodeBuilder.stringInterpolation(
       stringInterpolation_elements: _writeNodeList(node.elements),
-      expression_type: _writeType(node.staticType),
     );
   }
 
@@ -1147,8 +1215,6 @@
           node.constructorName?.accept(this),
       superConstructorInvocation_element: elementComponents.rawElement,
       superConstructorInvocation_elementType: elementComponents.definingType,
-      superConstructorInvocation_period: _getToken(node.period),
-      superConstructorInvocation_superKeyword: _getToken(node.superKeyword),
     );
     _storeConstructorInitializer(builder, node);
     return builder;
@@ -1156,9 +1222,7 @@
 
   @override
   LinkedNodeBuilder visitSuperExpression(SuperExpression node) {
-    var builder = LinkedNodeBuilder.superExpression(
-      superExpression_superKeyword: _getToken(node.superKeyword),
-    );
+    var builder = LinkedNodeBuilder.superExpression();
     _storeExpression(builder, node);
     return builder;
   }
@@ -1183,20 +1247,14 @@
   LinkedNodeBuilder visitSwitchStatement(SwitchStatement node) {
     return LinkedNodeBuilder.switchStatement(
       switchStatement_expression: node.expression.accept(this),
-      switchStatement_leftBracket: _getToken(node.leftBracket),
-      switchStatement_leftParenthesis: _getToken(node.leftParenthesis),
       switchStatement_members: _writeNodeList(node.members),
-      switchStatement_rightBracket: _getToken(node.rightBracket),
-      switchStatement_rightParenthesis: _getToken(node.rightParenthesis),
-      switchStatement_switchKeyword: _getToken(node.switchKeyword),
     );
   }
 
   @override
   LinkedNodeBuilder visitSymbolLiteral(SymbolLiteral node) {
     var builder = LinkedNodeBuilder.symbolLiteral(
-      symbolLiteral_poundSign: _getToken(node.poundSign),
-      symbolLiteral_components: _getTokens(node.components),
+      names: node.components.map((t) => t.lexeme).toList(),
     );
     _storeExpression(builder, node);
     return builder;
@@ -1204,9 +1262,7 @@
 
   @override
   LinkedNodeBuilder visitThisExpression(ThisExpression node) {
-    var builder = LinkedNodeBuilder.thisExpression(
-      thisExpression_thisKeyword: _getToken(node.thisKeyword),
-    );
+    var builder = LinkedNodeBuilder.thisExpression();
     _storeExpression(builder, node);
     return builder;
   }
@@ -1215,7 +1271,6 @@
   LinkedNodeBuilder visitThrowExpression(ThrowExpression node) {
     return LinkedNodeBuilder.throwExpression(
       throwExpression_expression: node.expression.accept(this),
-      throwExpression_throwKeyword: _getToken(node.throwKeyword),
       expression_type: _writeType(node.staticType),
     );
   }
@@ -1223,18 +1278,22 @@
   @override
   LinkedNodeBuilder visitTopLevelVariableDeclaration(
       TopLevelVariableDeclaration node) {
-    _variablesDeclaration = LinkedNodeVariablesDeclarationBuilder();
+    timerAstBinaryWriterTopVar.start();
+    try {
+      _variablesDeclaration = LinkedNodeVariablesDeclarationBuilder();
 
-    var builder = LinkedNodeBuilder.topLevelVariableDeclaration(
-      topLevelVariableDeclaration_semicolon: _getToken(node.semicolon),
-      topLevelVariableDeclaration_variableList: node.variables?.accept(this),
-    );
-    _storeCompilationUnitMember(builder, node);
+      var builder = LinkedNodeBuilder.topLevelVariableDeclaration(
+        topLevelVariableDeclaration_variableList: node.variables?.accept(this),
+      );
+      _storeCompilationUnitMember(builder, node);
 
-    _variablesDeclaration.comment = builder.annotatedNode_comment;
-    _variablesDeclaration = null;
+      _variablesDeclaration.comment = builder.annotatedNode_comment;
+      _variablesDeclaration = null;
 
-    return builder;
+      return builder;
+    } finally {
+      timerAstBinaryWriterTopVar.stop();
+    }
   }
 
   @override
@@ -1243,8 +1302,6 @@
       tryStatement_body: node.body.accept(this),
       tryStatement_catchClauses: _writeNodeList(node.catchClauses),
       tryStatement_finallyBlock: node.finallyBlock?.accept(this),
-      tryStatement_finallyKeyword: _getToken(node.finallyKeyword),
-      tryStatement_tryKeyword: _getToken(node.tryKeyword),
     );
   }
 
@@ -1252,8 +1309,6 @@
   LinkedNodeBuilder visitTypeArgumentList(TypeArgumentList node) {
     return LinkedNodeBuilder.typeArgumentList(
       typeArgumentList_arguments: _writeNodeList(node.arguments),
-      typeArgumentList_leftBracket: _getToken(node.leftBracket),
-      typeArgumentList_rightBracket: _getToken(node.rightBracket),
     );
   }
 
@@ -1261,10 +1316,14 @@
   LinkedNodeBuilder visitTypeName(TypeName node) {
     return LinkedNodeBuilder.typeName(
       typeName_name: node.name.accept(this),
-      typeName_question: _getToken(node.question),
       typeName_type: _writeType(node.type),
-      typeName_typeArguments: node.typeArguments?.accept(this),
-    );
+      typeName_typeArguments: _writeNodeList(
+        node.typeArguments?.arguments,
+      ),
+    )..flags = AstBinaryFlags.encode(
+        hasQuestion: node.question != null,
+        hasTypeArguments: node.typeArguments != null,
+      );
   }
 
   @override
@@ -1272,9 +1331,10 @@
     var builder = LinkedNodeBuilder.typeParameter(
       typeParameter_bound: node.bound?.accept(this),
       typeParameter_defaultType: _writeType(LazyAst.getDefaultType(node)),
-      typeParameter_extendsKeyword: _getToken(node.extendsKeyword),
-      typeParameter_name: node.name.accept(this),
     );
+    builder
+      ..name = node.name.name
+      ..nameOffset = node.name.offset;
     _storeDeclaration(builder, node);
     _storeCodeOffsetLength(builder, node);
     return builder;
@@ -1283,20 +1343,38 @@
   @override
   LinkedNodeBuilder visitTypeParameterList(TypeParameterList node) {
     return LinkedNodeBuilder.typeParameterList(
-      typeParameterList_leftBracket: _getToken(node.leftBracket),
-      typeParameterList_rightBracket: _getToken(node.rightBracket),
       typeParameterList_typeParameters: _writeNodeList(node.typeParameters),
     );
   }
 
   @override
   LinkedNodeBuilder visitVariableDeclaration(VariableDeclaration node) {
+    var initializer = node.initializer;
+    var declarationList = node.parent as VariableDeclarationList;
+    var declaration = declarationList.parent;
+    if (declaration is TopLevelVariableDeclaration) {
+      if (!declarationList.isConst) {
+        initializer = null;
+      }
+    } else if (declaration is FieldDeclaration) {
+      if (!(declarationList.isConst ||
+          !declaration.isStatic &&
+              declarationList.isFinal &&
+              _hasConstConstructor)) {
+        initializer = null;
+      }
+    }
+
     var builder = LinkedNodeBuilder.variableDeclaration(
-      variableDeclaration_equals: _getToken(node.equals),
-      variableDeclaration_initializer: node.initializer?.accept(this),
-      variableDeclaration_name: node.name.accept(this),
+      variableDeclaration_initializer: initializer?.accept(this),
       variableDeclaration_declaration: _variablesDeclaration,
     );
+    builder.flags = AstBinaryFlags.encode(
+      hasInitializer: node.initializer != null,
+    );
+    builder
+      ..name = node.name.name
+      ..nameOffset = node.name.offset;
     builder.topLevelTypeInferenceError = LazyAst.getTypeInferenceError(node);
     _writeActualType(builder, node);
     _storeInheritsCovariant(builder, node);
@@ -1311,11 +1389,15 @@
     }
 
     var builder = LinkedNodeBuilder.variableDeclarationList(
-      variableDeclarationList_keyword: _getToken(node.keyword),
-      variableDeclarationList_lateKeyword: _getToken(node.lateKeyword),
       variableDeclarationList_type: node.type?.accept(this),
       variableDeclarationList_variables: _writeNodeList(node.variables),
     );
+    builder.flags = AstBinaryFlags.encode(
+      isConst: node.isConst,
+      isFinal: node.isFinal,
+      isLate: node.lateKeyword != null,
+      isVar: node.keyword?.keyword == Keyword.VAR,
+    );
     _storeAnnotatedNode(builder, node);
     _storeCodeOffsetLengthVariables(builder, node);
     return builder;
@@ -1325,7 +1407,6 @@
   LinkedNodeBuilder visitVariableDeclarationStatement(
       VariableDeclarationStatement node) {
     return LinkedNodeBuilder.variableDeclarationStatement(
-      variableDeclarationStatement_semicolon: _getToken(node.semicolon),
       variableDeclarationStatement_variables: node.variables.accept(this),
     );
   }
@@ -1335,9 +1416,6 @@
     return LinkedNodeBuilder.whileStatement(
       whileStatement_body: node.body.accept(this),
       whileStatement_condition: node.condition.accept(this),
-      whileStatement_leftParenthesis: _getToken(node.leftParenthesis),
-      whileStatement_rightParenthesis: _getToken(node.rightParenthesis),
-      whileStatement_whileKeyword: _getToken(node.whileKeyword),
     );
   }
 
@@ -1345,25 +1423,28 @@
   LinkedNodeBuilder visitWithClause(WithClause node) {
     return LinkedNodeBuilder.withClause(
       withClause_mixinTypes: _writeNodeList(node.mixinTypes),
-      withClause_withKeyword: _getToken(node.withKeyword),
     );
   }
 
   @override
   LinkedNodeBuilder visitYieldStatement(YieldStatement node) {
     var builder = LinkedNodeBuilder.yieldStatement(
-      yieldStatement_yieldKeyword: _getToken(node.yieldKeyword),
       yieldStatement_expression: node.expression.accept(this),
-      yieldStatement_semicolon: _getToken(node.semicolon),
-      yieldStatement_star: _getToken(node.star),
+    );
+    builder.flags = AstBinaryFlags.encode(
+      isStar: node.star != null,
     );
     _storeStatement(builder, node);
     return builder;
   }
 
-  LinkedNodeBuilder writeNode(AstNode node) {
-    _tokensWriter.writeTokens(node.beginToken, node.endToken);
-    return node.accept(this);
+  LinkedNodeBuilder writeUnit(CompilationUnit unit) {
+    timerAstBinaryWriter.start();
+    try {
+      return unit.accept(this);
+    } finally {
+      timerAstBinaryWriter.stop();
+    }
   }
 
   _ElementComponents _componentsOfElement(Element element) {
@@ -1381,19 +1462,6 @@
     return _ElementComponents(elementIndex, null);
   }
 
-  int _getToken(Token token) {
-    return _tokensWriter.indexOfToken(token);
-  }
-
-  List<int> _getTokens(List<Token> tokenList) {
-    var result = List<int>(tokenList.length);
-    for (var i = 0; i < tokenList.length; ++i) {
-      var token = tokenList[i];
-      result[i] = _getToken(token);
-    }
-    return result;
-  }
-
   int _indexOfElement(Element element) {
     return _linkingContext.indexOfElement(element);
   }
@@ -1413,9 +1481,7 @@
     builder
       ..classOrMixinDeclaration_implementsClause =
           node.implementsClause?.accept(this)
-      ..classOrMixinDeclaration_leftBracket = _getToken(node.leftBracket)
       ..classOrMixinDeclaration_members = _writeNodeList(node.members)
-      ..classOrMixinDeclaration_rightBracket = _getToken(node.rightBracket)
       ..classOrMixinDeclaration_typeParameters =
           node.typeParameters?.accept(this);
     _storeNamedCompilationUnitMember(builder, node);
@@ -1439,10 +1505,6 @@
     }
   }
 
-  void _storeCombinator(LinkedNodeBuilder builder, Combinator node) {
-    builder.combinator_keyword = _getToken(node.keyword);
-  }
-
   void _storeCompilationUnitMember(
       LinkedNodeBuilder builder, CompilationUnitMember node) {
     _storeDeclaration(builder, node);
@@ -1457,7 +1519,6 @@
 
   void _storeDirective(LinkedNodeBuilder builder, Directive node) {
     _storeAnnotatedNode(builder, node);
-    builder..directive_keyword = _getToken(node.keyword);
   }
 
   void _storeExpression(LinkedNodeBuilder builder, Expression node) {
@@ -1466,9 +1527,7 @@
 
   void _storeForEachParts(LinkedNodeBuilder builder, ForEachParts node) {
     _storeForLoopParts(builder, node);
-    builder
-      ..forEachParts_inKeyword = _getToken(node.inKeyword)
-      ..forEachParts_iterable = node.iterable?.accept(this);
+    builder..forEachParts_iterable = node.iterable?.accept(this);
   }
 
   void _storeForLoopParts(LinkedNodeBuilder builder, ForLoopParts node) {}
@@ -1479,34 +1538,21 @@
   }
 
   void _storeForMixin(LinkedNodeBuilder builder, ForMixin node) {
-    builder
-      ..forMixin_awaitKeyword = _getToken(node.awaitKeyword)
-      ..forMixin_forKeyword = _getToken(node.forKeyword)
-      ..forMixin_forLoopParts = node.forLoopParts.accept(this)
-      ..forMixin_leftParenthesis = _getToken(node.leftParenthesis)
-      ..forMixin_rightParenthesis = _getToken(node.rightParenthesis);
+    builder.flags = AstBinaryFlags.encode(
+      hasAwait: node.awaitKeyword != null,
+    );
+    builder..forMixin_forLoopParts = node.forLoopParts.accept(this);
   }
 
   void _storeForParts(LinkedNodeBuilder builder, ForParts node) {
     _storeForLoopParts(builder, node);
     builder
-      ..forParts_leftSeparator = _getToken(node.leftSeparator)
       ..forParts_condition = node.condition?.accept(this)
-      ..forParts_rightSeparator = _getToken(node.rightSeparator)
       ..forParts_updaters = _writeNodeList(node.updaters);
   }
 
   void _storeFunctionBody(LinkedNodeBuilder builder, FunctionBody node) {}
 
-  void _storeIfMixin(LinkedNodeBuilder builder, IfMixin node) {
-    builder
-      ..ifMixin_condition = node.condition.accept(this)
-      ..ifMixin_elseKeyword = _getToken(node.elseKeyword)
-      ..ifMixin_ifKeyword = _getToken(node.ifKeyword)
-      ..ifMixin_leftParenthesis = _getToken(node.leftParenthesis)
-      ..ifMixin_rightParenthesis = _getToken(node.rightParenthesis);
-  }
-
   void _storeInheritsCovariant(LinkedNodeBuilder builder, AstNode node) {
     var value = LazyAst.getInheritsCovariant(node);
     builder.inheritsCovariant = value;
@@ -1531,7 +1577,9 @@
       LinkedNodeBuilder builder, NamedCompilationUnitMember node) {
     _storeCompilationUnitMember(builder, node);
     _storeCodeOffsetLength(builder, node);
-    builder..namedCompilationUnitMember_name = node.name.accept(this);
+    builder
+      ..name = node.name.name
+      ..nameOffset = node.name.offset;
   }
 
   void _storeNamespaceDirective(
@@ -1541,42 +1589,50 @@
       ..namespaceDirective_combinators = _writeNodeList(node.combinators)
       ..namespaceDirective_configurations = _writeNodeList(node.configurations)
       ..namespaceDirective_selectedUri = LazyDirective.getSelectedUri(node)
-      ..directive_semicolon = _getToken(node.semicolon);
+      ..nameOffset = node.offset;
   }
 
   void _storeNormalFormalParameter(
-      LinkedNodeBuilder builder, NormalFormalParameter node) {
+      LinkedNodeBuilder builder, NormalFormalParameter node, Token keyword) {
     _storeFormalParameter(builder, node);
     builder
       ..normalFormalParameter_comment = node.documentationComment?.accept(this)
-      ..normalFormalParameter_covariantKeyword =
-          _getToken(node.covariantKeyword)
-      ..normalFormalParameter_identifier = node.identifier?.accept(this)
-      ..normalFormalParameter_metadata = _writeNodeList(node.metadata)
-      ..normalFormalParameter_requiredKeyword = _getToken(node.requiredKeyword);
+      ..flags = AstBinaryFlags.encode(
+        isConst: keyword?.type == Keyword.CONST,
+        isCovariant: node.covariantKeyword != null,
+        isFinal: keyword?.type == Keyword.FINAL,
+        isRequired: node.requiredKeyword != null,
+        isVar: keyword?.type == Keyword.VAR,
+      )
+      ..name = node.identifier?.name
+      ..nameOffset = node.identifier?.offset ?? 0
+      ..normalFormalParameter_metadata = _writeNodeList(node.metadata);
   }
 
   void _storeStatement(LinkedNodeBuilder builder, Statement node) {}
 
   void _storeSwitchMember(LinkedNodeBuilder builder, SwitchMember node) {
-    builder.switchMember_colon = _getToken(node.colon);
-    builder.switchMember_keyword = _getToken(node.keyword);
     builder.switchMember_labels = _writeNodeList(node.labels);
     builder.switchMember_statements = _writeNodeList(node.statements);
   }
 
   void _storeTypeAlias(LinkedNodeBuilder builder, TypeAlias node) {
     _storeNamedCompilationUnitMember(builder, node);
-    builder
-      ..typeAlias_semicolon = _getToken(node.semicolon)
-      ..typeAlias_typedefKeyword = _getToken(node.typedefKeyword);
   }
 
-  void _storeTypedLiteral(LinkedNodeBuilder builder, TypedLiteral node) {
+  void _storeTypedLiteral(LinkedNodeBuilder builder, TypedLiteral node,
+      {bool isMap: false, bool isSet: false}) {
     _storeExpression(builder, node);
     builder
-      ..typedLiteral_constKeyword = _getToken(node.constKeyword)
-      ..typedLiteral_typeArguments = node.typeArguments?.accept(this);
+      ..flags = AstBinaryFlags.encode(
+        hasTypeArguments: node.typeArguments != null,
+        isConst: node.constKeyword != null,
+        isMap: isMap,
+        isSet: isSet,
+      )
+      ..typedLiteral_typeArguments = _writeNodeList(
+        node.typeArguments?.arguments,
+      );
   }
 
   void _storeUriBasedDirective(
@@ -1601,6 +1657,10 @@
   }
 
   List<LinkedNodeBuilder> _writeNodeList(List<AstNode> nodeList) {
+    if (nodeList == null) {
+      return const <LinkedNodeBuilder>[];
+    }
+
     var result = List<LinkedNodeBuilder>.filled(
       nodeList.length,
       null,
diff --git a/pkg/analyzer/lib/src/summary2/ast_resolver.dart b/pkg/analyzer/lib/src/summary2/ast_resolver.dart
index a98c541..1812c3e 100644
--- a/pkg/analyzer/lib/src/summary2/ast_resolver.dart
+++ b/pkg/analyzer/lib/src/summary2/ast_resolver.dart
@@ -30,7 +30,7 @@
 
     var typeResolverVisitor = new TypeResolverVisitor(
         _library, source, _linker.typeProvider, errorListener,
-        nameScope: _nameScope);
+        featureSet: featureSet, nameScope: _nameScope);
     node.accept(typeResolverVisitor);
 
     var variableResolverVisitor = new VariableResolverVisitor(
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 76261f8..c411c79 100644
--- a/pkg/analyzer/lib/src/summary2/builder/source_library_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/builder/source_library_builder.dart
@@ -33,7 +33,7 @@
   LinkedLibraryContext context;
 
   LibraryElementImpl element;
-  LibraryScope libraryScope;
+  LibraryScope scope;
 
   /// Local declarations.
   final Scope localScope = Scope.top();
@@ -74,7 +74,12 @@
         } else {
           var references = linker.elementFactory.exportsOfLibrary('$uri');
           for (var reference in references) {
-            export.addToExportScope(reference.name, reference);
+            var name = reference.name;
+            if (reference.isSetter) {
+              export.addToExportScope('$name=', reference);
+            } else {
+              export.addToExportScope(name, reference);
+            }
           }
         }
       }
@@ -169,28 +174,7 @@
     }
     if ('$uri' == 'dart:core') {
       localScope.declare('dynamic', reference.getChild('dynamic'));
-    }
-  }
-
-  void addSyntheticConstructors() {
-    for (var reference in localScope.map.values) {
-      var node = reference.node;
-      if (node == null) continue;
-      if (node.kind != LinkedNodeKind.classDeclaration) continue;
-
-      // Skip the class if it already has a constructor.
-      if (node.classOrMixinDeclaration_members
-          .any((n) => n.kind == LinkedNodeKind.constructorDeclaration)) {
-        continue;
-      }
-
-      node.classOrMixinDeclaration_members.add(
-        LinkedNodeBuilder.constructorDeclaration(
-          constructorDeclaration_parameters:
-              LinkedNodeBuilder.formalParameterList(),
-          constructorDeclaration_body: LinkedNodeBuilder.emptyFunctionBody(),
-        )..isSynthetic = true,
-      );
+      localScope.declare('Never', reference.getChild('Never'));
     }
   }
 
@@ -211,7 +195,7 @@
 
   void buildElement() {
     element = linker.elementFactory.libraryOfUri('$uri');
-    libraryScope = LibraryScope(element);
+    scope = LibraryScope(element);
   }
 
   void buildInitialExportScope() {
@@ -248,7 +232,7 @@
 
   void resolveMetadata() {
     for (CompilationUnitElementImpl unit in element.units) {
-      var resolver = MetadataResolver(linker, element, unit);
+      var resolver = MetadataResolver(linker, element, scope, unit);
       unit.linkedNode.accept(resolver);
     }
   }
@@ -258,13 +242,12 @@
       var unitRef = reference.getChild('@unit');
       var unitReference = unitRef.getChild(unitContext.uriStr);
       var resolver = ReferenceResolver(
-        linker.linkingBundleContext,
         nodesToBuildType,
         linker.elementFactory,
         element,
         unitReference,
         linker.contextFeatures.isEnabled(Feature.non_nullable),
-        libraryScope,
+        scope,
       );
       unitContext.unit.accept(resolver);
     }
diff --git a/pkg/analyzer/lib/src/summary2/combinator.dart b/pkg/analyzer/lib/src/summary2/combinator.dart
index 5d7b20e..96f1152 100644
--- a/pkg/analyzer/lib/src/summary2/combinator.dart
+++ b/pkg/analyzer/lib/src/summary2/combinator.dart
@@ -8,9 +8,16 @@
 
   Combinator(this.isShow, this.names);
 
-  Combinator.show(Iterable<String> names) : this(true, names.toSet());
-
   Combinator.hide(Iterable<String> names) : this(false, names.toSet());
 
+  Combinator.show(Iterable<String> names) : this(true, names.toSet());
+
   bool get isHide => !isShow;
+
+  bool matches(String name) {
+    if (name.endsWith('=')) {
+      name = name.substring(0, name.length - 1);
+    }
+    return names.contains(name);
+  }
 }
diff --git a/pkg/analyzer/lib/src/summary2/declaration_splicer.dart b/pkg/analyzer/lib/src/summary2/declaration_splicer.dart
deleted file mode 100644
index f562b51..0000000
--- a/pkg/analyzer/lib/src/summary2/declaration_splicer.dart
+++ /dev/null
@@ -1,593 +0,0 @@
-// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/src/dart/ast/ast.dart';
-import 'package:analyzer/src/dart/element/builder.dart';
-import 'package:analyzer/src/dart/element/element.dart';
-import 'package:analyzer/src/generated/resolver.dart';
-
-/// This class takes a [CompilationUnitElement] lazily resynthesized from a
-/// fully resolved, but partial AST (contains only APIs), and full unresolved
-/// AST - and splices them into a single AST with all declaration nodes
-/// fully resolved, and function bodies and variable initializers unresolved.
-///
-class DeclarationSplicer {
-  final CompilationUnitElementImpl _unitElement;
-
-  _ElementWalker _walker;
-
-  DeclarationSplicer(this._unitElement);
-
-  void splice(CompilationUnit full) {
-    var partialNode = _unitElement.linkedContext.readUnitEagerly();
-    _walk(_ElementWalker.forCompilationUnit(_unitElement), () {
-      _directives(full, partialNode);
-      _declarations(full, partialNode);
-    });
-  }
-
-  FunctionBody _body(FunctionBody full) {
-    _buildLocalElements(full);
-    return full;
-  }
-
-  void _buildLocalElements(AstNode node) {
-    if (node == null) return;
-
-    var holder = ElementHolder();
-    var elementBuilder = LocalElementBuilder(holder, _unitElement);
-    node.accept(elementBuilder);
-
-    ElementImpl element = _walker.element;
-    element.encloseElements(holder.functions);
-    element.encloseElements(holder.labels);
-    element.encloseElements(holder.localVariables);
-  }
-
-  void _classDeclaration(ClassDeclaration full, ClassDeclaration partial) {
-    var element = _walker.getClass();
-    _match(partial.name, element);
-    _walk(_ElementWalker.forClass(element), () {
-      _node(full.typeParameters, partial.typeParameters);
-      var fullList = full.members;
-      var partialList = partial.members;
-      for (var i = 0; i < fullList.length; ++i) {
-        _node(fullList[i], partialList[i]);
-      }
-    });
-    _metadata(partial.metadata, element);
-  }
-
-  void _classTypeAlias(ClassTypeAlias full, ClassTypeAlias partial) {
-    var element = _walker.getClass();
-    _match(partial.name, element);
-    _walk(_ElementWalker.forClass(element), () {
-      _node(full.typeParameters, partial.typeParameters);
-    });
-    _metadata(partial.metadata, element);
-  }
-
-  void _constructorDeclaration(
-    ConstructorDeclaration full,
-    ConstructorDeclaration partial,
-  ) {
-    var element = _walker.getConstructor();
-    _match(partial.name, element);
-    (partial as ConstructorDeclarationImpl).declaredElement = element;
-    _walk(_ElementWalker.forExecutable(element), () {
-      _formalParameterList(full.parameters, partial.parameters);
-      _constructorInitializers(full.initializers, partial.initializers);
-      partial.body = _body(full.body);
-    });
-    _metadata(partial.metadata, element);
-  }
-
-  void _constructorInitializers(
-    List<ConstructorInitializer> full,
-    List<ConstructorInitializer> partial,
-  ) {
-    if (full.isNotEmpty && partial.isEmpty) {
-      partial.addAll(full);
-    }
-    partial.forEach(_buildLocalElements);
-  }
-
-  void _declarations(CompilationUnit full, CompilationUnit partial) {
-    var fullList = full.declarations;
-    var partialList = partial.declarations;
-    for (var i = 0; i < fullList.length; ++i) {
-      var partialNode = _node(fullList[i], partialList[i]);
-      fullList[i] = partialNode;
-    }
-  }
-
-  void _directives(CompilationUnit full, CompilationUnit partial) {
-    var libraryElement = _unitElement.library;
-    var exportIndex = 0;
-    var importIndex = 0;
-    var partIndex = 0;
-    for (var directive in full.directives) {
-      if (directive is ExportDirective) {
-        var element = libraryElement.exports[exportIndex++];
-        _metadata(directive.metadata, element);
-      } else if (directive is ImportDirective) {
-        var element = libraryElement.imports[importIndex++];
-        _metadata(directive.metadata, element);
-      } else if (directive is LibraryDirective) {
-        var element = libraryElement;
-        _metadata(directive.metadata, element);
-      } else if (directive is PartDirective) {
-        var element = libraryElement.parts[partIndex++];
-        _metadata(directive.metadata, element);
-      }
-    }
-  }
-
-  void _enumConstantDeclaration(
-      EnumConstantDeclaration full, EnumConstantDeclaration partial) {
-    var element = _walker.getVariable();
-    _match(partial.name, element);
-    _metadata(partial.metadata, element);
-  }
-
-  void _enumDeclaration(EnumDeclaration full, EnumDeclaration partial) {
-    var element = _walker.getEnum();
-    _match(partial.name, element);
-    _walk(_ElementWalker.forClass(element), () {
-      var fullList = full.constants;
-      var partialList = partial.constants;
-      for (var i = 0; i < fullList.length; ++i) {
-        _node(fullList[i], partialList[i]);
-      }
-    });
-    _metadata(partial.metadata, element);
-  }
-
-  void _fieldDeclaration(FieldDeclaration full, FieldDeclaration partial) {
-    _node(full.fields, partial.fields);
-
-    var first = partial.fields.variables[0];
-    _metadata(partial.metadata, first.declaredElement);
-  }
-
-  void _fieldFormalParameter(
-    FieldFormalParameter full,
-    FieldFormalParameter partial,
-  ) {
-    var element = _walker.getParameter();
-    _match(partial.identifier, element);
-    _walk(_ElementWalker.forParameter(element), () {
-      _node(full.typeParameters, partial.typeParameters);
-      _node(full.parameters, partial.parameters);
-    });
-    _metadata(partial.metadata, element);
-  }
-
-  void _formalParameterList(
-    FormalParameterList full,
-    FormalParameterList partial,
-  ) {
-    var fullList = full.parameters;
-    var partialList = partial.parameters;
-    for (var i = 0; i < fullList.length; ++i) {
-      _node(fullList[i], partialList[i]);
-    }
-  }
-
-  void _functionDeclaration(
-    FunctionDeclaration full,
-    FunctionDeclaration partial,
-  ) {
-    var element = partial.propertyKeyword == null
-        ? _walker.getFunction()
-        : _walker.getAccessor();
-    _match(partial.name, element);
-    _walk(_ElementWalker.forExecutable(element), () {
-      _node(full.functionExpression, partial.functionExpression);
-    });
-    (partial.functionExpression as FunctionExpressionImpl).declaredElement =
-        element;
-    _metadata(partial.metadata, element);
-    _node(full.returnType, partial.returnType);
-  }
-
-  void _functionExpression(
-    FunctionExpression full,
-    FunctionExpression partial,
-  ) {
-    _node(full.typeParameters, partial.typeParameters);
-    _node(full.parameters, partial.parameters);
-    partial.body = _body(full.body);
-  }
-
-  void _functionTypeAlias(FunctionTypeAlias full, FunctionTypeAlias partial) {
-    var element = _walker.getTypedef();
-    _match(partial.name, element);
-    _walk(_ElementWalker.forGenericTypeAlias(element), () {
-      _node(full.typeParameters, partial.typeParameters);
-      _node(full.parameters, partial.parameters);
-    });
-    _metadata(partial.metadata, element);
-  }
-
-  void _functionTypedFormalParameter(
-    FunctionTypedFormalParameter full,
-    FunctionTypedFormalParameter partial,
-  ) {
-    var element = _walker.getParameter();
-    _match(partial.identifier, element);
-    _walk(_ElementWalker.forParameter(element), () {
-      _node(full.typeParameters, partial.typeParameters);
-      _node(full.parameters, partial.parameters);
-    });
-    _metadata(partial.metadata, element);
-  }
-
-  void _genericFunctionType(
-    GenericFunctionType full,
-    GenericFunctionType partial,
-  ) {
-    var element = (partial as GenericFunctionTypeImpl).declaredElement;
-    _walk(_ElementWalker.forGenericFunctionType(element), () {
-      _node(full.returnType, partial.returnType);
-      _node(full.typeParameters, partial.typeParameters);
-      _node(full.parameters, partial.parameters);
-    });
-  }
-
-  void _genericTypeAlias(GenericTypeAlias full, GenericTypeAlias partial) {
-    var element = _walker.getTypedef();
-    _match(partial.name, element);
-    _walk(_ElementWalker.forGenericTypeAlias(element), () {
-      _node(full.typeParameters, partial.typeParameters);
-      _node(full.functionType, partial.functionType);
-    });
-    _metadata(partial.metadata, element);
-  }
-
-  /// Updates [node] to point to [element], after ensuring that the
-  /// element has the expected name.
-  E _match<E extends Element>(SimpleIdentifier node, E element) {
-    // TODO(scheglov) has troubles with getter/setter.
-//    if (element.name != node.name) {
-//      throw new StateError(
-//        'Expected an element matching `${node.name}`, got `${element.name}`',
-//      );
-//    }
-    if (node != null) {
-      node.staticElement = element;
-    }
-    return element;
-  }
-
-  /// Associate [nodes] with the corresponding [ElementAnnotation]s.
-  void _metadata(List<Annotation> nodes, Element element) {
-    var elements = element.metadata;
-    if (nodes.length != elements.length) {
-      throw StateError('Found ${nodes.length} annotation nodes and '
-          '${elements.length} element annotations');
-    }
-    for (var i = 0; i < nodes.length; i++) {
-      var node = nodes[i];
-      node.elementAnnotation = elements[i];
-      _buildLocalElements(node);
-    }
-  }
-
-  void _methodDeclaration(MethodDeclaration full, MethodDeclaration partial) {
-    var element = partial.propertyKeyword == null
-        ? _walker.getFunction()
-        : _walker.getAccessor();
-    _match(partial.name, element);
-    _walk(_ElementWalker.forExecutable(element), () {
-      _node(full.typeParameters, partial.typeParameters);
-      _node(full.parameters, partial.parameters);
-      partial.body = _body(full.body);
-    });
-    _metadata(partial.metadata, element);
-    _node(full.returnType, partial.returnType);
-  }
-
-  void _mixinDeclaration(MixinDeclaration full, MixinDeclaration partial) {
-    var element = _walker.getMixin();
-    _match(partial.name, element);
-    _walk(_ElementWalker.forClass(element), () {
-      _node(full.typeParameters, partial.typeParameters);
-      var fullList = full.members;
-      var partialList = partial.members;
-      for (var i = 0; i < fullList.length; ++i) {
-        _node(fullList[i], partialList[i]);
-      }
-    });
-    _metadata(partial.metadata, element);
-  }
-
-  AstNode _node(AstNode full, AstNode partial) {
-    if (full == null && partial == null) {
-      return partial;
-    } else if (full is ClassDeclaration && partial is ClassDeclaration) {
-      _classDeclaration(full, partial);
-      return partial;
-    } else if (full is ClassTypeAlias && partial is ClassTypeAlias) {
-      _classTypeAlias(full, partial);
-      return partial;
-    } else if (full is ConstructorDeclaration &&
-        partial is ConstructorDeclaration) {
-      _constructorDeclaration(full, partial);
-      return partial;
-    } else if (full is DefaultFormalParameter &&
-        partial is DefaultFormalParameter) {
-      _node(full.parameter, partial.parameter);
-      return partial;
-    } else if (full is EnumConstantDeclaration &&
-        partial is EnumConstantDeclaration) {
-      _enumConstantDeclaration(full, partial);
-      return partial;
-    } else if (full is EnumDeclaration && partial is EnumDeclaration) {
-      _enumDeclaration(full, partial);
-      return partial;
-    } else if (full is FieldDeclaration && partial is FieldDeclaration) {
-      _fieldDeclaration(full, partial);
-      return partial;
-    } else if (full is FieldFormalParameter &&
-        partial is FieldFormalParameter) {
-      _fieldFormalParameter(full, partial);
-      return partial;
-    } else if (full is FormalParameterList && partial is FormalParameterList) {
-      _formalParameterList(full, partial);
-      return partial;
-    } else if (full is FunctionDeclaration && partial is FunctionDeclaration) {
-      _functionDeclaration(full, partial);
-      return partial;
-    } else if (full is FunctionExpression && partial is FunctionExpression) {
-      _functionExpression(full, partial);
-      return partial;
-    } else if (full is FunctionTypedFormalParameter &&
-        partial is FunctionTypedFormalParameter) {
-      _functionTypedFormalParameter(full, partial);
-      return partial;
-    } else if (full is FunctionTypeAlias && partial is FunctionTypeAlias) {
-      _functionTypeAlias(full, partial);
-      return partial;
-    } else if (full is GenericFunctionType && partial is GenericFunctionType) {
-      _genericFunctionType(full, partial);
-      return partial;
-    } else if (full is GenericTypeAlias && partial is GenericTypeAlias) {
-      _genericTypeAlias(full, partial);
-      return partial;
-    } else if (full is MethodDeclaration && partial is MethodDeclaration) {
-      _methodDeclaration(full, partial);
-      return partial;
-    } else if (full is MixinDeclaration && partial is MixinDeclaration) {
-      _mixinDeclaration(full, partial);
-      return partial;
-    } else if (full is SimpleFormalParameter &&
-        partial is SimpleFormalParameter) {
-      _simpleFormalParameter(full, partial);
-      return partial;
-    } else if (full is TopLevelVariableDeclaration &&
-        partial is TopLevelVariableDeclaration) {
-      _topLevelVariableDeclaration(full, partial);
-      return partial;
-    } else if (full is TypeName && partial is TypeName) {
-      _typeName(full, partial);
-      return partial;
-    } else if (full is TypeParameter && partial is TypeParameter) {
-      _typeParameter(full, partial);
-      return partial;
-    } else if (full is TypeParameterList && partial is TypeParameterList) {
-      _typeParameterList(full, partial);
-      return partial;
-    } else if (full is VariableDeclaration && partial is VariableDeclaration) {
-      _variableDeclaration(full, partial);
-      return partial;
-    } else if (full is VariableDeclarationList &&
-        partial is VariableDeclarationList) {
-      _variableDeclarationList(full, partial);
-      return partial;
-    } else {
-      throw UnimplementedError(
-        '${full.runtimeType} and ${partial.runtimeType}',
-      );
-    }
-  }
-
-  void _simpleFormalParameter(
-    SimpleFormalParameter full,
-    SimpleFormalParameter partial,
-  ) {
-    var element = _walker.getParameter();
-    _match(partial.identifier, element);
-    (partial as SimpleFormalParameterImpl).declaredElement = element;
-    _metadata(partial.metadata, element);
-    _node(full.type, partial.type);
-  }
-
-  void _topLevelVariableDeclaration(
-    TopLevelVariableDeclaration full,
-    TopLevelVariableDeclaration partial,
-  ) {
-    _node(full.variables, partial.variables);
-
-    var first = partial.variables.variables[0];
-    _metadata(partial.metadata, first.declaredElement);
-  }
-
-  void _typeName(TypeName full, TypeName partial) {
-    var fullList = full.typeArguments?.arguments;
-    var partialList = partial.typeArguments?.arguments;
-    if (fullList != null && partialList != null) {
-      for (var i = 0; i < fullList.length; ++i) {
-        _node(fullList[i], partialList[i]);
-      }
-    }
-  }
-
-  void _typeParameter(TypeParameter full, TypeParameter partial) {
-    var element = _walker.getTypeParameter();
-    _match(partial.name, element);
-    _node(full.bound, partial.bound);
-    _metadata(partial.metadata, element);
-  }
-
-  void _typeParameterList(TypeParameterList full, TypeParameterList partial) {
-    var fullList = full.typeParameters;
-    var partialList = partial.typeParameters;
-    for (var i = 0; i < fullList.length; ++i) {
-      _node(fullList[i], partialList[i]);
-    }
-  }
-
-  void _variableDeclaration(
-    VariableDeclaration full,
-    VariableDeclaration partial,
-  ) {
-    var element = _walker.getVariable();
-    _match(partial.name, element);
-    _walk(_ElementWalker.forVariable(element), () {
-      partial.initializer = full.initializer;
-      _buildLocalElements(partial.initializer);
-    });
-  }
-
-  void _variableDeclarationList(
-    VariableDeclarationList full,
-    VariableDeclarationList partial,
-  ) {
-    _node(full.type, partial.type);
-
-    var fullList = full.variables;
-    var partialList = partial.variables;
-    for (var i = 0; i < fullList.length; ++i) {
-      _node(fullList[i], partialList[i]);
-    }
-  }
-
-  void _walk(_ElementWalker walker, void f()) {
-    var outer = _walker;
-    _walker = walker;
-    f();
-    _walker = outer;
-  }
-}
-
-class _ElementWalker {
-  final Element element;
-
-  List<PropertyAccessorElement> _accessors;
-  int _accessorIndex = 0;
-
-  List<ClassElement> _classes;
-  int _classIndex = 0;
-
-  List<ConstructorElement> _constructors;
-  int _constructorIndex = 0;
-
-  List<ClassElement> _enums;
-  int _enumIndex = 0;
-
-  List<ExecutableElement> _functions;
-  int _functionIndex = 0;
-
-  List<ClassElement> _mixins;
-  int _mixinIndex = 0;
-
-  List<ParameterElement> _parameters;
-  int _parameterIndex = 0;
-
-  List<FunctionTypeAliasElement> _typedefs;
-  int _typedefIndex = 0;
-
-  List<TypeParameterElement> _typeParameters;
-  int _typeParameterIndex = 0;
-
-  List<VariableElement> _variables;
-  int _variableIndex = 0;
-
-  _ElementWalker.forClass(ClassElement element)
-      : element = element,
-        _accessors = element.accessors.where(_isNotSynthetic).toList(),
-        _constructors = element.isMixinApplication
-            ? null
-            : element.constructors.where(_isNotSynthetic).toList(),
-        _functions = element.methods,
-        _typeParameters = element.typeParameters,
-        _variables = element.fields.where(_isNotSynthetic).toList();
-
-  _ElementWalker.forCompilationUnit(CompilationUnitElement element)
-      : element = element,
-        _accessors = element.accessors.where(_isNotSynthetic).toList(),
-        _classes = element.types,
-        _enums = element.enums,
-        _functions = element.functions,
-        _mixins = element.mixins,
-        _typedefs = element.functionTypeAliases,
-        _variables = element.topLevelVariables.where(_isNotSynthetic).toList();
-
-  _ElementWalker.forExecutable(ExecutableElement element)
-      : element = element,
-        _parameters = element.parameters,
-        _typeParameters = element.typeParameters;
-
-  _ElementWalker.forGenericFunctionType(GenericFunctionTypeElement element)
-      : element = element,
-        _parameters = element.parameters,
-        _typeParameters = element.typeParameters;
-
-  _ElementWalker.forGenericTypeAlias(FunctionTypeAliasElement element)
-      : element = element,
-        _parameters = element.parameters,
-        _typeParameters = element.typeParameters;
-
-  _ElementWalker.forParameter(ParameterElement element)
-      : element = element,
-        _parameters = element.parameters,
-        _typeParameters = element.typeParameters;
-
-  _ElementWalker.forVariable(VariableElement element) : element = element;
-
-  PropertyAccessorElement getAccessor() {
-    return _accessors[_accessorIndex++];
-  }
-
-  ClassElement getClass() {
-    return _classes[_classIndex++];
-  }
-
-  ConstructorElement getConstructor() {
-    return _constructors[_constructorIndex++];
-  }
-
-  ClassElement getEnum() {
-    return _enums[_enumIndex++];
-  }
-
-  ExecutableElement getFunction() {
-    return _functions[_functionIndex++];
-  }
-
-  ClassElement getMixin() {
-    return _mixins[_mixinIndex++];
-  }
-
-  ParameterElement getParameter() {
-    return _parameters[_parameterIndex++];
-  }
-
-  FunctionTypeAliasElement getTypedef() {
-    return _typedefs[_typedefIndex++];
-  }
-
-  TypeParameterElement getTypeParameter() {
-    return _typeParameters[_typeParameterIndex++];
-  }
-
-  VariableElement getVariable() {
-    return _variables[_variableIndex++];
-  }
-
-  static bool _isNotSynthetic(Element e) => !e.isSynthetic;
-}
diff --git a/pkg/analyzer/lib/src/summary2/export.dart b/pkg/analyzer/lib/src/summary2/export.dart
index 63a1365..18247c3 100644
--- a/pkg/analyzer/lib/src/summary2/export.dart
+++ b/pkg/analyzer/lib/src/summary2/export.dart
@@ -16,8 +16,8 @@
   bool addToExportScope(String name, Reference reference) {
     if (combinators != null) {
       for (Combinator combinator in combinators) {
-        if (combinator.isShow && !combinator.names.contains(name)) return false;
-        if (combinator.isHide && combinator.names.contains(name)) return false;
+        if (combinator.isShow && !combinator.matches(name)) return false;
+        if (combinator.isHide && combinator.matches(name)) return false;
       }
     }
     return exporter.addToExportScope(name, reference);
diff --git a/pkg/analyzer/lib/src/summary2/function_type_builder.dart b/pkg/analyzer/lib/src/summary2/function_type_builder.dart
index 39425e6..2cec063 100644
--- a/pkg/analyzer/lib/src/summary2/function_type_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/function_type_builder.dart
@@ -45,7 +45,7 @@
   ) {
     return FunctionTypeBuilder(
       node.typeParameters?.typeParameters
-              ?.map((n) => n.declaredElement as TypeParameterElement)
+              ?.map((n) => n.declaredElement)
               ?.toList() ??
           [],
       node.parameters.parameters.map((n) {
diff --git a/pkg/analyzer/lib/src/summary2/lazy_ast.dart b/pkg/analyzer/lib/src/summary2/lazy_ast.dart
index 9f7fd21..13d6511 100644
--- a/pkg/analyzer/lib/src/summary2/lazy_ast.dart
+++ b/pkg/analyzer/lib/src/summary2/lazy_ast.dart
@@ -7,6 +7,7 @@
 import 'package:analyzer/src/dart/ast/ast.dart';
 import 'package:analyzer/src/summary/format.dart';
 import 'package:analyzer/src/summary/idl.dart';
+import 'package:analyzer/src/summary2/ast_binary_flags.dart';
 import 'package:analyzer/src/summary2/ast_binary_reader.dart';
 
 /// Accessor for reading AST lazily, or read data that is stored in IDL, but
@@ -109,6 +110,28 @@
     return node.getProperty(_key);
   }
 
+  static int getCodeLength(
+    AstBinaryReader reader,
+    ClassDeclaration node,
+  ) {
+    if (reader.isLazy) {
+      var lazy = get(node);
+      return lazy.data.codeLength;
+    }
+    return node.length;
+  }
+
+  static int getCodeOffset(
+    AstBinaryReader reader,
+    ClassDeclaration node,
+  ) {
+    if (reader.isLazy) {
+      var lazy = get(node);
+      return lazy.data.codeOffset;
+    }
+    return node.offset;
+  }
+
   static void readDocumentationComment(
     AstBinaryReader reader,
     ClassDeclaration node,
@@ -214,6 +237,28 @@
     return node.getProperty(_key);
   }
 
+  static int getCodeLength(
+    AstBinaryReader reader,
+    ClassTypeAlias node,
+  ) {
+    if (reader.isLazy) {
+      var lazy = get(node);
+      return lazy.data.codeLength;
+    }
+    return node.length;
+  }
+
+  static int getCodeOffset(
+    AstBinaryReader reader,
+    ClassTypeAlias node,
+  ) {
+    if (reader.isLazy) {
+      var lazy = get(node);
+      return lazy.data.codeOffset;
+    }
+    return node.offset;
+  }
+
   static void readDocumentationComment(
     AstBinaryReader reader,
     ClassTypeAlias node,
@@ -289,6 +334,44 @@
   }
 }
 
+class LazyCompilationUnit {
+  static const _key = 'lazyAst';
+
+  final LinkedNode data;
+
+  LazyCompilationUnit(this.data);
+
+  static LazyCompilationUnit get(CompilationUnit node) {
+    return node.getProperty(_key);
+  }
+
+  static int getCodeLength(
+    AstBinaryReader reader,
+    CompilationUnit node,
+  ) {
+    if (reader.isLazy) {
+      var lazy = get(node);
+      return lazy.data.codeLength;
+    }
+    return node.length;
+  }
+
+  static int getCodeOffset(
+    AstBinaryReader reader,
+    CompilationUnit node,
+  ) {
+    if (reader.isLazy) {
+      var lazy = get(node);
+      return lazy.data.codeOffset;
+    }
+    return node.offset;
+  }
+
+  static void setData(CompilationUnit node, LinkedNode data) {
+    node.setProperty(_key, LazyCompilationUnit(data));
+  }
+}
+
 class LazyConstructorDeclaration {
   static const _key = 'lazyAst';
 
@@ -307,6 +390,28 @@
     return node.getProperty(_key);
   }
 
+  static int getCodeLength(
+    AstBinaryReader reader,
+    ConstructorDeclaration node,
+  ) {
+    if (reader.isLazy) {
+      var lazy = get(node);
+      return lazy.data.codeLength;
+    }
+    return node.length;
+  }
+
+  static int getCodeOffset(
+    AstBinaryReader reader,
+    ConstructorDeclaration node,
+  ) {
+    if (reader.isLazy) {
+      var lazy = get(node);
+      return lazy.data.codeOffset;
+    }
+    return node.offset;
+  }
+
   static void readBody(
     AstBinaryReader reader,
     ConstructorDeclaration node,
@@ -408,6 +513,15 @@
     return node.getProperty(_key);
   }
 
+  static int getNameOffset(Directive node) {
+    var lazy = get(node);
+    if (lazy != null) {
+      return lazy.data.nameOffset;
+    } else {
+      return node.offset;
+    }
+  }
+
   static String getSelectedUri(UriBasedDirective node) {
     return node.getProperty(_uriKey);
   }
@@ -498,6 +612,28 @@
     return node.getProperty(_key);
   }
 
+  static int getCodeLength(
+    AstBinaryReader reader,
+    EnumDeclaration node,
+  ) {
+    if (reader.isLazy) {
+      var lazy = get(node);
+      return lazy.data.codeLength;
+    }
+    return node.length;
+  }
+
+  static int getCodeOffset(
+    AstBinaryReader reader,
+    EnumDeclaration node,
+  ) {
+    if (reader.isLazy) {
+      var lazy = get(node);
+      return lazy.data.codeOffset;
+    }
+    return node.offset;
+  }
+
   static void readConstants(
     AstBinaryReader reader,
     EnumDeclaration node,
@@ -611,6 +747,28 @@
     return node.getProperty(_key);
   }
 
+  static int getCodeLength(
+    AstBinaryReader reader,
+    FormalParameter node,
+  ) {
+    if (reader.isLazy) {
+      var lazy = get(node);
+      return lazy.data.codeLength;
+    }
+    return node.length;
+  }
+
+  static int getCodeOffset(
+    AstBinaryReader reader,
+    FormalParameter node,
+  ) {
+    if (reader.isLazy) {
+      var lazy = get(node);
+      return lazy.data.codeOffset;
+    }
+    return node.offset;
+  }
+
   static DartType getType(
     AstBinaryReader reader,
     FormalParameter node,
@@ -628,7 +786,7 @@
 
   static TopLevelInferenceError getTypeInferenceError(FormalParameter node) {
     var lazy = get(node);
-    if (!lazy._hasTypeInferenceError) {
+    if (lazy != null && !lazy._hasTypeInferenceError) {
       var error = lazy.data.topLevelTypeInferenceError;
       LazyAst.setTypeInferenceError(node, error);
       lazy._hasTypeInferenceError = true;
@@ -636,6 +794,15 @@
     return LazyAst.getTypeInferenceError(node);
   }
 
+  static bool hasDefaultValue(DefaultFormalParameter node) {
+    var lazy = LazyFormalParameter.get(node);
+    if (lazy != null) {
+      return AstBinaryFlags.hasInitializer(lazy.data.flags);
+    } else {
+      return node.defaultValue != null;
+    }
+  }
+
   static void readDefaultValue(
     AstBinaryReader reader,
     DefaultFormalParameter node,
@@ -723,6 +890,28 @@
     return node.getProperty(_key);
   }
 
+  static int getCodeLength(
+    AstBinaryReader reader,
+    FunctionDeclaration node,
+  ) {
+    if (reader.isLazy) {
+      var lazy = get(node);
+      return lazy.data.codeLength;
+    }
+    return node.length;
+  }
+
+  static int getCodeOffset(
+    AstBinaryReader reader,
+    FunctionDeclaration node,
+  ) {
+    if (reader.isLazy) {
+      var lazy = get(node);
+      return lazy.data.codeOffset;
+    }
+    return node.offset;
+  }
+
   static DartType getReturnType(
     AstBinaryReader reader,
     FunctionDeclaration node,
@@ -811,6 +1000,24 @@
     return node.getProperty(_key);
   }
 
+  static bool isAsynchronous(FunctionExpression node) {
+    var lazy = get(node);
+    if (lazy != null) {
+      return AstBinaryFlags.isAsync(lazy.data.flags);
+    } else {
+      return node.body.isAsynchronous;
+    }
+  }
+
+  static bool isGenerator(FunctionExpression node) {
+    var lazy = get(node);
+    if (lazy != null) {
+      return AstBinaryFlags.isGenerator(lazy.data.flags);
+    } else {
+      return node.body.isGenerator;
+    }
+  }
+
   static void readBody(
     AstBinaryReader reader,
     FunctionExpression node,
@@ -860,6 +1067,28 @@
     return node.getProperty(_key);
   }
 
+  static int getCodeLength(
+    AstBinaryReader reader,
+    FunctionTypeAlias node,
+  ) {
+    if (reader.isLazy) {
+      var lazy = get(node);
+      return lazy.data.codeLength;
+    }
+    return node.length;
+  }
+
+  static int getCodeOffset(
+    AstBinaryReader reader,
+    FunctionTypeAlias node,
+  ) {
+    if (reader.isLazy) {
+      var lazy = get(node);
+      return lazy.data.codeOffset;
+    }
+    return node.offset;
+  }
+
   static bool getHasSelfReference(FunctionTypeAlias node) {
     return node.getProperty(_hasSelfReferenceKey);
   }
@@ -943,67 +1172,6 @@
   }
 }
 
-class LazyGenericFunctionType {
-  static const _key = 'lazyAst';
-
-  final LinkedNode data;
-
-  bool _hasFormalParameters = false;
-  bool _hasReturnType = false;
-  bool _hasReturnTypeNode = 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 readReturnTypeNode(
-    AstBinaryReader reader,
-    GenericFunctionType node,
-  ) {
-    var lazy = get(node);
-    if (lazy != null && !lazy._hasReturnTypeNode) {
-      node.returnType = reader.readNode(
-        lazy.data.genericFunctionType_returnType,
-      );
-      lazy._hasReturnTypeNode = true;
-    }
-  }
-
-  static void setData(GenericFunctionType node, LinkedNode data) {
-    node.setProperty(_key, LazyGenericFunctionType(data));
-  }
-}
-
 class LazyGenericTypeAlias {
   static const _key = 'lazyAst';
   static const _hasSelfReferenceKey = 'lazyAst_hasSelfReferenceKey';
@@ -1020,6 +1188,28 @@
     return node.getProperty(_key);
   }
 
+  static int getCodeLength(
+    AstBinaryReader reader,
+    GenericTypeAlias node,
+  ) {
+    if (reader.isLazy) {
+      var lazy = get(node);
+      return lazy.data.codeLength;
+    }
+    return node.length;
+  }
+
+  static int getCodeOffset(
+    AstBinaryReader reader,
+    GenericTypeAlias node,
+  ) {
+    if (reader.isLazy) {
+      var lazy = get(node);
+      return lazy.data.codeOffset;
+    }
+    return node.offset;
+  }
+
   static bool getHasSelfReference(GenericTypeAlias node) {
     return node.getProperty(_hasSelfReferenceKey);
   }
@@ -1093,6 +1283,28 @@
     return node.getProperty(_key);
   }
 
+  static int getCodeLength(
+    AstBinaryReader reader,
+    MethodDeclaration node,
+  ) {
+    if (reader.isLazy) {
+      var lazy = get(node);
+      return lazy.data.codeLength;
+    }
+    return node.length;
+  }
+
+  static int getCodeOffset(
+    AstBinaryReader reader,
+    MethodDeclaration node,
+  ) {
+    if (reader.isLazy) {
+      var lazy = get(node);
+      return lazy.data.codeOffset;
+    }
+    return node.offset;
+  }
+
   static DartType getReturnType(
     AstBinaryReader reader,
     MethodDeclaration node,
@@ -1111,13 +1323,30 @@
   static bool isAbstract(MethodDeclaration node) {
     var lazy = get(node);
     if (lazy != null) {
-      return lazy.data.methodDeclaration_body.kind ==
-          LinkedNodeKind.emptyFunctionBody;
+      return AstBinaryFlags.isAbstract(lazy.data.flags);
     } else {
       return node.isAbstract;
     }
   }
 
+  static bool isAsynchronous(MethodDeclaration node) {
+    var lazy = get(node);
+    if (lazy != null) {
+      return AstBinaryFlags.isAsync(lazy.data.flags);
+    } else {
+      return node.body.isAsynchronous;
+    }
+  }
+
+  static bool isGenerator(MethodDeclaration node) {
+    var lazy = get(node);
+    if (lazy != null) {
+      return AstBinaryFlags.isGenerator(lazy.data.flags);
+    } else {
+      return node.body.isGenerator;
+    }
+  }
+
   static void readBody(
     AstBinaryReader reader,
     MethodDeclaration node,
@@ -1230,6 +1459,28 @@
     return lazy;
   }
 
+  static int getCodeLength(
+    AstBinaryReader reader,
+    MixinDeclaration node,
+  ) {
+    if (reader.isLazy) {
+      var lazy = get(node);
+      return lazy.data.codeLength;
+    }
+    return node.length;
+  }
+
+  static int getCodeOffset(
+    AstBinaryReader reader,
+    MixinDeclaration node,
+  ) {
+    if (reader.isLazy) {
+      var lazy = get(node);
+      return lazy.data.codeOffset;
+    }
+    return node.offset;
+  }
+
   static void readDocumentationComment(
     AstBinaryReader reader,
     MixinDeclaration node,
@@ -1362,6 +1613,28 @@
     return node.getProperty(_key);
   }
 
+  static int getCodeLength(
+    AstBinaryReader reader,
+    TypeParameter node,
+  ) {
+    if (reader.isLazy) {
+      var lazy = get(node);
+      return lazy.data.codeLength;
+    }
+    return node.length;
+  }
+
+  static int getCodeOffset(
+    AstBinaryReader reader,
+    TypeParameter node,
+  ) {
+    if (reader.isLazy) {
+      var lazy = get(node);
+      return lazy.data.codeOffset;
+    }
+    return node.offset;
+  }
+
   static DartType getDefaultType(AstBinaryReader reader, TypeParameter node) {
     var lazy = get(node);
     if (lazy != null && !lazy._hasDefaultType) {
@@ -1416,6 +1689,38 @@
     return node.getProperty(_key);
   }
 
+  static int getCodeLength(
+    AstBinaryReader reader,
+    VariableDeclaration node,
+  ) {
+    if (reader.isLazy) {
+      var lazy = get(node);
+      return lazy.data.codeLength;
+    }
+    VariableDeclarationList parent = node.parent;
+    if (parent.variables[0] == node) {
+      return node.end - parent.offset;
+    } else {
+      return node.end - node.offset;
+    }
+  }
+
+  static int getCodeOffset(
+    AstBinaryReader reader,
+    VariableDeclaration node,
+  ) {
+    if (reader.isLazy) {
+      var lazy = get(node);
+      return lazy.data.codeOffset;
+    }
+    VariableDeclarationList parent = node.parent;
+    if (parent.variables[0] == node) {
+      return parent.offset;
+    } else {
+      return node.offset;
+    }
+  }
+
   static DartType getType(
     AstBinaryReader reader,
     VariableDeclaration node,
@@ -1434,7 +1739,7 @@
   static TopLevelInferenceError getTypeInferenceError(
       VariableDeclaration node) {
     var lazy = get(node);
-    if (!lazy._hasTypeInferenceError) {
+    if (lazy != null && !lazy._hasTypeInferenceError) {
       var error = lazy.data.topLevelTypeInferenceError;
       LazyAst.setTypeInferenceError(node, error);
       lazy._hasTypeInferenceError = true;
@@ -1442,6 +1747,15 @@
     return LazyAst.getTypeInferenceError(node);
   }
 
+  static bool hasInitializer(VariableDeclaration node) {
+    var lazy = get(node);
+    if (lazy != null) {
+      return AstBinaryFlags.hasInitializer(lazy.data.flags);
+    } else {
+      return node.initializer != null;
+    }
+  }
+
   static void readInitializer(
     AstBinaryReader reader,
     VariableDeclaration node,
diff --git a/pkg/analyzer/lib/src/summary2/link.dart b/pkg/analyzer/lib/src/summary2/link.dart
index 7ee0e37..e4f4f7b 100644
--- a/pkg/analyzer/lib/src/summary2/link.dart
+++ b/pkg/analyzer/lib/src/summary2/link.dart
@@ -2,10 +2,9 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'package:analyzer/dart/analysis/declared_variables.dart';
 import 'package:analyzer/dart/analysis/features.dart';
-import 'package:analyzer/dart/analysis/session.dart';
 import 'package:analyzer/dart/ast/ast.dart' show CompilationUnit;
-import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/inheritance_manager2.dart';
 import 'package:analyzer/src/generated/constant.dart';
@@ -14,7 +13,6 @@
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/type_system.dart';
 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';
@@ -27,23 +25,20 @@
 import 'package:analyzer/src/summary2/type_alias.dart';
 import 'package:analyzer/src/summary2/types_builder.dart';
 
+var timerLinkingLinkingBundle = Stopwatch();
+var timerLinkingRemoveBundle = Stopwatch();
+
 LinkResult link(
-  AnalysisOptions analysisOptions,
-  SourceFactory sourceFactory,
-  DeclaredVariables declaredVariables,
-  List<LinkedNodeBundle> inputBundles,
+  LinkedElementFactory elementFactory,
   List<LinkInputLibrary> inputLibraries,
 ) {
-  var linker = Linker(analysisOptions, sourceFactory, declaredVariables);
-  linker.link(inputBundles, inputLibraries);
+  var linker = Linker(elementFactory);
+  linker.link(inputLibraries);
   return LinkResult(linker.linkingBundle);
 }
 
 class Linker {
-  final DeclaredVariables declaredVariables;
-
-  final Reference rootReference = Reference.root();
-  LinkedElementFactory elementFactory;
+  final LinkedElementFactory elementFactory;
 
   LinkedNodeBundleBuilder linkingBundle;
   LinkedBundleContext bundleContext;
@@ -52,49 +47,41 @@
   /// Libraries that are being linked.
   final Map<Uri, SourceLibraryBuilder> builders = {};
 
-  _AnalysisContextForLinking analysisContext;
-  TypeProvider typeProvider;
-  Dart2TypeSystem typeSystem;
-  InheritanceManager2 inheritance;
+  InheritanceManager2 inheritance; // TODO(scheglov) cache it
 
-  Linker(
-    AnalysisOptions analysisOptions,
-    SourceFactory sourceFactory,
-    this.declaredVariables,
-  ) {
+  Linker(this.elementFactory) {
     var dynamicRef = rootReference.getChild('dart:core').getChild('dynamic');
     dynamicRef.element = DynamicElementImpl.instance;
+    var neverRef = rootReference.getChild('dart:core').getChild('Never');
+    neverRef.element = NeverElementImpl.instance;
 
     linkingBundleContext = LinkingBundleContext(dynamicRef);
 
-    analysisContext = _AnalysisContextForLinking(
-      analysisOptions,
-      sourceFactory,
-    );
-
-    elementFactory = LinkedElementFactory(
-      analysisContext,
-      _AnalysisSessionForLinking(),
-      rootReference,
-    );
-
     bundleContext = LinkedBundleContext.forAst(
       elementFactory,
       linkingBundleContext.references,
     );
   }
 
+  InternalAnalysisContext get analysisContext {
+    return elementFactory.analysisContext;
+  }
+
   FeatureSet get contextFeatures {
     return analysisContext.analysisOptions.contextFeatures;
   }
 
-  void link(List<LinkedNodeBundle> inputBundles,
-      List<LinkInputLibrary> inputLibraries) {
-    for (var input in inputBundles) {
-      var inputBundleContext = LinkedBundleContext(elementFactory, input);
-      elementFactory.addBundle(inputBundleContext);
-    }
+  DeclaredVariables get declaredVariables {
+    return analysisContext.declaredVariables;
+  }
 
+  Reference get rootReference => elementFactory.rootReference;
+
+  TypeProvider get typeProvider => analysisContext.typeProvider;
+
+  Dart2TypeSystem get typeSystem => analysisContext.typeSystem;
+
+  void link(List<LinkInputLibrary> inputLibraries) {
     for (var inputLibrary in inputLibraries) {
       SourceLibraryBuilder.build(this, inputLibrary);
     }
@@ -103,19 +90,19 @@
 
     _buildOutlines();
 
+    timerLinkingLinkingBundle.start();
     _createLinkingBundle();
-  }
+    timerLinkingLinkingBundle.stop();
 
-  void _addSyntheticConstructors() {
-    for (var library in builders.values) {
-      library.addSyntheticConstructors();
-    }
+    timerLinkingRemoveBundle.start();
+    linkingBundleContext.clearIndexes();
+    elementFactory.removeBundle(bundleContext);
+    timerLinkingRemoveBundle.stop();
   }
 
   void _buildOutlines() {
     _resolveUriDirectives();
     _computeLibraryScopes();
-    _addSyntheticConstructors();
     _createTypeSystem();
     _resolveTypes();
     TypeAliasSelfReferenceFinder().perform(this);
@@ -201,14 +188,15 @@
         var unit = unitContext.unit;
 
         var writer = AstBinaryWriter(linkingBundleContext);
-        var unitLinkedNode = writer.writeNode(unit);
+        var unitLinkedNode = writer.writeUnit(unit);
         builder.node.units.add(
           LinkedNodeUnitBuilder(
             isSynthetic: unitContext.isSynthetic,
             uriStr: unitContext.uriStr,
             lineStarts: unit.lineInfo.lineStarts,
-            tokens: writer.tokensBuilder,
             node: unitLinkedNode,
+            isNNBD: unit.featureSet.isEnabled(Feature.non_nullable),
+            genericFunctionTypes: writer.genericFunctionTypes,
           ),
         );
       }
@@ -226,19 +214,17 @@
   }
 
   void _createTypeSystem() {
-    var coreRef = rootReference.getChild('dart:core');
-    var coreLib = elementFactory.elementOfReference(coreRef);
+    if (typeProvider != null) {
+      inheritance = InheritanceManager2(typeSystem);
+      return;
+    }
 
-    var asyncRef = rootReference.getChild('dart:async');
-    var asyncLib = elementFactory.elementOfReference(asyncRef);
+    var coreLib = elementFactory.libraryOfUri('dart:core');
+    var asyncLib = elementFactory.libraryOfUri('dart:async');
 
-    typeProvider = SummaryTypeProvider()
+    analysisContext.typeProvider = SummaryTypeProvider()
       ..initializeCore(coreLib)
       ..initializeAsync(asyncLib);
-    analysisContext.typeProvider = typeProvider;
-
-    typeSystem = Dart2TypeSystem(typeProvider);
-    analysisContext.typeSystem = typeSystem;
 
     inheritance = InheritanceManager2(typeSystem);
   }
@@ -305,32 +291,3 @@
 
   LinkResult(this.bundle);
 }
-
-class _AnalysisContextForLinking implements InternalAnalysisContext {
-  @override
-  final AnalysisOptions analysisOptions;
-
-  @override
-  final SourceFactory sourceFactory;
-
-  @override
-  TypeProvider typeProvider;
-
-  @override
-  TypeSystem typeSystem;
-
-  _AnalysisContextForLinking(this.analysisOptions, this.sourceFactory);
-
-  @override
-  Namespace getPublicNamespace(LibraryElement library) {
-    // TODO(scheglov) Not sure if this method of AnalysisContext is useful.
-    var builder = new NamespaceBuilder();
-    return builder.createPublicNamespaceForLibrary(library);
-  }
-
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
-
-class _AnalysisSessionForLinking implements AnalysisSession {
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
diff --git a/pkg/analyzer/lib/src/summary2/linked_element_factory.dart b/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
index 37c4ef9..94fef40a 100644
--- a/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
+++ b/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
@@ -5,6 +5,7 @@
 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/ast/ast.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/resolver/scope.dart';
 import 'package:analyzer/src/generated/engine.dart' show AnalysisContext;
@@ -28,6 +29,10 @@
     return _coreTypes ??= CoreTypes(this);
   }
 
+  bool get hasDartCore {
+    return libraryMap.containsKey('dart:core');
+  }
+
   void addBundle(LinkedBundleContext context) {
     libraryMap.addAll(context.libraryMap);
   }
@@ -78,6 +83,15 @@
     var reference = rootReference.getChild(uriStr);
     return elementOfReference(reference);
   }
+
+  /// We have linked the bundle, and need to disconnect its libraries, so
+  /// that the client can re-add the bundle, this time read from bytes.
+  void removeBundle(LinkedBundleContext context) {
+    for (var uriStr in context.libraryMap.keys) {
+      libraryMap.remove(uriStr);
+      rootReference.removeChild(uriStr);
+    }
+  }
 }
 
 class _ElementRequest {
@@ -123,6 +137,14 @@
       return _function(enclosing, reference);
     }
 
+    if (parentName == '@genericFunctionType') {
+      CompilationUnitElementImpl enclosing = elementOfReference(parent2);
+      var context = enclosing.linkedContext;
+      var id = int.parse(reference.name);
+      GenericFunctionTypeImpl node = context.getGenericFunctionType(id);
+      return node.declaredElement as GenericFunctionTypeElementImpl;
+    }
+
     if (parentName == '@getter' || parentName == '@setter') {
       var enclosing = elementOfReference(parent2);
       return _accessor(enclosing, reference);
@@ -226,6 +248,9 @@
     if (librarySource == null) return null;
 
     var libraryContext = elementFactory.libraryMap[uriStr];
+    if (libraryContext == null) {
+      throw ArgumentError('Missing library: $uriStr');
+    }
     var libraryNode = libraryContext.node;
     var hasName = libraryNode.name.isNotEmpty;
 
diff --git a/pkg/analyzer/lib/src/summary2/linked_unit_context.dart b/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
index ac704b4..320f151 100644
--- a/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
+++ b/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
@@ -2,21 +2,21 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
-import 'package:analyzer/dart/element/visitor.dart';
 import 'package:analyzer/source/line_info.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/generated/resolver.dart';
 import 'package:analyzer/src/generated/utilities_dart.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 {
@@ -27,16 +27,16 @@
   final Reference reference;
   final bool isSynthetic;
   final LinkedNodeUnit data;
-  final TokensContext tokensContext;
+
+  /// This list is filled lazily with [GenericFunctionType] nodes as they
+  /// are requested by [getGenericFunctionType].
+  List<GenericFunctionType> _genericFunctionTypeNodeList;
 
   AstBinaryReader _astReader;
 
   CompilationUnit _unit;
   bool _hasDirectivesRead = false;
 
-  /// Mapping from identifiers to elements for generic function types.
-  final Map<int, GenericFunctionTypeElementImpl> _genericFunctionTypes = {};
-
   /// Mapping from identifiers to synthetic type parameters.
   ///
   /// Synthetic type parameters are added when [readType] begins reading a
@@ -53,25 +53,20 @@
       this.reference,
       this.isSynthetic,
       this.data,
-      {CompilationUnit unit})
-      : tokensContext = data != null ? TokensContext(data.tokens) : null {
+      {CompilationUnit unit}) {
     _astReader = AstBinaryReader(this);
     _astReader.isLazy = unit == null;
 
+    if (data != null) {
+      _genericFunctionTypeNodeList = List<GenericFunctionType>(
+        data.genericFunctionTypes.length,
+      );
+    }
+
     _unit = unit;
     _hasDirectivesRead = _unit != null;
   }
 
-  LinkedUnitContext._(
-      this.bundleContext,
-      this.libraryContext,
-      this.indexInLibrary,
-      this.uriStr,
-      this.reference,
-      this.isSynthetic,
-      this.data,
-      this.tokensContext);
-
   bool get hasPartOfDirective {
     for (var directive in unit_withDirectives.directives) {
       if (directive is PartOfDirective) {
@@ -84,12 +79,25 @@
   /// Return `true` if this unit is a part of a bundle that is being linked.
   bool get isLinking => bundleContext.isLinking;
 
+  bool get isNNBD {
+    if (data != null) return data.isNNBD;
+    return _unit.featureSet.isEnabled(Feature.non_nullable);
+  }
+
+  TypeProvider get typeProvider =>
+      bundleContext.elementFactory.analysisContext.typeProvider;
+
   CompilationUnit get unit => _unit;
 
   CompilationUnit get unit_withDeclarations {
     if (_unit == null) {
       _unit = _astReader.readNode(data.node);
-      _unit.lineInfo = LineInfo(data.lineStarts);
+
+      var lineStarts = data.lineStarts;
+      if (lineStarts.isEmpty) {
+        lineStarts = [0];
+      }
+      _unit.lineInfo = LineInfo(lineStarts);
     }
     return _unit;
   }
@@ -106,31 +114,6 @@
     return _unit;
   }
 
-  /// Every [GenericFunctionType] node has [GenericFunctionTypeElement], which
-  /// is created during reading of this node.
-  void addGenericFunctionType(int id, GenericFunctionTypeImpl node) {
-    if (this.reference == null) return;
-
-    LazyAst.setGenericFunctionTypeId(node, id);
-
-    var element = _genericFunctionTypes[id];
-    if (element == null) {
-      element = GenericFunctionTypeElementImpl.forLinkedNode(
-        this.reference.element,
-        null,
-        node,
-      );
-      _genericFunctionTypes[id] = element;
-    }
-
-    node.declaredElement = element;
-
-    var containerRef = this.reference.getChild('@genericFunctionType');
-    var reference = containerRef.getChild('$id');
-    reference.element = element;
-    element.reference = reference;
-  }
-
   /// Return the [LibraryElement] referenced in the [node].
   LibraryElement directiveLibrary(UriBasedDirective node) {
     var uriStr = LazyDirective.getSelectedUri(node);
@@ -140,74 +123,70 @@
 
   int getCodeLength(AstNode node) {
     if (node is ClassDeclaration) {
-      return LazyClassDeclaration.get(node).data.codeLength;
+      return LazyClassDeclaration.getCodeLength(_astReader, node);
     } else if (node is ClassTypeAlias) {
-      return LazyClassTypeAlias.get(node).data.codeLength;
+      return LazyClassTypeAlias.getCodeLength(_astReader, node);
     } else if (node is CompilationUnit) {
-      return data.node.codeLength;
+      if (data != null) {
+        return data.node.codeLength;
+      } else {
+        return node.length;
+      }
     } else if (node is ConstructorDeclaration) {
-      return LazyConstructorDeclaration.get(node).data.codeLength;
+      return LazyConstructorDeclaration.getCodeLength(_astReader, node);
     } else if (node is EnumDeclaration) {
-      return LazyEnumDeclaration.get(node).data.codeLength;
+      return LazyEnumDeclaration.getCodeLength(_astReader, node);
     } else if (node is FormalParameter) {
-      return LazyFormalParameter.get(node).data.codeLength;
+      return LazyFormalParameter.getCodeLength(_astReader, node);
     } else if (node is FunctionDeclaration) {
-      return LazyFunctionDeclaration.get(node).data.codeLength;
+      return LazyFunctionDeclaration.getCodeLength(_astReader, node);
     } else if (node is FunctionTypeAliasImpl) {
-      return LazyFunctionTypeAlias.get(node).data.codeLength;
+      return LazyFunctionTypeAlias.getCodeLength(_astReader, node);
     } else if (node is GenericTypeAlias) {
-      return LazyGenericTypeAlias.get(node).data.codeLength;
+      return LazyGenericTypeAlias.getCodeLength(_astReader, node);
     } else if (node is MethodDeclaration) {
-      return LazyMethodDeclaration.get(node).data.codeLength;
+      return LazyMethodDeclaration.getCodeLength(_astReader, node);
     } else if (node is MixinDeclaration) {
-      return LazyMixinDeclaration.get(node).data.codeLength;
+      return LazyMixinDeclaration.getCodeLength(_astReader, node);
     } else if (node is TypeParameter) {
-      return LazyTypeParameter.get(node).data.codeLength;
+      return LazyTypeParameter.getCodeLength(_astReader, node);
     } else if (node is VariableDeclaration) {
-      return LazyVariableDeclaration.get(node).data.codeLength;
+      return LazyVariableDeclaration.getCodeLength(_astReader, node);
     }
     throw UnimplementedError('${node.runtimeType}');
   }
 
   int getCodeOffset(AstNode node) {
     if (node is ClassDeclaration) {
-      return LazyClassDeclaration.get(node).data.codeOffset;
+      return LazyClassDeclaration.getCodeOffset(_astReader, node);
     } else if (node is ClassTypeAlias) {
-      return LazyClassTypeAlias.get(node).data.codeOffset;
+      return LazyClassTypeAlias.getCodeOffset(_astReader, node);
     } else if (node is CompilationUnit) {
-      return data.node.codeOffset;
+      return 0;
     } else if (node is ConstructorDeclaration) {
-      return LazyConstructorDeclaration.get(node).data.codeOffset;
+      return LazyConstructorDeclaration.getCodeOffset(_astReader, node);
     } else if (node is EnumDeclaration) {
-      return LazyEnumDeclaration.get(node).data.codeOffset;
+      return LazyEnumDeclaration.getCodeOffset(_astReader, node);
     } else if (node is FormalParameter) {
-      return LazyFormalParameter.get(node).data.codeOffset;
+      return LazyFormalParameter.getCodeOffset(_astReader, node);
     } else if (node is FunctionDeclaration) {
-      return LazyFunctionDeclaration.get(node).data.codeOffset;
+      return LazyFunctionDeclaration.getCodeOffset(_astReader, node);
     } else if (node is FunctionTypeAliasImpl) {
-      return LazyFunctionTypeAlias.get(node).data.codeOffset;
+      return LazyFunctionTypeAlias.getCodeOffset(_astReader, node);
     } else if (node is GenericTypeAlias) {
-      return LazyGenericTypeAlias.get(node).data.codeOffset;
+      return LazyGenericTypeAlias.getCodeOffset(_astReader, node);
     } else if (node is MethodDeclaration) {
-      return LazyMethodDeclaration.get(node).data.codeOffset;
+      return LazyMethodDeclaration.getCodeOffset(_astReader, node);
     } else if (node is MixinDeclaration) {
-      return LazyMixinDeclaration.get(node).data.codeOffset;
+      return LazyMixinDeclaration.getCodeOffset(_astReader, node);
     } else if (node is TypeParameter) {
-      return LazyTypeParameter.get(node).data.codeOffset;
+      return LazyTypeParameter.getCodeOffset(_astReader, node);
     } else if (node is VariableDeclaration) {
-      return LazyVariableDeclaration.get(node).data.codeOffset;
+      return LazyVariableDeclaration.getCodeOffset(_astReader, node);
     }
     throw UnimplementedError('${node.runtimeType}');
   }
 
-  String getConstructorDeclarationName(LinkedNode node) {
-    var name = node.constructorDeclaration_name;
-    if (name != null) {
-      return getSimpleName(name);
-    }
-    return '';
-  }
-
   List<ConstructorInitializer> getConstructorInitializers(
     ConstructorDeclaration node,
   ) {
@@ -244,8 +223,7 @@
   }
 
   int getDirectiveOffset(AstNode node) {
-    LazyDirective.readMetadata(_astReader, node);
-    return node.offset;
+    return LazyDirective.getNameOffset(node);
   }
 
   Comment getDocumentationComment(AstNode node) {
@@ -324,10 +302,6 @@
     }
   }
 
-  String getFormalParameterName(LinkedNode node) {
-    return getSimpleName(node.normalFormalParameter_identifier);
-  }
-
   List<FormalParameter> getFormalParameters(AstNode node) {
     if (node is ConstructorDeclaration) {
       LazyConstructorDeclaration.readFormalParameters(_astReader, node);
@@ -354,7 +328,6 @@
       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);
@@ -364,9 +337,32 @@
     }
   }
 
+  GenericFunctionTypeImpl getGenericFunctionType(int id) {
+    GenericFunctionTypeImpl node = _genericFunctionTypeNodeList[id];
+    if (node == null) {
+      var data = this.data.genericFunctionTypes[id];
+      node = _astReader.readGenericFunctionTypeShallow(data);
+      LazyAst.setGenericFunctionTypeId(node, id);
+      _genericFunctionTypeNodeList[id] = node;
+
+      var containerRef = this.reference.getChild('@genericFunctionType');
+      var reference = containerRef.getChild('$id');
+      var element = GenericFunctionTypeElementImpl.forLinkedNode(
+        this.reference.element,
+        reference,
+        node,
+      );
+      node.declaredElement = element;
+
+      _astReader.readGenericFunctionTypeFinish(data, node);
+    }
+    return node;
+  }
+
   Reference getGenericFunctionTypeReference(GenericFunctionType node) {
+    var containerRef = reference.getChild('@genericFunctionType');
     var id = LazyAst.getGenericFunctionTypeId(node);
-    return reference.getChild('@genericFunctionType').getChild('$id');
+    return containerRef.getChild('$id');
   }
 
   GenericFunctionType getGeneticTypeAliasFunction(GenericTypeAlias node) {
@@ -498,10 +494,6 @@
     return const <Annotation>[];
   }
 
-  String getMethodName(LinkedNode node) {
-    return getSimpleName(node.methodDeclaration_name);
-  }
-
   Iterable<MethodDeclaration> getMethods(AstNode node) sync* {
     if (node is ClassOrMixinDeclaration) {
       var members = _getClassOrMixinMembers(node);
@@ -552,7 +544,7 @@
     } else if (node is FunctionTypeAlias) {
       return LazyFunctionTypeAlias.getReturnType(_astReader, node);
     } else if (node is GenericFunctionType) {
-      return LazyGenericFunctionType.getReturnType(_astReader, node);
+      return node.returnType?.type ?? DynamicTypeImpl.instance;
     } else if (node is MethodDeclaration) {
       return LazyMethodDeclaration.getReturnType(_astReader, node);
     } else {
@@ -565,7 +557,6 @@
       LazyFunctionTypeAlias.readReturnTypeNode(_astReader, node);
       return node.returnType;
     } else if (node is GenericFunctionType) {
-      LazyGenericFunctionType.readReturnTypeNode(_astReader, node);
       return node.returnType;
     } else if (node is FunctionDeclaration) {
       LazyFunctionDeclaration.readReturnTypeNode(_astReader, node);
@@ -582,18 +573,6 @@
     return LazyDirective.getSelectedUri(node);
   }
 
-  String getSimpleName(LinkedNode node) {
-    return getTokenLexeme(node.simpleIdentifier_token);
-  }
-
-  List<String> getSimpleNameList(List<LinkedNode> nodeList) {
-    return nodeList.map(getSimpleName).toList();
-  }
-
-  int getSimpleOffset(LinkedNode node) {
-    return getTokenOffset(node.simpleIdentifier_token);
-  }
-
   String getStringContent(LinkedNode node) {
     return node.simpleStringLiteral_value;
   }
@@ -610,14 +589,6 @@
     }
   }
 
-  String getTokenLexeme(int token) {
-    return tokensContext.lexeme(token);
-  }
-
-  int getTokenOffset(int token) {
-    return tokensContext.offset(token);
-  }
-
   /// Return the actual type for the [node] - explicit or inferred.
   DartType getType(AstNode node) {
     if (node is DefaultFormalParameter) {
@@ -683,14 +654,6 @@
     }
   }
 
-  String getUnitMemberName(LinkedNode node) {
-    return getSimpleName(node.namedCompilationUnitMember_name);
-  }
-
-  String getVariableName(LinkedNode node) {
-    return getSimpleName(node.variableDeclaration_name);
-  }
-
   WithClause getWithClause(AstNode node) {
     if (node is ClassDeclaration) {
       LazyClassDeclaration.readWithClause(_astReader, node);
@@ -703,9 +666,16 @@
     }
   }
 
+  bool hasDefaultValue(FormalParameter node) {
+    if (node is DefaultFormalParameter) {
+      return LazyFormalParameter.hasDefaultValue(node);
+    }
+    return false;
+  }
+
   bool hasImplicitReturnType(AstNode node) {
     if (node is FunctionDeclaration) {
-      LazyFunctionDeclaration.readFunctionExpression(_astReader, node);
+      LazyFunctionDeclaration.readReturnTypeNode(_astReader, node);
       return node.returnType == null;
     }
     if (node is MethodDeclaration) {
@@ -728,6 +698,10 @@
     return false;
   }
 
+  bool hasInitializer(VariableDeclaration node) {
+    return LazyVariableDeclaration.hasInitializer(node);
+  }
+
   bool hasOverrideInferenceDone(AstNode node) {
     // Only nodes in the libraries being linked might be not inferred yet.
     if (_astReader.isLazy) return true;
@@ -749,12 +723,18 @@
   }
 
   bool isAsynchronous(AstNode node) {
-    var body = _getFunctionBody(node);
-    return body.isAsynchronous;
-  }
-
-  bool isAsyncKeyword(int token) {
-    return tokensContext.type(token) == UnlinkedTokenType.ASYNC;
+    if (node is ConstructorDeclaration) {
+      return false;
+    } else if (node is FunctionDeclaration) {
+      LazyFunctionDeclaration.readFunctionExpression(_astReader, node);
+      return isAsynchronous(node.functionExpression);
+    } else if (node is FunctionExpression) {
+      return LazyFunctionExpression.isAsynchronous(node);
+    } else if (node is MethodDeclaration) {
+      return LazyMethodDeclaration.isAsynchronous(node);
+    } else {
+      throw UnimplementedError('${node.runtimeType}');
+    }
   }
 
   bool isConst(AstNode node) {
@@ -768,14 +748,6 @@
     throw UnimplementedError('${node.runtimeType}');
   }
 
-  bool isConstKeyword(int token) {
-    return tokensContext.type(token) == UnlinkedTokenType.CONST;
-  }
-
-  bool isConstVariableList(LinkedNode node) {
-    return isConstKeyword(node.variableDeclarationList_keyword);
-  }
-
   bool isExplicitlyCovariant(AstNode node) {
     if (node is EnumConstantDeclaration) {
       return false;
@@ -812,21 +784,23 @@
     throw UnimplementedError('${node.runtimeType}');
   }
 
-  bool isFinalKeyword(int token) {
-    return tokensContext.type(token) == UnlinkedTokenType.FINAL;
-  }
-
-  bool isFinalVariableList(LinkedNode node) {
-    return isFinalKeyword(node.variableDeclarationList_keyword);
-  }
-
   bool isFunction(LinkedNode node) {
     return node.kind == LinkedNodeKind.functionDeclaration;
   }
 
   bool isGenerator(AstNode node) {
-    var body = _getFunctionBody(node);
-    return body.isGenerator;
+    if (node is ConstructorDeclaration) {
+      return false;
+    } else if (node is FunctionDeclaration) {
+      LazyFunctionDeclaration.readFunctionExpression(_astReader, node);
+      return isGenerator(node.functionExpression);
+    } else if (node is FunctionExpression) {
+      return LazyFunctionExpression.isGenerator(node);
+    } else if (node is MethodDeclaration) {
+      return LazyMethodDeclaration.isGenerator(node);
+    } else {
+      throw UnimplementedError('${node.runtimeType}');
+    }
   }
 
   bool isGetter(AstNode node) {
@@ -852,10 +826,6 @@
     throw UnimplementedError('${node.runtimeType}');
   }
 
-  bool isLibraryKeyword(int token) {
-    return tokensContext.type(token) == UnlinkedTokenType.LIBRARY;
-  }
-
   bool isMethod(LinkedNode node) {
     return node.kind == LinkedNodeKind.methodDeclaration;
   }
@@ -886,10 +856,6 @@
     throw UnimplementedError('${node.runtimeType}');
   }
 
-  bool isSyncKeyword(int token) {
-    return tokensContext.type(token) == UnlinkedTokenType.SYNC;
-  }
-
   Expression readInitializer(AstNode node) {
     if (node is DefaultFormalParameter) {
       LazyFormalParameter.readDefaultValue(_astReader, node);
@@ -979,35 +945,6 @@
     }
   }
 
-  /// Read new resolved [CompilationUnit] from the [data], and in contrast to
-  /// reading AST for element model, read it eagerly. We can do this, because
-  /// the element model is fully accessible, so we don't need to worry about
-  /// potential forward references.
-  ///
-  /// The new instance of [CompilationUnit] is required because the client of
-  /// this method is going to modify the unit - merge parsed, not yet resolved
-  /// function bodies into it, and resolve them.
-  CompilationUnit readUnitEagerly() {
-    reference.element.accept(
-      _TypeParameterReader(),
-    );
-    _RecursiveTypeReader(this).read(unit);
-
-    var context = LinkedUnitContext._(
-      bundleContext,
-      libraryContext,
-      indexInLibrary,
-      uriStr,
-      reference,
-      isSynthetic,
-      data,
-      TokensContext(data.tokens),
-    );
-    context._genericFunctionTypes.addAll(_genericFunctionTypes);
-    var astReader = AstBinaryReader(context);
-    return astReader.readNode(data.node);
-  }
-
   void setInheritsCovariant(AstNode node, bool value) {
     if (node is FormalParameter) {
       LazyAst.setInheritsCovariant(node, value);
@@ -1085,24 +1022,6 @@
     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}');
-    }
-  }
-
   NodeList<Annotation> _getPartDirectiveAnnotation() {
     var definingContext = libraryContext.definingUnit;
     var unit = definingContext.unit;
@@ -1160,95 +1079,3 @@
     }
   }
 }
-
-/// Ensure that all [GenericFunctionType] and [TypeParameter] nodes are read,
-/// so their elements are created and set in [Reference]s.
-class _RecursiveTypeReader {
-  final LinkedUnitContext context;
-
-  _RecursiveTypeReader(this.context);
-
-  void read(AstNode node) {
-    if (node == null) {
-    } else if (node is ClassDeclaration) {
-      _readTypeParameters(node);
-      node.members.forEach(read);
-    } else if (node is ClassTypeAlias) {
-      _readTypeParameters(node);
-    } else if (node is CompilationUnit) {
-      for (var declaration in node.declarations) {
-        read(declaration);
-      }
-    } else if (node is ConstructorDeclaration) {
-      _readFormalParameters(node);
-    } else if (node is EnumDeclaration) {
-    } else if (node is FieldDeclaration) {
-      read(node.fields);
-    } else if (node is FunctionDeclaration) {
-      _readTypeParameters(node);
-      _readFormalParameters(node);
-      _readReturnType(node);
-    } else if (node is FunctionTypeAlias) {
-      _readTypeParameters(node);
-      _readFormalParameters(node);
-      _readReturnType(node);
-    } else if (node is GenericFunctionType) {
-      _readTypeParameters(node);
-      _readFormalParameters(node);
-      _readReturnType(node);
-    } else if (node is GenericTypeAlias) {
-      _readTypeParameters(node);
-      LazyGenericTypeAlias.readFunctionType(context._astReader, node);
-      read(node.functionType);
-    } else if (node is MethodDeclaration) {
-      _readTypeParameters(node);
-      _readFormalParameters(node);
-      _readReturnType(node);
-    } else if (node is MixinDeclaration) {
-      _readTypeParameters(node);
-      node.members.forEach(read);
-    } else if (node is TopLevelVariableDeclaration) {
-      read(node.variables);
-    } else if (node is TypeName) {
-      node.typeArguments?.arguments?.forEach(read);
-    } else if (node is VariableDeclarationList) {
-      LazyVariableDeclarationList.readTypeNode(context._astReader, node);
-      read(node.type);
-    } else {
-      throw StateError('${node.runtimeType}');
-    }
-  }
-
-  void _readFormalParameters(AstNode node) {
-    var formalParameters = context.getFormalParameters(node);
-    if (formalParameters == null) return;
-
-    for (var formalParameter in formalParameters) {
-      if (formalParameter is SimpleFormalParameter) {
-        read(formalParameter.type);
-      }
-    }
-  }
-
-  void _readReturnType(AstNode node) {
-    var returnType = context.getReturnTypeNode(node);
-    read(returnType);
-  }
-
-  void _readTypeParameters(AstNode node) {
-    var typeParameters = context.getTypeParameters2(node);
-    if (typeParameters == null) return;
-
-    for (var typeParameter in typeParameters.typeParameters) {
-      var bound = context.getTypeParameterBound(typeParameter);
-      read(bound);
-    }
-  }
-}
-
-class _TypeParameterReader extends RecursiveElementVisitor<void> {
-  @override
-  void visitTypeParameterElement(TypeParameterElement element) {
-    super.visitTypeParameterElement(element);
-  }
-}
diff --git a/pkg/analyzer/lib/src/summary2/linking_bundle_context.dart b/pkg/analyzer/lib/src/summary2/linking_bundle_context.dart
index fd4148c..7a7c22d 100644
--- a/pkg/analyzer/lib/src/summary2/linking_bundle_context.dart
+++ b/pkg/analyzer/lib/src/summary2/linking_bundle_context.dart
@@ -32,14 +32,16 @@
   final Map<TypeParameterElement, int> _typeParameters = Map.identity();
   int _nextSyntheticTypeParameterId = 0x10000;
 
-  final Map<GenericFunctionTypeElement, int> _genericFunctionTypes =
-      Map.identity();
-  int _nextGenericFunctionTypeId = 1;
-
   LinkingBundleContext(this.dynamicReference);
 
-  int idOfGenericFunctionType(GenericFunctionTypeElement element) {
-    return _genericFunctionTypes[element];
+  /// We need indexes for references during linking, but once we are done,
+  /// we must clear indexes to make references ready for linking a next bundle.
+  void clearIndexes() {
+    for (var reference in references) {
+      if (reference != null) {
+        reference.index = null;
+      }
+    }
   }
 
   int idOfTypeParameter(TypeParameterElement element) {
@@ -72,10 +74,6 @@
     return reference.index;
   }
 
-  int nextGenericFunctionTypeId() {
-    return _nextGenericFunctionTypeId++;
-  }
-
   LinkedNodeTypeBuilder writeType(DartType type) {
     if (type == null) return null;
 
diff --git a/pkg/analyzer/lib/src/summary2/metadata_resolver.dart b/pkg/analyzer/lib/src/summary2/metadata_resolver.dart
index 7c9e52f..a9265e1 100644
--- a/pkg/analyzer/lib/src/summary2/metadata_resolver.dart
+++ b/pkg/analyzer/lib/src/summary2/metadata_resolver.dart
@@ -14,11 +14,11 @@
 class MetadataResolver extends ThrowingAstVisitor<void> {
   final Linker _linker;
   final LibraryElement _libraryElement;
+  final Scope _libraryScope;
   final CompilationUnitElement _unitElement;
 
-  Scope scope;
-
-  MetadataResolver(this._linker, this._libraryElement, this._unitElement);
+  MetadataResolver(this._linker, this._libraryElement, this._libraryScope,
+      this._unitElement);
 
   @override
   void visitAnnotation(Annotation node) {
@@ -27,7 +27,7 @@
     var holder = ElementHolder();
     node.accept(LocalElementBuilder(holder, null));
 
-    var astResolver = AstResolver(_linker, _libraryElement, scope);
+    var astResolver = AstResolver(_linker, _libraryElement, _libraryScope);
     astResolver.resolve(node);
   }
 
diff --git a/pkg/analyzer/lib/src/summary2/reference.dart b/pkg/analyzer/lib/src/summary2/reference.dart
index 95c0ae7..626fdc8 100644
--- a/pkg/analyzer/lib/src/summary2/reference.dart
+++ b/pkg/analyzer/lib/src/summary2/reference.dart
@@ -69,6 +69,8 @@
 
   bool get isPrefix => parent != null && parent.name == '@prefix';
 
+  bool get isSetter => parent != null && parent.name == '@setter';
+
   bool get isTypeAlias => parent != null && parent.name == '@typeAlias';
 
   /// Return the child with the given name, or `null` if does not exist.
@@ -97,5 +99,9 @@
     }
   }
 
+  void removeChild(String name) {
+    _children.remove(name);
+  }
+
   String toString() => parent == null ? 'root' : '$parent::$name';
 }
diff --git a/pkg/analyzer/lib/src/summary2/reference_resolver.dart b/pkg/analyzer/lib/src/summary2/reference_resolver.dart
index cfaee14..e54f0a3 100644
--- a/pkg/analyzer/lib/src/summary2/reference_resolver.dart
+++ b/pkg/analyzer/lib/src/summary2/reference_resolver.dart
@@ -14,7 +14,6 @@
 import 'package:analyzer/src/summary2/function_type_builder.dart';
 import 'package:analyzer/src/summary2/lazy_ast.dart';
 import 'package:analyzer/src/summary2/linked_element_factory.dart';
-import 'package:analyzer/src/summary2/linking_bundle_context.dart';
 import 'package:analyzer/src/summary2/linking_node_scope.dart';
 import 'package:analyzer/src/summary2/named_type_builder.dart';
 import 'package:analyzer/src/summary2/reference.dart';
@@ -30,18 +29,22 @@
 /// the type is set, otherwise we keep it empty, so we will attempt to infer
 /// it later).
 class ReferenceResolver extends ThrowingAstVisitor<void> {
-  final LinkingBundleContext linkingContext;
   final NodesToBuildType nodesToBuildType;
   final LinkedElementFactory elementFactory;
   final LibraryElement _libraryElement;
   final Reference unitReference;
   final bool nnbd;
 
+  /// The depth-first number of the next [GenericFunctionType] node.
+  int _nextGenericFunctionTypeId = 0;
+
   Reference reference;
   Scope scope;
 
+  /// Is `true` if the current [ClassDeclaration] has a const constructor.
+  bool _hasConstConstructor = false;
+
   ReferenceResolver(
-    this.linkingContext,
     this.nodesToBuildType,
     this.elementFactory,
     this._libraryElement,
@@ -68,6 +71,14 @@
     scope = new ClassScope(scope, element);
     LinkingNodeContext(node, scope);
 
+    _hasConstConstructor = false;
+    for (var member in node.members) {
+      if (member is ConstructorDeclaration && member.constKeyword != null) {
+        _hasConstConstructor = true;
+        break;
+      }
+    }
+
     node.typeParameters?.accept(this);
     node.extendsClause?.accept(this);
     node.implementsClause?.accept(this);
@@ -153,6 +164,12 @@
   @override
   void visitFieldDeclaration(FieldDeclaration node) {
     node.fields.accept(this);
+
+    if (node.fields.isConst ||
+        !node.isStatic && node.fields.isFinal && _hasConstConstructor) {
+      var visitor = _SetGenericFunctionTypeIdVisitor(this);
+      node.fields.variables.accept(visitor);
+    }
   }
 
   @override
@@ -261,7 +278,7 @@
     var outerScope = scope;
     var outerReference = reference;
 
-    var id = linkingContext.nextGenericFunctionTypeId();
+    var id = _nextGenericFunctionTypeId++;
     LazyAst.setGenericFunctionTypeId(node, id);
 
     var containerRef = unitReference.getChild('@genericFunctionType');
@@ -389,6 +406,10 @@
   @override
   void visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
     node.variables.accept(this);
+    if (node.variables.isConst) {
+      var visitor = _SetGenericFunctionTypeIdVisitor(this);
+      node.variables.variables.accept(visitor);
+    }
   }
 
   @override
@@ -487,3 +508,20 @@
     }
   }
 }
+
+/// For consistency we set identifiers for [GenericFunctionType]s in constant
+/// variable initializers, and instance final fields of classes with constant
+/// constructors.
+class _SetGenericFunctionTypeIdVisitor extends RecursiveAstVisitor<void> {
+  final ReferenceResolver resolver;
+
+  _SetGenericFunctionTypeIdVisitor(this.resolver);
+
+  @override
+  void visitGenericFunctionType(GenericFunctionType node) {
+    var id = resolver._nextGenericFunctionTypeId++;
+    LazyAst.setGenericFunctionTypeId(node, id);
+
+    super.visitGenericFunctionType(node);
+  }
+}
diff --git a/pkg/analyzer/lib/src/summary2/tokens_context.dart b/pkg/analyzer/lib/src/summary2/tokens_context.dart
index eb8f654..bae4d3bc 100644
--- a/pkg/analyzer/lib/src/summary2/tokens_context.dart
+++ b/pkg/analyzer/lib/src/summary2/tokens_context.dart
@@ -3,107 +3,11 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/dart/ast/token.dart';
-import 'package:analyzer/src/dart/ast/token.dart';
 import 'package:analyzer/src/summary/idl.dart';
 
 /// The context for reading tokens.
 class TokensContext {
-  final UnlinkedTokens _tokens;
-  final List<Token> _indexToToken;
-  final Map<Token, int> _tokenToIndex;
-
-  TokensContext(this._tokens)
-      : _indexToToken = List<Token>(_tokens.type.length),
-        _tokenToIndex = Map.identity();
-
-  String lexeme(int index) {
-    return _tokens.lexeme[index];
-  }
-
-  void linkTokens(Token from, Token to) {
-    var fromIndex = _tokenToIndex[from];
-    var toIndex = _tokenToIndex[to];
-    Token prevToken = null;
-    for (var index = fromIndex; index <= toIndex && index != 0;) {
-      var token = _indexToToken[index];
-      token ??= tokenOfIndex(index);
-
-      prevToken?.next = token;
-
-      prevToken = token;
-      index = _tokens.next[index];
-    }
-  }
-
-  int offset(int index) {
-    return _tokens.offset[index];
-  }
-
-  Token tokenOfIndex(int index) {
-    if (index == 0) return null;
-
-    var token = _indexToToken[index];
-    if (token == null) {
-      var kind = _tokens.kind[index];
-      switch (kind) {
-        case UnlinkedTokenKind.nothing:
-          return null;
-        case UnlinkedTokenKind.comment:
-          token = CommentToken(
-            _binaryToAstTokenType(_tokens.type[index]),
-            _tokens.lexeme[index],
-            _tokens.offset[index],
-          );
-          break;
-        case UnlinkedTokenKind.keyword:
-          token = KeywordToken(
-            _binaryToAstTokenType(_tokens.type[index]),
-            _tokens.offset[index],
-            _getCommentToken(_tokens.precedingComment[index]),
-          );
-          break;
-        case UnlinkedTokenKind.simple:
-          token = SimpleToken(
-            _binaryToAstTokenType(_tokens.type[index]),
-            _tokens.offset[index],
-            _getCommentToken(_tokens.precedingComment[index]),
-          );
-          break;
-        case UnlinkedTokenKind.string:
-          token = StringToken(
-            _binaryToAstTokenType(_tokens.type[index]),
-            _tokens.lexeme[index],
-            _tokens.offset[index],
-            _getCommentToken(_tokens.precedingComment[index]),
-          );
-          break;
-        default:
-          throw UnimplementedError('Token kind: $kind');
-      }
-      _indexToToken[index] = token;
-      _tokenToIndex[token] = index;
-    }
-    return token;
-  }
-
-  UnlinkedTokenType type(int index) {
-    return _tokens.type[index];
-  }
-
-  CommentToken _getCommentToken(int index) {
-    var result = tokenOfIndex(index);
-    var token = result;
-    while (true) {
-      index = _tokens.next[index];
-      if (index == 0) return result;
-
-      var nextToken = tokenOfIndex(index);
-      token.next = nextToken;
-      token = nextToken;
-    }
-  }
-
-  static TokenType _binaryToAstTokenType(UnlinkedTokenType type) {
+  static TokenType binaryToAstTokenType(UnlinkedTokenType type) {
     switch (type) {
       case UnlinkedTokenType.ABSTRACT:
         return Keyword.ABSTRACT;
diff --git a/pkg/analyzer/lib/src/summary2/tokens_writer.dart b/pkg/analyzer/lib/src/summary2/tokens_writer.dart
index 6668845..859e2ef 100644
--- a/pkg/analyzer/lib/src/summary2/tokens_writer.dart
+++ b/pkg/analyzer/lib/src/summary2/tokens_writer.dart
@@ -3,167 +3,10 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/dart/ast/token.dart';
-import 'package:analyzer/src/dart/ast/token.dart';
-import 'package:analyzer/src/summary/format.dart';
 import 'package:analyzer/src/summary/idl.dart';
-import 'package:meta/meta.dart';
 
 class TokensWriter {
-  final UnlinkedTokensBuilder _tokens = UnlinkedTokensBuilder();
-  final Map<Token, int> _tokenToIndex = Map.identity();
-
-  TokensWriter() {
-    _addToken(
-      null,
-      isSynthetic: true,
-      kind: UnlinkedTokenKind.nothing,
-      length: 0,
-      lexeme: '',
-      offset: 0,
-      precedingComment: 0,
-      type: UnlinkedTokenType.NOTHING,
-    );
-  }
-
-  UnlinkedTokensBuilder get tokensBuilder => _tokens;
-
-  int indexOfToken(Token token) {
-    if (token == null) return 0;
-
-    var index = _tokenToIndex[token];
-    if (index == null) {
-      throw StateError('Unexpected token: $token');
-    }
-    return index;
-  }
-
-  /// Write all the tokens from the [first] to the [last] inclusively.
-  void writeTokens(Token first, Token last) {
-    if (first is CommentToken) {
-      first = (first as CommentToken).parent;
-    }
-
-    var endGroupToBeginIndexMap = <Token, int>{};
-    var previousIndex = 0;
-    for (var token = first;; token = token.next) {
-      var index = _writeToken(token);
-
-      if (previousIndex != 0) {
-        _tokens.next[previousIndex] = index;
-      }
-      previousIndex = index;
-
-      if (token.endGroup != null) {
-        endGroupToBeginIndexMap[token.endGroup] = index;
-      }
-
-      var beginIndex = endGroupToBeginIndexMap[token];
-      if (beginIndex != null) {
-        _tokens.endGroup[beginIndex] = index;
-      }
-
-      if (token == last) break;
-    }
-  }
-
-  int _addToken(
-    Token token, {
-    @required bool isSynthetic,
-    @required UnlinkedTokenKind kind,
-    @required int length,
-    @required String lexeme,
-    @required int offset,
-    @required int precedingComment,
-    @required UnlinkedTokenType type,
-  }) {
-    _tokens.endGroup.add(0);
-    _tokens.isSynthetic.add(isSynthetic);
-    _tokens.kind.add(kind);
-    _tokens.length.add(length);
-    _tokens.lexeme.add(lexeme);
-    _tokens.next.add(0);
-    _tokens.offset.add(offset);
-    _tokens.precedingComment.add(precedingComment);
-    _tokens.type.add(type);
-
-    var index = _tokenToIndex.length;
-    _tokenToIndex[token] = index;
-    return index;
-  }
-
-  int _writeCommentToken(CommentToken token) {
-    if (token == null) return 0;
-
-    int firstIndex = null;
-    var previousIndex = 0;
-    while (token != null) {
-      var index = _addToken(
-        token,
-        isSynthetic: false,
-        kind: UnlinkedTokenKind.comment,
-        length: token.length,
-        lexeme: token.lexeme,
-        offset: token.offset,
-        precedingComment: 0,
-        type: _astToBinaryTokenType(token.type),
-      );
-      firstIndex ??= index;
-
-      if (previousIndex != 0) {
-        _tokens.next[previousIndex] = index;
-      }
-      previousIndex = index;
-
-      token = token.next;
-    }
-
-    return firstIndex;
-  }
-
-  int _writeToken(Token token) {
-    assert(_tokenToIndex[token] == null);
-
-    var commentIndex = _writeCommentToken(token.precedingComments);
-
-    if (token is KeywordToken) {
-      return _addToken(
-        token,
-        isSynthetic: token.isSynthetic,
-        kind: UnlinkedTokenKind.keyword,
-        lexeme: token.lexeme,
-        offset: token.offset,
-        length: token.length,
-        precedingComment: commentIndex,
-        type: _astToBinaryTokenType(token.type),
-      );
-    } else if (token is StringToken) {
-      return _addToken(
-        token,
-        isSynthetic: token.isSynthetic,
-        kind: UnlinkedTokenKind.string,
-        lexeme: token.lexeme,
-        offset: token.offset,
-        length: token.length,
-        precedingComment: commentIndex,
-        type: _astToBinaryTokenType(token.type),
-      );
-    } else if (token is SimpleToken) {
-      return _addToken(
-        token,
-        isSynthetic: token.isSynthetic,
-        kind: UnlinkedTokenKind.simple,
-        lexeme: token.lexeme,
-        offset: token.offset,
-        length: token.length,
-        precedingComment: commentIndex,
-        type: _astToBinaryTokenType(token.type),
-      );
-    } else {
-      throw UnimplementedError('(${token.runtimeType}) $token');
-    }
-  }
-
-  static UnlinkedTokenType _astToBinaryTokenType(TokenType type) {
+  static UnlinkedTokenType astToBinaryTokenType(TokenType type) {
     if (type == Keyword.ABSTRACT) {
       return UnlinkedTokenType.ABSTRACT;
     } else if (type == TokenType.AMPERSAND) {
diff --git a/pkg/analyzer/lib/src/summary2/top_level_inference.dart b/pkg/analyzer/lib/src/summary2/top_level_inference.dart
index 5b35375..eef737d 100644
--- a/pkg/analyzer/lib/src/summary2/top_level_inference.dart
+++ b/pkg/analyzer/lib/src/summary2/top_level_inference.dart
@@ -50,7 +50,7 @@
       _library = builder.element;
       for (var unitContext in builder.context.units) {
         for (var unitMember in unitContext.unit.declarations) {
-          _scope = builder.libraryScope;
+          _scope = builder.scope;
           if (unitMember is TopLevelVariableDeclaration) {
             _variableDeclarationList(unitMember.variables);
           } else if (unitMember is ClassOrMixinDeclaration) {
@@ -330,7 +330,7 @@
         unit.types.forEach(_addClassElementFields);
         unit.mixins.forEach(_addClassElementFields);
 
-        _scope = builder.libraryScope;
+        _scope = builder.scope;
         for (var element in unit.topLevelVariables) {
           _addNode(element);
         }
diff --git a/pkg/analyzer/lib/src/summary2/type_alias.dart b/pkg/analyzer/lib/src/summary2/type_alias.dart
index cc1830b..79e8ba8 100644
--- a/pkg/analyzer/lib/src/summary2/type_alias.dart
+++ b/pkg/analyzer/lib/src/summary2/type_alias.dart
@@ -95,7 +95,9 @@
 
     if (node is TypeName) {
       var element = node.name.staticElement;
-      if (element is ElementImpl) {
+      if (element is ElementImpl &&
+          element.enclosingElement != null &&
+          element.linkedContext.isLinking) {
         var typeNode = element.linkedNode;
         if (typeNode == self) {
           hasSelfReference = true;
@@ -122,8 +124,8 @@
             _typeParameterList(typeNode.typeParameters);
           }
         }
-        _argumentList(node.typeArguments);
       }
+      _argumentList(node.typeArguments);
     } else if (node is GenericFunctionType) {
       _typeParameterList(node.typeParameters);
       _formalParameterList(node.parameters);
diff --git a/pkg/analyzer/lib/src/task/strong/checker.dart b/pkg/analyzer/lib/src/task/strong/checker.dart
index 0708ecf..e451ec6 100644
--- a/pkg/analyzer/lib/src/task/strong/checker.dart
+++ b/pkg/analyzer/lib/src/task/strong/checker.dart
@@ -6,6 +6,7 @@
 // refactored to fit into analyzer.
 import 'dart:collection';
 
+import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/standard_resolution_map.dart';
 import 'package:analyzer/dart/ast/token.dart' show TokenType;
@@ -123,6 +124,8 @@
   final AnalysisOptionsImpl _options;
   _OverrideChecker _overrideChecker;
 
+  FeatureSet _featureSet;
+
   bool _failure = false;
   bool _hasImplicitCasts;
   HashSet<ExecutableElement> _covariantPrivateMembers;
@@ -334,6 +337,7 @@
 
   @override
   void visitCompilationUnit(CompilationUnit node) {
+    _featureSet = node.featureSet;
     _hasImplicitCasts = false;
     _covariantPrivateMembers = new HashSet();
     node.visitChildren(this);
@@ -733,7 +737,7 @@
       var rhsType = _getExpressionType(expr.rightHandSide);
       var lhsType = _getExpressionType(expr.leftHandSide);
       var returnType = rules.refineBinaryExpressionType(
-          lhsType, op, rhsType, functionType.returnType);
+          lhsType, op, rhsType, functionType.returnType, _featureSet);
 
       // Check the argument for an implicit cast.
       _checkImplicitCast(expr.rightHandSide, paramTypes[0], from: rhsType);
@@ -958,8 +962,8 @@
         var functionType = element.type;
         var rhsType = typeProvider.intType;
         var lhsType = _getExpressionType(operand);
-        var returnType = rules.refineBinaryExpressionType(
-            lhsType, TokenType.PLUS, rhsType, functionType.returnType);
+        var returnType = rules.refineBinaryExpressionType(lhsType,
+            TokenType.PLUS, rhsType, functionType.returnType, _featureSet);
 
         // Skip the argument check - `int` cannot be downcast.
         //
diff --git a/pkg/analyzer/lib/src/workspace/package_build.dart b/pkg/analyzer/lib/src/workspace/package_build.dart
index 7e5bcbd..4459dd5 100644
--- a/pkg/analyzer/lib/src/workspace/package_build.dart
+++ b/pkg/analyzer/lib/src/workspace/package_build.dart
@@ -285,17 +285,10 @@
 
   @override
   WorkspacePackage findPackageFor(String filePath) {
-    final Folder folder = provider.getFolder(filePath);
-    if (provider.pathContext.isWithin(root, folder.path)) {
-      List<String> uriParts =
-          (packageUriResolver as PackageBuildPackageUriResolver)
-              ._restoreUriParts('${folder.path}/lib/__fake__.dart');
-      if (uriParts == null || uriParts.isEmpty) {
-        _theOnlyPackage ??= new PackageBuildWorkspacePackage(null, root, this);
-      } else {
-        _theOnlyPackage ??=
-            new PackageBuildWorkspacePackage(uriParts[0], root, this);
-      }
+    path.Context context = provider.pathContext;
+    final folder = provider.getFolder(context.dirname(filePath));
+    if (context.isWithin(root, folder.path)) {
+      _theOnlyPackage ??= new PackageBuildWorkspacePackage(root, this);
       return _theOnlyPackage;
     } else {
       return null;
@@ -346,22 +339,15 @@
  * a given package in a PackageBuildWorkspace.
  */
 class PackageBuildWorkspacePackage extends WorkspacePackage {
-  /// A prefix for any URI of a path in this package.
-  final String _uriPrefix;
-
   final String root;
 
   final PackageBuildWorkspace workspace;
 
-  PackageBuildWorkspacePackage(String packageName, this.root, this.workspace)
-      : this._uriPrefix = 'package:$packageName/';
+  PackageBuildWorkspacePackage(this.root, this.workspace);
 
   @override
   bool contains(Source source) {
-    if (source.uri.isScheme('package')) {
-      return source.uri.toString().startsWith(_uriPrefix);
-    }
-    String filePath = source.fullName;
+    String filePath = filePathFromSource(source);
     if (filePath == null) return false;
     // There is a 1-1 relationship between PackageBuildWorkspaces and
     // PackageBuildWorkspacePackages. If a file is in a package's workspace,
diff --git a/pkg/analyzer/pubspec.yaml b/pkg/analyzer/pubspec.yaml
index 1723adb..fdd4710 100644
--- a/pkg/analyzer/pubspec.yaml
+++ b/pkg/analyzer/pubspec.yaml
@@ -1,5 +1,5 @@
 name: analyzer
-version: 0.36.3
+version: 0.36.4-dev
 author: Dart Team <misc@dartlang.org>
 description: Static analyzer for Dart.
 homepage: https://github.com/dart-lang/sdk/tree/master/pkg/analyzer
diff --git a/pkg/analyzer/test/generated/analysis_context_factory.dart b/pkg/analyzer/test/generated/analysis_context_factory.dart
index e2aef27..b70df9d 100644
--- a/pkg/analyzer/test/generated/analysis_context_factory.dart
+++ b/pkg/analyzer/test/generated/analysis_context_factory.dart
@@ -4,6 +4,7 @@
 
 import 'dart:collection';
 
+import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/dart/element/element.dart';
@@ -47,7 +48,8 @@
       {UriResolver contributedResolver,
       MemoryResourceProvider resourceProvider}) {
     AnalysisContextForTests context = new AnalysisContextForTests();
-    return initContextWithCore(context, contributedResolver, resourceProvider);
+    return initContextWithCore(context, FeatureSet.forTesting(),
+        contributedResolver, resourceProvider);
   }
 
   /**
@@ -60,7 +62,8 @@
       {MemoryResourceProvider resourceProvider}) {
     AnalysisContextForTests context = new AnalysisContextForTests();
     context._internalSetAnalysisOptions(options);
-    return initContextWithCore(context, null, resourceProvider);
+    return initContextWithCore(
+        context, options.contextFeatures, null, resourceProvider);
   }
 
   /**
@@ -73,8 +76,8 @@
       Map<String, String> packages,
       {MemoryResourceProvider resourceProvider}) {
     AnalysisContextForTests context = new AnalysisContextForTests();
-    return initContextWithCore(
-        context, new TestPackageUriResolver(packages), resourceProvider);
+    return initContextWithCore(context, FeatureSet.forTesting(),
+        new TestPackageUriResolver(packages), resourceProvider);
   }
 
   /**
@@ -84,7 +87,7 @@
    * be used when accessing the file system.
    */
   static InternalAnalysisContext initContextWithCore(
-      InternalAnalysisContext context,
+      InternalAnalysisContext context, FeatureSet featureSet,
       [UriResolver contributedResolver,
       MemoryResourceProvider resourceProvider]) {
     DartSdk sdk = new _AnalysisContextFactory_initContextWithCore(
@@ -174,7 +177,10 @@
       proxyTopLevelVariableElt
     ];
     LibraryElementImpl coreLibrary = new LibraryElementImpl.forNode(
-        coreContext, null, AstTestFactory.libraryIdentifier2(["dart", "core"]));
+        coreContext,
+        null,
+        AstTestFactory.libraryIdentifier2(["dart", "core"]),
+        featureSet.isEnabled(Feature.non_nullable));
     coreLibrary.definingCompilationUnit = coreUnit;
     //
     // dart:async
@@ -182,7 +188,8 @@
     LibraryElementImpl asyncLibrary = new LibraryElementImpl.forNode(
         coreContext,
         null,
-        AstTestFactory.libraryIdentifier2(["dart", "async"]));
+        AstTestFactory.libraryIdentifier2(["dart", "async"]),
+        featureSet.isEnabled(Feature.non_nullable));
     CompilationUnitElementImpl asyncUnit = new CompilationUnitElementImpl();
     Source asyncSource = sourceFactory.forUri(DartSdk.DART_ASYNC);
     asyncUnit.librarySource = asyncUnit.source = asyncSource;
@@ -329,8 +336,11 @@
             "document", false, true, htmlDocumentElement.type);
     htmlUnit.topLevelVariables = <TopLevelVariableElement>[document];
     htmlUnit.accessors = <PropertyAccessorElement>[document.getter];
-    LibraryElementImpl htmlLibrary = new LibraryElementImpl.forNode(coreContext,
-        null, AstTestFactory.libraryIdentifier2(["dart", "dom", "html"]));
+    LibraryElementImpl htmlLibrary = new LibraryElementImpl.forNode(
+        coreContext,
+        null,
+        AstTestFactory.libraryIdentifier2(["dart", "dom", "html"]),
+        featureSet.isEnabled(Feature.non_nullable));
     htmlLibrary.definingCompilationUnit = htmlUnit;
     //
     // dart:math
@@ -390,7 +400,10 @@
     ];
     mathUnit.types = <ClassElement>[randomElement];
     LibraryElementImpl mathLibrary = new LibraryElementImpl.forNode(
-        coreContext, null, AstTestFactory.libraryIdentifier2(["dart", "math"]));
+        coreContext,
+        null,
+        AstTestFactory.libraryIdentifier2(["dart", "math"]),
+        featureSet.isEnabled(Feature.non_nullable));
     mathLibrary.definingCompilationUnit = mathUnit;
     //
     // Record the elements.
diff --git a/pkg/analyzer/test/generated/compile_time_error_code.dart b/pkg/analyzer/test/generated/compile_time_error_code.dart
index 9d25dc4..e11ba55 100644
--- a/pkg/analyzer/test/generated/compile_time_error_code.dart
+++ b/pkg/analyzer/test/generated/compile_time_error_code.dart
@@ -1875,15 +1875,15 @@
   }
 
   test_genericFunctionTypedParameter() async {
-    // TODO(paulberry): remove when dartbug.com/28515 fixed.
+    var code = '''
+void g(T f<T>(T x)) {}
+''';
     if (AnalysisDriver.useSummary2) {
-      await assertNoErrorsInCode('''
-void g(T f<T>(T x)) {}
-''');
+      await assertNoErrorsInCode(code);
     } else {
-      await assertErrorsInCode('''
-void g(T f<T>(T x)) {}
-''', [
+      // Once dartbug.com/28515 is fixed, this syntax should no longer generate an
+      // error.
+      await assertErrorsInCode(code, [
         // Due to dartbug.com/28515, some additional errors appear when using the
         // new analysis driver.
         error(StaticWarningCode.UNDEFINED_CLASS, 7, 1),
diff --git a/pkg/analyzer/test/generated/declaration_resolver_test.dart b/pkg/analyzer/test/generated/declaration_resolver_test.dart
index f2ac4f2..db29c01 100644
--- a/pkg/analyzer/test/generated/declaration_resolver_test.dart
+++ b/pkg/analyzer/test/generated/declaration_resolver_test.dart
@@ -6,7 +6,6 @@
 
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/src/dart/analysis/driver.dart';
 import 'package:analyzer/src/dart/ast/ast.dart';
 import 'package:analyzer/src/dart/ast/utilities.dart';
 import 'package:analyzer/src/dart/element/element.dart';
@@ -21,11 +20,6 @@
 import 'test_support.dart';
 
 main() {
-  // With summary2 DeclarationResolver is not used.
-  if (AnalysisDriver.useSummary2) {
-    return;
-  }
-
   defineReflectiveSuite(() {
     defineReflectiveTests(DeclarationResolverMetadataTest);
     defineReflectiveTests(DeclarationResolverTest);
diff --git a/pkg/analyzer/test/generated/parser_fasta_test.dart b/pkg/analyzer/test/generated/parser_fasta_test.dart
index 104879f..6de285d 100644
--- a/pkg/analyzer/test/generated/parser_fasta_test.dart
+++ b/pkg/analyzer/test/generated/parser_fasta_test.dart
@@ -24,7 +24,6 @@
     show LanguageVersionToken, ScannerConfiguration, ScannerResult, scanString;
 import 'package:front_end/src/fasta/scanner/error_token.dart' show ErrorToken;
 import 'package:front_end/src/fasta/scanner/string_scanner.dart';
-import 'package:front_end/src/scanner/errors.dart' show translateErrorToken;
 import 'package:pub_semver/src/version.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -1631,12 +1630,6 @@
     featureSet ??= FeatureSet.forTesting();
     var source = new StringSource(content, 'parser_test_StringSource.dart');
 
-    void reportError(
-        ScannerErrorCode errorCode, int offset, List<Object> arguments) {
-      listener
-          .onError(new AnalysisError(source, offset, 1, errorCode, arguments));
-    }
-
     // Adjust the feature set based on language version comment.
     void languageVersionChanged(
         fasta.Scanner scanner, LanguageVersionToken languageVersion) {
@@ -1650,16 +1643,7 @@
         includeComments: true,
         configuration: Scanner.buildConfig(featureSet),
         languageVersionChanged: languageVersionChanged);
-    Token token = result.tokens;
-    if (result.hasErrors) {
-      // The default recovery strategy used by scanString
-      // places all error tokens at the head of the stream.
-      while (token.type == TokenType.BAD_INPUT) {
-        translateErrorToken(token, reportError);
-        token = token.next;
-      }
-    }
-    _fastaTokens = token;
+    _fastaTokens = result.tokens;
 
     // Run parser
     ErrorReporter errorReporter = new ErrorReporter(listener, source);
@@ -2696,8 +2680,16 @@
    */
   _run(String enclosingEvent, f()) {
     _eventListener.begin(enclosingEvent);
+
+    // Simulate error handling of parseUnit by skipping error tokens
+    // before parsing and reporting them after parsing is complete.
+    Token errorToken = currentToken;
+    currentToken = fastaParser.skipErrorTokens(currentToken);
     var result = f();
+    fastaParser.reportAllErrorTokens(errorToken);
+
     _eventListener.end(enclosingEvent);
+
     String lexeme = currentToken is ErrorToken
         ? currentToken.runtimeType.toString()
         : currentToken.lexeme;
diff --git a/pkg/analyzer/test/generated/parser_test.dart b/pkg/analyzer/test/generated/parser_test.dart
index 3e203b1..1f29027 100644
--- a/pkg/analyzer/test/generated/parser_test.dart
+++ b/pkg/analyzer/test/generated/parser_test.dart
@@ -4398,20 +4398,12 @@
   }
 
   void test_missingClosingParenthesis() {
-    // It is possible that it is not possible to generate this error (that it's
-    // being reported in code that cannot actually be reached), but that hasn't
-    // been proven yet.
     createParser('(int a, int b ;',
-        expectedEndOffset: 14 /* ErrorToken at end of token stream */);
+        expectedEndOffset: 14 /* parsing ends at synthetic ')' */);
     FormalParameterList list = parser.parseFormalParameterList();
     expectNotNullIfNoErrors(list);
-    if (usingFastaParser) {
-      // Fasta scanner reports missing `)` error
-      listener.assertNoErrors();
-    } else {
-      listener.errors
-          .contains(expectedError(ParserErrorCode.EXPECTED_TOKEN, 14, 1));
-    }
+    listener.errors
+        .contains(expectedError(ParserErrorCode.EXPECTED_TOKEN, 14, 1));
   }
 
   void test_missingConstFinalVarOrType_static() {
@@ -9409,34 +9401,14 @@
     Source source = new TestSource();
     listener = new GatheringErrorListener();
 
-    void reportError(
-        ScannerErrorCode errorCode, int offset, List<Object> arguments) {
-      listener
-          .onError(new AnalysisError(source, offset, 1, errorCode, arguments));
-    }
-
-    //
-    // Scan the source.
-    //
     ScannerResult result = scanString(content, includeComments: true);
-    Token token = result.tokens;
-    if (result.hasErrors) {
-      // The default recovery strategy used by scanString
-      // places all error tokens at the head of the stream.
-      while (token.type == TokenType.BAD_INPUT) {
-        translateErrorToken(token, reportError);
-        token = token.next;
-      }
-    }
     listener.setLineInfo(source, result.lineStarts);
-    //
-    // Create and initialize the parser.
-    //
+
     parser = new Parser(source, listener, featureSet: FeatureSet.forTesting());
     parser.allowNativeClause = allowNativeClause;
     parser.parseFunctionBodies = parseFunctionBodies;
     parser.enableOptionalNewAndConst = enableOptionalNewAndConst;
-    parser.currentToken = token;
+    parser.currentToken = result.tokens;
   }
 
   @override
@@ -9557,31 +9529,13 @@
     Source source = new TestSource();
     GatheringErrorListener listener = new GatheringErrorListener();
 
-    void reportError(
-        ScannerErrorCode errorCode, int offset, List<Object> arguments) {
-      listener
-          .onError(new AnalysisError(source, offset, 1, errorCode, arguments));
-    }
-
-    //
-    // Scan the source.
-    //
     ScannerResult result = scanString(content, includeComments: true);
-    Token token = result.tokens;
-    if (result.hasErrors) {
-      // The default recovery strategy used by scanString
-      // places all error tokens at the head of the stream.
-      while (token.type == TokenType.BAD_INPUT) {
-        translateErrorToken(token, reportError);
-        token = token.next;
-      }
-    }
     listener.setLineInfo(source, result.lineStarts);
 
     Parser parser =
         new Parser(source, listener, featureSet: FeatureSet.forTesting());
     parser.enableOptionalNewAndConst = enableOptionalNewAndConst;
-    CompilationUnit unit = parser.parseCompilationUnit(token);
+    CompilationUnit unit = parser.parseCompilationUnit(result.tokens);
     expect(unit, isNotNull);
     if (codes != null) {
       listener.assertErrorsWithCodes(codes);
@@ -9601,30 +9555,12 @@
     Source source = NonExistingSource.unknown;
     listener ??= AnalysisErrorListener.NULL_LISTENER;
 
-    void reportError(
-        ScannerErrorCode errorCode, int offset, List<Object> arguments) {
-      listener
-          .onError(new AnalysisError(source, offset, 1, errorCode, arguments));
-    }
-
-    //
-    // Scan the source.
-    //
     ScannerResult result = scanString(content, includeComments: true);
-    Token token = result.tokens;
-    if (result.hasErrors) {
-      // The default recovery strategy used by scanString
-      // places all error tokens at the head of the stream.
-      while (token.type == TokenType.BAD_INPUT) {
-        translateErrorToken(token, reportError);
-        token = token.next;
-      }
-    }
 
     Parser parser =
         new Parser(source, listener, featureSet: FeatureSet.forTesting());
     parser.enableOptionalNewAndConst = enableOptionalNewAndConst;
-    CompilationUnit unit = parser.parseCompilationUnit(token);
+    CompilationUnit unit = parser.parseCompilationUnit(result.tokens);
     unit.lineInfo = new LineInfo(result.lineStarts);
     return unit;
   }
@@ -9952,31 +9888,13 @@
     Source source = new TestSource();
     listener = new GatheringErrorListener();
 
-    void reportError(
-        ScannerErrorCode errorCode, int offset, List<Object> arguments) {
-      listener
-          .onError(new AnalysisError(source, offset, 1, errorCode, arguments));
-    }
-
-    //
-    // Scan the source.
-    //
     ScannerResult result = scanString(content, includeComments: true);
-    Token token = result.tokens;
-    if (result.hasErrors) {
-      // The default recovery strategy used by scanString
-      // places all error tokens at the head of the stream.
-      while (token.type == TokenType.BAD_INPUT) {
-        translateErrorToken(token, reportError);
-        token = token.next;
-      }
-    }
     listener.setLineInfo(source, result.lineStarts);
 
     Parser parser =
         new Parser(source, listener, featureSet: FeatureSet.forTesting());
     parser.enableOptionalNewAndConst = enableOptionalNewAndConst;
-    Statement statement = parser.parseStatement(token);
+    Statement statement = parser.parseStatement(result.tokens);
     expect(statement, isNotNull);
     return statement;
   }
@@ -9997,31 +9915,13 @@
     Source source = new TestSource();
     GatheringErrorListener listener = new GatheringErrorListener();
 
-    void reportError(
-        ScannerErrorCode errorCode, int offset, List<Object> arguments) {
-      listener
-          .onError(new AnalysisError(source, offset, 1, errorCode, arguments));
-    }
-
-    //
-    // Scan the source.
-    //
     ScannerResult result = scanString(content);
-    Token token = result.tokens;
-    if (result.hasErrors) {
-      // The default recovery strategy used by scanString
-      // places all error tokens at the head of the stream.
-      while (token.type == TokenType.BAD_INPUT) {
-        translateErrorToken(token, reportError);
-        token = token.next;
-      }
-    }
     listener.setLineInfo(source, result.lineStarts);
 
     Parser parser =
         new Parser(source, listener, featureSet: FeatureSet.forTesting());
     parser.enableOptionalNewAndConst = enableOptionalNewAndConst;
-    List<Statement> statements = parser.parseStatements(token);
+    List<Statement> statements = parser.parseStatements(result.tokens);
     expect(statements, hasLength(expectedCount));
     listener.assertErrorsWithCodes(errorCodes);
     return statements;
diff --git a/pkg/analyzer/test/generated/resolver_test.dart b/pkg/analyzer/test/generated/resolver_test.dart
index 59f614f..7fa83ed 100644
--- a/pkg/analyzer/test/generated/resolver_test.dart
+++ b/pkg/analyzer/test/generated/resolver_test.dart
@@ -5,6 +5,7 @@
 import 'dart:async';
 import 'dart:collection';
 
+import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/standard_ast_factory.dart';
 import 'package:analyzer/dart/ast/standard_resolution_map.dart';
@@ -43,6 +44,7 @@
     defineReflectiveTests(ErrorResolverTest);
     defineReflectiveTests(LibraryImportScopeTest);
     defineReflectiveTests(LibraryScopeTest);
+    defineReflectiveTests(NonNullableTypeProviderTest);
     defineReflectiveTests(PrefixedNamespaceTest);
     defineReflectiveTests(ScopeTest);
     defineReflectiveTests(StrictModeTest);
@@ -332,6 +334,129 @@
 }
 
 @reflectiveTest
+class NonNullableTypeProviderTest extends EngineTestCase {
+  void assertNonNullable(InterfaceType type) {
+    expect((type as TypeImpl).nullabilitySuffix, NullabilitySuffix.none);
+  }
+
+  void test_creation() {
+    //
+    // Create a mock library element with the types expected to be in dart:core.
+    // We cannot use either ElementFactory or TestTypeProvider (which uses
+    // ElementFactory) because we side-effect the elements in ways that would
+    // break other tests.
+    //
+    InterfaceType objectType = _classElement("Object", null).type;
+    InterfaceType boolType = _classElement("bool", objectType).type;
+    InterfaceType numType = _classElement("num", objectType).type;
+    InterfaceType deprecatedType = _classElement('Deprecated', objectType).type;
+    InterfaceType doubleType = _classElement("double", numType).type;
+    InterfaceType functionType = _classElement("Function", objectType).type;
+    InterfaceType futureType = _classElement("Future", objectType, ["T"]).type;
+    InterfaceType futureOrType =
+        _classElement("FutureOr", objectType, ["T"]).type;
+    InterfaceType intType = _classElement("int", numType).type;
+    InterfaceType iterableType =
+        _classElement("Iterable", objectType, ["T"]).type;
+    InterfaceType listType = _classElement("List", objectType, ["E"]).type;
+    InterfaceType mapType = _classElement("Map", objectType, ["K", "V"]).type;
+    InterfaceType nullType = _classElement('Null', objectType).type;
+    InterfaceType setType = _classElement("Set", objectType, ["E"]).type;
+    InterfaceType stackTraceType = _classElement("StackTrace", objectType).type;
+    InterfaceType streamType = _classElement("Stream", objectType, ["T"]).type;
+    InterfaceType stringType = _classElement("String", objectType).type;
+    InterfaceType symbolType = _classElement("Symbol", objectType).type;
+    InterfaceType typeType = _classElement("Type", objectType).type;
+    CompilationUnitElementImpl coreUnit = new CompilationUnitElementImpl();
+    coreUnit.types = <ClassElement>[
+      boolType.element,
+      deprecatedType.element,
+      doubleType.element,
+      functionType.element,
+      intType.element,
+      iterableType.element,
+      listType.element,
+      mapType.element,
+      nullType.element,
+      numType.element,
+      setType.element,
+      objectType.element,
+      stackTraceType.element,
+      stringType.element,
+      symbolType.element,
+      typeType.element
+    ];
+    coreUnit.source = new TestSource('dart:core');
+    coreUnit.librarySource = coreUnit.source;
+    CompilationUnitElementImpl asyncUnit = new CompilationUnitElementImpl();
+    asyncUnit.types = <ClassElement>[
+      futureType.element,
+      futureOrType.element,
+      streamType.element
+    ];
+    asyncUnit.source = new TestSource('dart:async');
+    asyncUnit.librarySource = asyncUnit.source;
+    LibraryElementImpl coreLibrary = new LibraryElementImpl.forNode(
+        null, null, AstTestFactory.libraryIdentifier2(["dart.core"]), true);
+    coreLibrary.definingCompilationUnit = coreUnit;
+    LibraryElementImpl asyncLibrary = new LibraryElementImpl.forNode(
+        null, null, AstTestFactory.libraryIdentifier2(["dart.async"]), true);
+    asyncLibrary.definingCompilationUnit = asyncUnit;
+    //
+    // Create a type provider and ensure that it can return the expected types.
+    //
+    TypeProvider provider =
+        new NonNullableTypeProvider(coreLibrary, asyncLibrary);
+    assertNonNullable(provider.boolType);
+    expect(provider.bottomType, isNotNull);
+    assertNonNullable(provider.deprecatedType);
+    assertNonNullable(provider.doubleType);
+    expect(provider.dynamicType, isNotNull);
+    assertNonNullable(provider.functionType);
+    assertNonNullable(provider.futureType);
+    assertNonNullable(provider.futureOrType);
+    assertNonNullable(provider.intType);
+    assertNonNullable(provider.listType);
+    assertNonNullable(provider.mapType);
+    expect(provider.neverType, isNotNull);
+    assertNonNullable(provider.nullType);
+    assertNonNullable(provider.numType);
+    assertNonNullable(provider.objectType);
+    assertNonNullable(provider.stackTraceType);
+    assertNonNullable(provider.streamType);
+    assertNonNullable(provider.stringType);
+    assertNonNullable(provider.symbolType);
+    assertNonNullable(provider.typeType);
+  }
+
+  ClassElement _classElement(String typeName, InterfaceType superclassType,
+      [List<String> parameterNames]) {
+    ClassElementImpl element =
+        new ClassElementImpl.forNode(AstTestFactory.identifier3(typeName));
+    element.supertype = superclassType;
+    if (parameterNames != null) {
+      int count = parameterNames.length;
+      if (count > 0) {
+        List<TypeParameterElementImpl> typeParameters =
+            new List<TypeParameterElementImpl>(count);
+        List<TypeParameterTypeImpl> typeArguments =
+            new List<TypeParameterTypeImpl>(count);
+        for (int i = 0; i < count; i++) {
+          TypeParameterElementImpl typeParameter =
+              new TypeParameterElementImpl.forNode(
+                  AstTestFactory.identifier3(parameterNames[i]));
+          typeParameters[i] = typeParameter;
+          typeArguments[i] = new TypeParameterTypeImpl(typeParameter);
+          typeParameter.type = typeArguments[i];
+        }
+        element.typeParameters = typeParameters;
+      }
+    }
+    return element;
+  }
+}
+
+@reflectiveTest
 class PrefixedNamespaceTest extends DriverResolutionTest {
   void test_lookup_missing() {
     ClassElement element = ElementFactory.classElement2('A');
@@ -1065,10 +1190,10 @@
     asyncUnit.source = new TestSource('dart:async');
     asyncUnit.librarySource = asyncUnit.source;
     LibraryElementImpl coreLibrary = new LibraryElementImpl.forNode(
-        null, null, AstTestFactory.libraryIdentifier2(["dart.core"]));
+        null, null, AstTestFactory.libraryIdentifier2(["dart.core"]), true);
     coreLibrary.definingCompilationUnit = coreUnit;
     LibraryElementImpl asyncLibrary = new LibraryElementImpl.forNode(
-        null, null, AstTestFactory.libraryIdentifier2(["dart.async"]));
+        null, null, AstTestFactory.libraryIdentifier2(["dart.async"]), true);
     asyncLibrary.definingCompilationUnit = asyncUnit;
     //
     // Create a type provider and ensure that it can return the expected types.
@@ -1168,13 +1293,20 @@
     InternalAnalysisContext context = AnalysisContextFactory.contextWithCore(
         resourceProvider: resourceProvider);
     Source librarySource = new FileSource(getFile("/lib.dart"));
+    // TODO(paulberry): make it possible to override the feature set so we can
+    // test NNBD features.
+    var featureSet = FeatureSet.forTesting(sdkVersion: '2.2.2');
     LibraryElementImpl element = new LibraryElementImpl.forNode(
-        context, null, AstTestFactory.libraryIdentifier2(["lib"]));
+        context,
+        null,
+        AstTestFactory.libraryIdentifier2(["lib"]),
+        featureSet.isEnabled(Feature.non_nullable));
     element.definingCompilationUnit = new CompilationUnitElementImpl();
     _typeProvider = new TestTypeProvider();
     libraryScope = new LibraryScope(element);
     _visitor = new TypeResolverVisitor(
         element, librarySource, _typeProvider, _listener,
+        featureSet: featureSet,
         nameScope: libraryScope,
         shouldSetElementSupertypes: shouldSetElementSupertypes);
   }
@@ -1206,12 +1338,18 @@
       InternalAnalysisContext context = AnalysisContextFactory.contextWithCore(
           resourceProvider: resourceProvider);
       var source = getFile('/test.dart').createSource();
-      var libraryElement = new LibraryElementImpl.forNode(context, null, null)
+      // TODO(paulberry): make it possible to override the feature set so we can
+      // test NNBD features.
+      var featureSet = FeatureSet.forTesting(sdkVersion: '2.2.2');
+      var libraryElement = new LibraryElementImpl.forNode(
+          context, null, null, featureSet.isEnabled(Feature.non_nullable))
         ..definingCompilationUnit = unitElement;
       var libraryScope = new LibraryScope(libraryElement);
       var visitor = new TypeResolverVisitor(
           libraryElement, source, _typeProvider, _listener,
-          nameScope: libraryScope, mode: TypeResolverMode.api);
+          featureSet: featureSet,
+          nameScope: libraryScope,
+          mode: TypeResolverMode.api);
       libraryScope.define(A);
       unit.accept(visitor);
     }
@@ -2077,12 +2215,18 @@
       InternalAnalysisContext context = AnalysisContextFactory.contextWithCore(
           resourceProvider: resourceProvider);
       var source = getFile('/test.dart').createSource();
-      var libraryElement = new LibraryElementImpl.forNode(context, null, null)
+      // TODO(paulberry): make it possible to override the feature set so we can
+      // test NNBD features.
+      var featureSet = FeatureSet.forTesting(sdkVersion: '2.2.2');
+      var libraryElement = new LibraryElementImpl.forNode(
+          context, null, null, featureSet.isEnabled(Feature.non_nullable))
         ..definingCompilationUnit = unitElement;
       libraryScope = new LibraryScope(libraryElement);
       visitor = new TypeResolverVisitor(
           libraryElement, source, _typeProvider, _listener,
-          nameScope: libraryScope, mode: TypeResolverMode.local);
+          featureSet: featureSet,
+          nameScope: libraryScope,
+          mode: TypeResolverMode.local);
     }
 
     // Define top-level types.
diff --git a/pkg/analyzer/test/generated/resolver_test_case.dart b/pkg/analyzer/test/generated/resolver_test_case.dart
index 611479c..b0bb6d4 100644
--- a/pkg/analyzer/test/generated/resolver_test_case.dart
+++ b/pkg/analyzer/test/generated/resolver_test_case.dart
@@ -4,6 +4,7 @@
 
 import 'dart:async';
 
+import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/analysis/results.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/standard_resolution_map.dart';
@@ -567,10 +568,12 @@
         new CompilationUnitElementImpl();
     compilationUnit.librarySource =
         compilationUnit.source = definingCompilationUnitSource;
+    var featureSet = context.analysisOptions.contextFeatures;
     LibraryElementImpl library = new LibraryElementImpl.forNode(
         context,
         driver?.currentSession,
-        AstTestFactory.libraryIdentifier2([libraryName]));
+        AstTestFactory.libraryIdentifier2([libraryName]),
+        featureSet.isEnabled(Feature.non_nullable));
     library.definingCompilationUnit = compilationUnit;
     library.parts = sourcedCompilationUnits;
     return library;
diff --git a/pkg/analyzer/test/generated/scanner_test.dart b/pkg/analyzer/test/generated/scanner_test.dart
index 02039f4..5470859 100644
--- a/pkg/analyzer/test/generated/scanner_test.dart
+++ b/pkg/analyzer/test/generated/scanner_test.dart
@@ -9,6 +9,7 @@
 import 'package:analyzer/src/dart/scanner/reader.dart';
 import 'package:analyzer/src/dart/scanner/scanner.dart';
 import 'package:analyzer/src/generated/source.dart';
+import 'package:front_end/src/fasta/scanner/error_token.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -143,11 +144,15 @@
     // See https://github.com/dart-lang/sdk/issues/30320
     String source = '<!-- @Component(';
     GatheringErrorListener listener = new GatheringErrorListener();
-    _scanWithListener(source, listener);
-    listener.assertErrorsWithCodes(const [
-      ScannerErrorCode.EXPECTED_TOKEN,
-      ScannerErrorCode.EXPECTED_TOKEN,
-    ]);
+    Scanner scanner =
+        new Scanner(null, new CharSequenceReader(source), listener)
+          ..configureFeatures(featureSet);
+    Token token = scanner.tokenize(reportScannerErrors: false);
+    expect(token, TypeMatcher<UnmatchedToken>());
+    token = token.next;
+    expect(token, TypeMatcher<UnmatchedToken>());
+    token = token.next;
+    expect(token, isNot(TypeMatcher<ErrorToken>()));
   }
 
   void _assertLineInfo(
diff --git a/pkg/analyzer/test/generated/static_type_analyzer_test.dart b/pkg/analyzer/test/generated/static_type_analyzer_test.dart
index 8382b04..e261136 100644
--- a/pkg/analyzer/test/generated/static_type_analyzer_test.dart
+++ b/pkg/analyzer/test/generated/static_type_analyzer_test.dart
@@ -1528,14 +1528,14 @@
         new CompilationUnitElementImpl();
     definingCompilationUnit.librarySource =
         definingCompilationUnit.source = source;
-    LibraryElementImpl definingLibrary =
-        new LibraryElementImpl.forNode(context, null, null);
+    var featureSet = FeatureSet.forTesting();
+    LibraryElementImpl definingLibrary = new LibraryElementImpl.forNode(
+        context, null, null, featureSet.isEnabled(Feature.non_nullable));
     definingLibrary.definingCompilationUnit = definingCompilationUnit;
     _typeProvider = context.typeProvider;
     _visitor = new ResolverVisitor(
         inheritance, definingLibrary, source, _typeProvider, _listener,
-        featureSet: FeatureSet.forTesting(),
-        nameScope: new LibraryScope(definingLibrary));
+        featureSet: featureSet, nameScope: new LibraryScope(definingLibrary));
     return _visitor.typeAnalyzer;
   }
 
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
index 83168dd..73fc758 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
@@ -1204,11 +1204,7 @@
     FunctionExpressionInvocation invocation = field.initializer;
     FunctionExpression closure = invocation.function.unParenthesized;
     FunctionElementImpl closureElement = closure.declaredElement;
-    if (AnalysisDriver.useSummary2) {
-      expect(closureElement.enclosingElement, same(field.declaredElement));
-    } else {
-      expect(closureElement.enclosingElement, same(fieldInitializer));
-    }
+    expect(closureElement.enclosingElement, same(fieldInitializer));
   }
 
   test_closure_inTopLevelVariable() async {
@@ -1226,11 +1222,7 @@
     FunctionExpressionInvocation invocation = variable.initializer;
     FunctionExpression closure = invocation.function.unParenthesized;
     FunctionElementImpl closureElement = closure.declaredElement;
-    if (AnalysisDriver.useSummary2) {
-      expect(closureElement.enclosingElement, same(variable.declaredElement));
-    } else {
-      expect(closureElement.enclosingElement, same(variableInitializer));
-    }
+    expect(closureElement.enclosingElement, same(variableInitializer));
   }
 
   test_conditionalExpression() async {
diff --git a/pkg/analyzer/test/src/dart/analysis/index_test.dart b/pkg/analyzer/test/src/dart/analysis/index_test.dart
index a4217fe..56fb0c4 100644
--- a/pkg/analyzer/test/src/dart/analysis/index_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/index_test.dart
@@ -883,6 +883,19 @@
     assertThat(element)..isReferencedAt('p: 1', true);
   }
 
+  test_isReferencedBy_ParameterElement_genericFunctionType() async {
+    await _indexTestUnit('''
+typedef F = void Function({int p});
+
+void main() {
+  F f;
+  f(p: 0);
+}
+''');
+    // We should not crash because of reference to "p" - a named parameter
+    // of a generic function type.
+  }
+
   test_isReferencedBy_ParameterElement_optionalPositional() async {
     await _indexTestUnit('''
 foo([p]) {
diff --git a/pkg/analyzer/test/src/dart/ast/utilities_test.dart b/pkg/analyzer/test/src/dart/ast/utilities_test.dart
index 31e9a56..5771180 100644
--- a/pkg/analyzer/test/src/dart/ast/utilities_test.dart
+++ b/pkg/analyzer/test/src/dart/ast/utilities_test.dart
@@ -640,7 +640,7 @@
   void test_visitPartDirective() {
     PartDirective fromNode = AstTestFactory.partDirective2("part.dart");
     LibraryElement element = new LibraryElementImpl.forNode(
-        null, null, AstTestFactory.libraryIdentifier2(["lib"]));
+        null, null, AstTestFactory.libraryIdentifier2(["lib"]), true);
     fromNode.element = element;
     PartDirective toNode = AstTestFactory.partDirective2("part.dart");
     ResolutionCopier.copyResolutionData(fromNode, toNode);
@@ -651,7 +651,7 @@
     PartOfDirective fromNode = AstTestFactory.partOfDirective(
         AstTestFactory.libraryIdentifier2(["lib"]));
     LibraryElement element = new LibraryElementImpl.forNode(
-        null, null, AstTestFactory.libraryIdentifier2(["lib"]));
+        null, null, AstTestFactory.libraryIdentifier2(["lib"]), true);
     fromNode.element = element;
     PartOfDirective toNode = AstTestFactory.partOfDirective(
         AstTestFactory.libraryIdentifier2(["lib"]));
diff --git a/pkg/analyzer/test/src/dart/constant/value_test.dart b/pkg/analyzer/test/src/dart/constant/value_test.dart
index b6c7046..521182b 100644
--- a/pkg/analyzer/test/src/dart/constant/value_test.dart
+++ b/pkg/analyzer/test/src/dart/constant/value_test.dart
@@ -595,10 +595,6 @@
     expect(_doubleValue(null).hasKnownValue, isFalse);
   }
 
-  void test_hasKnownValue_dynamic() {
-    expect(_dynamicValue().hasKnownValue, isTrue);
-  }
-
   void test_hasKnownValue_int_known() {
     expect(_intValue(23).hasKnownValue, isTrue);
   }
@@ -611,10 +607,6 @@
     expect(_listValue().hasKnownValue, isTrue);
   }
 
-  void test_hasKnownValue_list_invalidElement() {
-    expect(_listValue([_dynamicValue()]).hasKnownValue, isTrue);
-  }
-
   void test_hasKnownValue_list_valid() {
     expect(_listValue([_intValue(23)]).hasKnownValue, isTrue);
   }
@@ -623,16 +615,6 @@
     expect(_mapValue().hasKnownValue, isTrue);
   }
 
-  void test_hasKnownValue_map_invalidKey() {
-    expect(_mapValue([_dynamicValue(), _stringValue("value")]).hasKnownValue,
-        isTrue);
-  }
-
-  void test_hasKnownValue_map_invalidValue() {
-    expect(_mapValue([_stringValue("key"), _dynamicValue()]).hasKnownValue,
-        isTrue);
-  }
-
   void test_hasKnownValue_map_valid() {
     expect(
         _mapValue([_stringValue("key"), _stringValue("value")]).hasKnownValue,
@@ -643,10 +625,6 @@
     expect(_nullValue().hasKnownValue, isTrue);
   }
 
-  void test_hasKnownValue_num() {
-    expect(_numValue().hasKnownValue, isFalse);
-  }
-
   void test_hasKnownValue_string_known() {
     expect(_stringValue("twenty-three").hasKnownValue, isTrue);
   }
@@ -801,10 +779,6 @@
     expect(_doubleValue(null).isBoolNumStringOrNull, isTrue);
   }
 
-  void test_isBoolNumStringOrNull_dynamic() {
-    expect(_dynamicValue().isBoolNumStringOrNull, isTrue);
-  }
-
   void test_isBoolNumStringOrNull_int_known() {
     expect(_intValue(23).isBoolNumStringOrNull, isTrue);
   }
@@ -821,10 +795,6 @@
     expect(_nullValue().isBoolNumStringOrNull, isTrue);
   }
 
-  void test_isBoolNumStringOrNull_num() {
-    expect(_numValue().isBoolNumStringOrNull, isTrue);
-  }
-
   void test_isBoolNumStringOrNull_string_known() {
     expect(_stringValue("twenty-three").isBoolNumStringOrNull, isTrue);
   }
@@ -1944,11 +1914,6 @@
     }
   }
 
-  DartObjectImpl _dynamicValue() {
-    return new DartObjectImpl(
-        _typeProvider.nullType, DynamicState.DYNAMIC_STATE);
-  }
-
   DartObjectImpl _intValue(int value) {
     if (value == null) {
       return new DartObjectImpl(_typeProvider.intType, IntState.UNKNOWN_VALUE);
@@ -1977,10 +1942,6 @@
     return new DartObjectImpl(_typeProvider.nullType, NullState.NULL_STATE);
   }
 
-  DartObjectImpl _numValue() {
-    return new DartObjectImpl(_typeProvider.nullType, NumState.UNKNOWN_VALUE);
-  }
-
   DartObjectImpl _setValue([Set<DartObjectImpl> elements]) {
     return new DartObjectImpl(_typeProvider.setType,
         new SetState(elements ?? new Set<DartObjectImpl>()));
diff --git a/pkg/analyzer/test/src/dart/element/element_test.dart b/pkg/analyzer/test/src/dart/element/element_test.dart
index 1abce89..bc41dcb 100644
--- a/pkg/analyzer/test/src/dart/element/element_test.dart
+++ b/pkg/analyzer/test/src/dart/element/element_test.dart
@@ -3559,7 +3559,7 @@
   void test_creation() {
     expect(
         new LibraryElementImpl.forNode(createAnalysisContext(), null,
-            AstTestFactory.libraryIdentifier2(["l"])),
+            AstTestFactory.libraryIdentifier2(["l"]), true),
         isNotNull);
   }
 
@@ -3646,7 +3646,7 @@
   void test_setImports() {
     AnalysisContext context = createAnalysisContext();
     LibraryElementImpl library = new LibraryElementImpl.forNode(
-        context, null, AstTestFactory.libraryIdentifier2(["l1"]));
+        context, null, AstTestFactory.libraryIdentifier2(["l1"]), true);
     List<ImportElementImpl> expectedImports = [
       ElementFactory.importFor(ElementFactory.library(context, "l2"), null),
       ElementFactory.importFor(ElementFactory.library(context, "l3"), null)
diff --git a/pkg/analyzer/test/src/dart/element/type_algebra_test.dart b/pkg/analyzer/test/src/dart/element/type_algebra_test.dart
index 5aa1321..d3bf71a 100644
--- a/pkg/analyzer/test/src/dart/element/type_algebra_test.dart
+++ b/pkg/analyzer/test/src/dart/element/type_algebra_test.dart
@@ -92,7 +92,7 @@
       {t: intType},
       {t: BottomTypeImpl.instance},
     ).substituteType(type);
-    assertElementTypeString(result, '(<bottom>) → int');
+    assertElementTypeString(result, '(Never) → int');
   }
 }
 
diff --git a/pkg/analyzer/test/src/dart/resolution/export_test.dart b/pkg/analyzer/test/src/dart/resolution/export_test.dart
new file mode 100644
index 0000000..565f72d
--- /dev/null
+++ b/pkg/analyzer/test/src/dart/resolution/export_test.dart
@@ -0,0 +1,32 @@
+// 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/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'driver_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(ExportResolutionTest);
+  });
+}
+
+@reflectiveTest
+class ExportResolutionTest extends DriverResolutionTest {
+  /// Test that both getter and setter are in the export namespace.
+  test_namespace_getter_setter() async {
+    newFile('/test/lib/a.dart', content: r'''
+get f => null;
+set f(_) {}
+''');
+    addTestFile(r'''
+export 'a.dart';
+''');
+    await resolveTestFile();
+    var exportNamespace = result.libraryElement.exportNamespace;
+    expect(exportNamespace.get('f'), isNotNull);
+    expect(exportNamespace.get('f='), isNotNull);
+  }
+}
diff --git a/pkg/analyzer/test/src/dart/resolution/generic_function_type_test.dart b/pkg/analyzer/test/src/dart/resolution/generic_function_type_test.dart
new file mode 100644
index 0000000..59062c6
--- /dev/null
+++ b/pkg/analyzer/test/src/dart/resolution/generic_function_type_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/dart/ast/ast.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'driver_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(GenericFunctionTypeResolutionTest);
+  });
+}
+
+@reflectiveTest
+class GenericFunctionTypeResolutionTest extends DriverResolutionTest {
+  /// Test that when [GenericFunctionType] is used in a constant variable
+  /// initializer, analysis does not throw an exception; and that the next
+  /// [GenericFunctionType] is also handled correctly.
+  test_constInitializer_field_static_const() async {
+    await assertNoErrorsInCode('''
+class A<T> {
+  const A();
+}
+
+class B {
+  static const x = const A<bool Function()>();
+}
+
+int Function(int a) y;
+''');
+  }
+
+  /// Test that when [GenericFunctionType] is used in a constant variable
+  /// initializer, analysis does not throw an exception; and that the next
+  /// [GenericFunctionType] is also handled correctly.
+  test_constInitializer_topLevel() async {
+    await assertNoErrorsInCode('''
+class A<T> {
+  const A();
+}
+
+const x = const A<bool Function()>();
+
+int Function(int a) y;
+''');
+  }
+}
diff --git a/pkg/analyzer/test/src/dart/resolution/namespace_test.dart b/pkg/analyzer/test/src/dart/resolution/namespace_test.dart
new file mode 100644
index 0000000..7cceecc
--- /dev/null
+++ b/pkg/analyzer/test/src/dart/resolution/namespace_test.dart
@@ -0,0 +1,38 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/dart/analysis/features.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'driver_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(ImportResolutionTest);
+    defineReflectiveTests(ImportResolutionWithNnbdTest);
+  });
+}
+
+@reflectiveTest
+class ImportResolutionTest extends DriverResolutionTest {
+  test_overrideCoreType_Never() async {
+    newFile('/test/lib/declares_never.dart', content: '''
+class Never {}
+''');
+    assertNoErrorsInCode(r'''
+import 'declares_never.dart';
+
+Never f() => throw 'foo';
+''');
+  }
+}
+
+@reflectiveTest
+class ImportResolutionWithNnbdTest extends ImportResolutionTest {
+  @override
+  AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
+    ..contextFeatures = new FeatureSet.forTesting(
+        sdkVersion: '2.3.0', additionalFeatures: [Feature.non_nullable]);
+}
diff --git a/pkg/analyzer/test/src/dart/resolution/test_all.dart b/pkg/analyzer/test/src/dart/resolution/test_all.dart
index ebd712a..10b3832 100644
--- a/pkg/analyzer/test/src/dart/resolution/test_all.dart
+++ b/pkg/analyzer/test/src/dart/resolution/test_all.dart
@@ -12,11 +12,13 @@
 import 'constructor_test.dart' as constructor;
 import 'definite_assignment_test.dart' as definite_assignment;
 import 'enum_test.dart' as enum_resolution;
+import 'export_test.dart' as export_;
 import 'flow_analysis_test.dart' as flow_analysis;
 import 'for_element_test.dart' as for_element;
 import 'for_in_test.dart' as for_in;
 import 'function_expression_invocation_test.dart'
     as function_expression_invocation;
+import 'generic_function_type_test.dart' as generic_function_type;
 import 'generic_type_alias_test.dart' as generic_type_alias;
 import 'import_prefix_test.dart' as import_prefix;
 import 'instance_creation_test.dart' as instance_creation;
@@ -26,6 +28,7 @@
     as instance_member_inference_mixin;
 import 'method_invocation_test.dart' as method_invocation;
 import 'mixin_test.dart' as mixin_resolution;
+import 'namespace_test.dart' as namespace;
 import 'non_nullable_test.dart' as non_nullable;
 import 'optional_const_test.dart' as optional_const;
 import 'property_access_test.dart' as property_access;
@@ -42,10 +45,12 @@
     constructor.main();
     definite_assignment.main();
     enum_resolution.main();
+    export_.main();
     flow_analysis.main();
     for_element.main();
     for_in.main();
     function_expression_invocation.main();
+    generic_function_type.main();
     generic_type_alias.main();
     import_prefix.main();
     instance_creation.main();
@@ -53,6 +58,7 @@
     instance_member_inference_mixin.main();
     method_invocation.main();
     mixin_resolution.main();
+    namespace.main();
     non_nullable.main();
     optional_const.main();
     property_access.main();
diff --git a/pkg/analyzer/test/src/dart/resolution/type_inference/equality_expressions_test.dart b/pkg/analyzer/test/src/dart/resolution/type_inference/equality_expressions_test.dart
new file mode 100644
index 0000000..d0bf2ff
--- /dev/null
+++ b/pkg/analyzer/test/src/dart/resolution/type_inference/equality_expressions_test.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:analyzer/dart/analysis/features.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../driver_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(EqualTest);
+    defineReflectiveTests(EqualWithNnbdTest);
+    defineReflectiveTests(NotEqualTest);
+    defineReflectiveTests(NotEqualWithNnbdTest);
+  });
+}
+
+@reflectiveTest
+class EqualTest extends DriverResolutionTest {
+  test_simple() async {
+    addTestFile('''
+void f(Object a, Object b) {
+  var c = a == b;
+  print(c);
+}
+''');
+    await resolveTestFile();
+    assertType(findNode.simple('c)'), 'bool');
+  }
+}
+
+@reflectiveTest
+class EqualWithNnbdTest extends EqualTest {
+  @override
+  AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
+    ..contextFeatures = new FeatureSet.forTesting(
+        sdkVersion: '2.3.0', additionalFeatures: [Feature.non_nullable]);
+
+  @override
+  bool get typeToStringWithNullability => true;
+}
+
+@reflectiveTest
+class NotEqualTest extends DriverResolutionTest {
+  test_simple() async {
+    addTestFile('''
+void f(Object a, Object b) {
+  var c = a != b;
+  print(c);
+}
+''');
+    await resolveTestFile();
+    assertType(findNode.simple('c)'), 'bool');
+  }
+}
+
+@reflectiveTest
+class NotEqualWithNnbdTest extends NotEqualTest {
+  @override
+  AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
+    ..contextFeatures = new FeatureSet.forTesting(
+        sdkVersion: '2.3.0', additionalFeatures: [Feature.non_nullable]);
+
+  @override
+  bool get typeToStringWithNullability => true;
+}
diff --git a/pkg/analyzer/test/src/dart/resolution/type_inference/logical_boolean_expressions_test.dart b/pkg/analyzer/test/src/dart/resolution/type_inference/logical_boolean_expressions_test.dart
new file mode 100644
index 0000000..7f26d21
--- /dev/null
+++ b/pkg/analyzer/test/src/dart/resolution/type_inference/logical_boolean_expressions_test.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:analyzer/dart/analysis/features.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../driver_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(LogicalAndTest);
+    defineReflectiveTests(LogicalAndWithNnbdTest);
+    defineReflectiveTests(LogicalOrTest);
+    defineReflectiveTests(LogicalOrWithNnbdTest);
+  });
+}
+
+@reflectiveTest
+class LogicalAndTest extends DriverResolutionTest {
+  test_simple() async {
+    addTestFile('''
+void f(bool a, bool b) {
+  var c = a && b;
+  print(c);
+}
+''');
+    await resolveTestFile();
+    assertType(findNode.simple('c)'), 'bool');
+  }
+}
+
+@reflectiveTest
+class LogicalAndWithNnbdTest extends LogicalAndTest {
+  @override
+  AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
+    ..contextFeatures = new FeatureSet.forTesting(
+        sdkVersion: '2.3.0', additionalFeatures: [Feature.non_nullable]);
+
+  @override
+  bool get typeToStringWithNullability => true;
+}
+
+@reflectiveTest
+class LogicalOrTest extends DriverResolutionTest {
+  test_simple() async {
+    addTestFile('''
+void f(bool a, bool b) {
+  var c = a || b;
+  print(c);
+}
+''');
+    await resolveTestFile();
+    assertType(findNode.simple('c)'), 'bool');
+  }
+}
+
+@reflectiveTest
+class LogicalOrWithNnbdTest extends LogicalOrTest {
+  @override
+  AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
+    ..contextFeatures = new FeatureSet.forTesting(
+        sdkVersion: '2.3.0', additionalFeatures: [Feature.non_nullable]);
+
+  @override
+  bool get typeToStringWithNullability => true;
+}
diff --git a/pkg/analyzer/test/src/dart/resolution/type_inference/prefix_expressions_test.dart b/pkg/analyzer/test/src/dart/resolution/type_inference/prefix_expressions_test.dart
new file mode 100644
index 0000000..2f8bf00
--- /dev/null
+++ b/pkg/analyzer/test/src/dart/resolution/type_inference/prefix_expressions_test.dart
@@ -0,0 +1,41 @@
+// 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/analysis/features.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../driver_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(NotTest);
+    defineReflectiveTests(NotWithNnbdTest);
+  });
+}
+
+@reflectiveTest
+class NotTest extends DriverResolutionTest {
+  test_simple() async {
+    addTestFile('''
+void f(bool a) {
+  var b = !a;
+  print(b);
+}
+''');
+    await resolveTestFile();
+    assertType(findNode.simple('b)'), 'bool');
+  }
+}
+
+@reflectiveTest
+class NotWithNnbdTest extends NotTest {
+  @override
+  AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
+    ..contextFeatures = new FeatureSet.forTesting(
+        sdkVersion: '2.3.0', additionalFeatures: [Feature.non_nullable]);
+
+  @override
+  bool get typeToStringWithNullability => true;
+}
diff --git a/pkg/analyzer/test/src/dart/resolution/type_inference/test_all.dart b/pkg/analyzer/test/src/dart/resolution/type_inference/test_all.dart
index 54ada38..8d7aae0 100644
--- a/pkg/analyzer/test/src/dart/resolution/type_inference/test_all.dart
+++ b/pkg/analyzer/test/src/dart/resolution/type_inference/test_all.dart
@@ -4,14 +4,22 @@
 
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
+import 'equality_expressions_test.dart' as equality_expressions;
 import 'list_literal_test.dart' as list_literal;
+import 'logical_boolean_expressions_test.dart' as logical_boolean_expressions;
 import 'map_literal_test.dart' as map_literal;
+import 'prefix_expressions_test.dart' as prefix_expressions;
 import 'set_literal_test.dart' as set_literal;
+import 'type_test_expressions_test.dart' as type_test_expressions;
 
 main() {
   defineReflectiveSuite(() {
+    equality_expressions.main();
     list_literal.main();
+    logical_boolean_expressions.main();
     map_literal.main();
+    prefix_expressions.main();
     set_literal.main();
+    type_test_expressions.main();
   }, name: 'type inference');
 }
diff --git a/pkg/analyzer/test/src/dart/resolution/type_inference/type_test_expressions_test.dart b/pkg/analyzer/test/src/dart/resolution/type_inference/type_test_expressions_test.dart
new file mode 100644
index 0000000..9dd6039
--- /dev/null
+++ b/pkg/analyzer/test/src/dart/resolution/type_inference/type_test_expressions_test.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:analyzer/dart/analysis/features.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../driver_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(IsNotTest);
+    defineReflectiveTests(IsNotWithNnbdTest);
+    defineReflectiveTests(IsTest);
+    defineReflectiveTests(IsWithNnbdTest);
+  });
+}
+
+@reflectiveTest
+class IsNotTest extends DriverResolutionTest {
+  test_simple() async {
+    addTestFile('''
+void f(Object a) {
+  var b = a is! String;
+  print(b);
+}
+''');
+    await resolveTestFile();
+    assertType(findNode.simple('b)'), 'bool');
+  }
+}
+
+@reflectiveTest
+class IsNotWithNnbdTest extends IsNotTest {
+  @override
+  AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
+    ..contextFeatures = new FeatureSet.forTesting(
+        sdkVersion: '2.3.0', additionalFeatures: [Feature.non_nullable]);
+
+  @override
+  bool get typeToStringWithNullability => true;
+}
+
+@reflectiveTest
+class IsTest extends DriverResolutionTest {
+  test_simple() async {
+    addTestFile('''
+void f(Object a) {
+  var b = a is String;
+  print(b);
+}
+''');
+    await resolveTestFile();
+    assertType(findNode.simple('b)'), 'bool');
+  }
+}
+
+@reflectiveTest
+class IsWithNnbdTest extends IsTest {
+  @override
+  AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
+    ..contextFeatures = new FeatureSet.forTesting(
+        sdkVersion: '2.3.0', additionalFeatures: [Feature.non_nullable]);
+
+  @override
+  bool get typeToStringWithNullability => true;
+}
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 8c5c365..aa13cab 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
@@ -121,6 +121,19 @@
     expect(otherFileResult.errors, isEmpty);
   }
 
+  test_fromEnvironment_assertInitializer() async {
+    await assertNoErrorsInCode('''
+class A {
+  const A(int x) : assert(x > 5);
+}
+
+main() {
+  var c = const A(int.fromEnvironment('x'));
+  print(c);
+}
+''');
+  }
+
   test_ifElement_false_thenNotEvaluated() async {
     await assertErrorsInCode(
         '''
@@ -214,4 +227,16 @@
 }
 ''');
   }
+
+  test_fromEnvironment_ifElement() async {
+    await assertNoErrorsInCode('''
+const b = bool.fromEnvironment('foo');
+
+main() {
+  const l1 = [1, 2, 3];
+  const l2 = [if (b) ...l1];
+  print(l2);
+}
+''');
+  }
 }
diff --git a/pkg/analyzer/test/src/diagnostics/extends_non_class_test.dart b/pkg/analyzer/test/src/diagnostics/extends_non_class_test.dart
new file mode 100644
index 0000000..1859d26
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/extends_non_class_test.dart
@@ -0,0 +1,36 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/dart/analysis/features.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(ExtendsNonClassTest);
+    defineReflectiveTests(ExtendsNonClassWithNnbdTest);
+  });
+}
+
+@reflectiveTest
+class ExtendsNonClassTest extends DriverResolutionTest {}
+
+@reflectiveTest
+class ExtendsNonClassWithNnbdTest extends ExtendsNonClassTest {
+  @override
+  AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
+    ..contextFeatures = new FeatureSet.forTesting(
+        sdkVersion: '2.3.0', additionalFeatures: [Feature.non_nullable]);
+
+  test_Never() async {
+    await assertErrorsInCode('''
+class A extends Never {}
+''', [
+      error(CompileTimeErrorCode.EXTENDS_NON_CLASS, 16, 5),
+    ]);
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/implements_non_class_test.dart b/pkg/analyzer/test/src/diagnostics/implements_non_class_test.dart
new file mode 100644
index 0000000..176830e
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/implements_non_class_test.dart
@@ -0,0 +1,36 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/dart/analysis/features.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(ImplementsNonClassTest);
+    defineReflectiveTests(ImplementsNonClassWithNnbdTest);
+  });
+}
+
+@reflectiveTest
+class ImplementsNonClassTest extends DriverResolutionTest {}
+
+@reflectiveTest
+class ImplementsNonClassWithNnbdTest extends ImplementsNonClassTest {
+  @override
+  AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
+    ..contextFeatures = new FeatureSet.forTesting(
+        sdkVersion: '2.3.0', additionalFeatures: [Feature.non_nullable]);
+
+  test_Never() async {
+    await assertErrorsInCode('''
+class A implements Never {}
+''', [
+      error(CompileTimeErrorCode.IMPLEMENTS_NON_CLASS, 19, 5),
+    ]);
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/mixin_of_non_class_test.dart b/pkg/analyzer/test/src/diagnostics/mixin_of_non_class_test.dart
new file mode 100644
index 0000000..6e5666d
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/mixin_of_non_class_test.dart
@@ -0,0 +1,36 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/dart/analysis/features.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(MixinOfNonClassTest);
+    defineReflectiveTests(MixinOfNonClassWithNnbdTest);
+  });
+}
+
+@reflectiveTest
+class MixinOfNonClassTest extends DriverResolutionTest {}
+
+@reflectiveTest
+class MixinOfNonClassWithNnbdTest extends MixinOfNonClassTest {
+  @override
+  AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
+    ..contextFeatures = new FeatureSet.forTesting(
+        sdkVersion: '2.3.0', additionalFeatures: [Feature.non_nullable]);
+
+  test_Never() async {
+    await assertErrorsInCode('''
+class A with Never {}
+''', [
+      error(CompileTimeErrorCode.MIXIN_OF_NON_CLASS, 13, 5),
+    ]);
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/mixin_super_class_constraint_non_interface_test.dart b/pkg/analyzer/test/src/diagnostics/mixin_super_class_constraint_non_interface_test.dart
index 1479299..07fbff3 100644
--- a/pkg/analyzer/test/src/diagnostics/mixin_super_class_constraint_non_interface_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/mixin_super_class_constraint_non_interface_test.dart
@@ -27,7 +27,6 @@
     ..contextFeatures = new FeatureSet.forTesting(
         sdkVersion: '2.3.0', additionalFeatures: [Feature.non_nullable]);
 
-  @failingTest
   test_Never() async {
     await assertErrorsInCode('''
 mixin M on Never {}
diff --git a/pkg/analyzer/test/src/diagnostics/sdk_version_never_test.dart b/pkg/analyzer/test/src/diagnostics/sdk_version_never_test.dart
new file mode 100644
index 0000000..749e00f
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/sdk_version_never_test.dart
@@ -0,0 +1,48 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/dart/analysis/features.dart';
+import 'package:analyzer/src/dart/error/hint_codes.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'sdk_constraint_verifier_support.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(SdkVersionNeverTest);
+  });
+}
+
+@reflectiveTest
+class SdkVersionNeverTest extends SdkConstraintVerifierTest {
+  @override
+  AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
+    ..contextFeatures = new FeatureSet.forTesting(
+        sdkVersion: '2.3.0', additionalFeatures: [Feature.non_nullable]);
+
+  @failingTest
+  test_equals() async {
+    // This test cannot pass because there is no version number that is equal to
+    // when non-nullable was enabled.
+    await verifyVersion('2.1.0', '''
+Never sink;
+''');
+  }
+
+  @failingTest
+  test_greaterThan() async {
+    // This test cannot pass because there is no version number that is equal to
+    // when non-nullable was enabled.
+    await verifyVersion('2.1.0', '''
+Never sink;
+''');
+  }
+
+  test_lessThan() async {
+    await verifyVersion('2.3.0', '''
+Never sink;
+''', errorCodes: [HintCode.SDK_VERSION_NEVER]);
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/test_all.dart b/pkg/analyzer/test/src/diagnostics/test_all.dart
index 5a11626..fff3f23 100644
--- a/pkg/analyzer/test/src/diagnostics/test_all.dart
+++ b/pkg/analyzer/test/src/diagnostics/test_all.dart
@@ -32,7 +32,9 @@
 import 'equal_elements_in_const_set_test.dart' as equal_elements_in_const_set;
 import 'equal_keys_in_const_map_test.dart' as equal_keys_in_const_map;
 import 'expression_in_map_test.dart' as expression_in_map;
+import 'extends_non_class_test.dart' as extends_non_class;
 import 'final_not_initialized_test.dart' as final_not_initialized;
+import 'implements_non_class_test.dart' as implements_non_class;
 import 'implicit_this_reference_in_initializer_test.dart'
     as implicit_this_reference_in_initializer;
 import 'import_deferred_library_with_load_function_test.dart'
@@ -69,6 +71,7 @@
     as missing_default_value_for_paramter;
 import 'missing_required_param_test.dart' as missing_required_param;
 import 'missing_return_test.dart' as missing_return;
+import 'mixin_of_non_class_test.dart' as mixin_of_non_class;
 import 'mixin_on_sealed_class_test.dart' as mixin_on_sealed_class;
 import 'mixin_super_class_constraint_non_interface_test.dart'
     as mixin_super_class_constraint_non_interface;
@@ -128,6 +131,7 @@
     as sdk_version_gt_gt_gt_operator;
 import 'sdk_version_is_expression_in_const_context_test.dart'
     as sdk_version_is_expression_in_const_context;
+import 'sdk_version_never_test.dart' as sdk_version_never;
 import 'sdk_version_set_literal_test.dart' as sdk_version_set_literal;
 import 'sdk_version_ui_as_code_test.dart' as sdk_version_ui_as_code;
 import 'set_element_type_not_assignable_test.dart'
@@ -184,7 +188,9 @@
     equal_elements_in_const_set.main();
     equal_keys_in_const_map.main();
     expression_in_map.main();
+    extends_non_class.main();
     final_not_initialized.main();
+    implements_non_class.main();
     implicit_this_reference_in_initializer.main();
     import_deferred_library_with_load_function.main();
     invalid_assignment.main();
@@ -209,6 +215,7 @@
     missing_default_value_for_paramter.main();
     missing_required_param.main();
     missing_return.main();
+    mixin_of_non_class.main();
     mixin_on_sealed_class.main();
     mixin_super_class_constraint_non_interface.main();
     must_be_immutable.main();
@@ -248,6 +255,7 @@
     sdk_version_eq_eq_operator.main();
     sdk_version_gt_gt_gt_operator.main();
     sdk_version_is_expression_in_const_context.main();
+    sdk_version_never.main();
     sdk_version_set_literal.main();
     sdk_version_ui_as_code.main();
     set_element_type_not_assignable.main();
diff --git a/pkg/analyzer/test/src/diagnostics/unchecked_use_of_nullable_value_test.dart b/pkg/analyzer/test/src/diagnostics/unchecked_use_of_nullable_value_test.dart
index 5ee8a4e..d008f0a 100644
--- a/pkg/analyzer/test/src/diagnostics/unchecked_use_of_nullable_value_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/unchecked_use_of_nullable_value_test.dart
@@ -156,10 +156,7 @@
 ''');
   }
 
-  @failingTest
   test_invoke_dynamicFunctionType_nullable() async {
-    // test is failing because nullable function invocations aren't being
-    // resolved correctly
     await assertErrorCodesInCode(r'''
 m() {
   Function? x;
diff --git a/pkg/analyzer/test/src/lint/lint_rule_test.dart b/pkg/analyzer/test/src/lint/lint_rule_test.dart
new file mode 100644
index 0000000..55b1e3e5
--- /dev/null
+++ b/pkg/analyzer/test/src/lint/lint_rule_test.dart
@@ -0,0 +1,113 @@
+// 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/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/src/dart/ast/ast.dart';
+import 'package:analyzer/src/dart/ast/token.dart';
+import 'package:analyzer/src/dart/error/lint_codes.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/lint/linter.dart';
+import 'package:test/test.dart';
+
+import '../../generated/test_support.dart';
+
+main() {
+  group('lint rule', () {
+    group('error code reporting', () {
+      test('reportLintForToken (custom)', () {
+        final rule = TestRule();
+        final reporter = CollectingReporter(
+            GatheringErrorListener(), new _MockSource('mock'));
+        rule.reporter = reporter;
+
+        rule.reportLintForToken(Token.eof(0),
+            errorCode: customCode, ignoreSyntheticTokens: false);
+        expect(reporter.code, customCode);
+      });
+      test('reportLintForToken (default)', () {
+        final rule = TestRule();
+        final reporter = CollectingReporter(
+            GatheringErrorListener(), new _MockSource('mock'));
+        rule.reporter = reporter;
+
+        rule.reportLintForToken(Token.eof(0), ignoreSyntheticTokens: false);
+        expect(reporter.code, rule.lintCode);
+      });
+      test('reportLint (custom)', () {
+        final rule = TestRule();
+        final reporter = CollectingReporter(
+            GatheringErrorListener(), new _MockSource('mock'));
+        rule.reporter = reporter;
+
+        final node =
+            EmptyStatementImpl(new SimpleToken(TokenType.SEMICOLON, 0));
+        rule.reportLint(node, errorCode: customCode);
+        expect(reporter.code, customCode);
+      });
+      test('reportLint (default)', () {
+        final rule = TestRule();
+        final reporter = CollectingReporter(
+            GatheringErrorListener(), new _MockSource('mock'));
+        rule.reporter = reporter;
+
+        final node =
+            EmptyStatementImpl(new SimpleToken(TokenType.SEMICOLON, 0));
+        rule.reportLint(node);
+        expect(reporter.code, rule.lintCode);
+      });
+    });
+  });
+}
+
+const LintCode customCode = const LintCode(
+    'hash_and_equals', 'Override `==` if overriding `hashCode`.',
+    correction: 'Implement `==`.');
+
+class CollectingReporter extends ErrorReporter {
+  ErrorCode code;
+
+  CollectingReporter(AnalysisErrorListener listener, Source source)
+      : super(listener, source);
+  void reportErrorForElement(ErrorCode errorCode, Element element,
+      [List<Object> arguments]) {
+    code = errorCode;
+  }
+
+  void reportErrorForNode(ErrorCode errorCode, AstNode node,
+      [List<Object> arguments]) {
+    code = errorCode;
+  }
+
+  @override
+  void reportErrorForToken(ErrorCode errorCode, Token token,
+      [List<Object> arguments]) {
+    code = errorCode;
+  }
+}
+
+class TestRule extends LintRule {
+  TestRule()
+      : super(
+          name: 'test_rule',
+          description: '',
+          details: '... tl;dr ...',
+          group: Group.errors,
+        );
+}
+
+class _MockSource implements Source {
+  @override
+  final String fullName;
+
+  _MockSource(this.fullName);
+
+  @override
+  noSuchMethod(Invocation invocation) {
+    throw new StateError('Unexpected invocation of ${invocation.memberName}');
+  }
+}
diff --git a/pkg/analyzer/test/src/lint/test_all.dart b/pkg/analyzer/test/src/lint/test_all.dart
index 47596f2..6b1afdc 100644
--- a/pkg/analyzer/test/src/lint/test_all.dart
+++ b/pkg/analyzer/test/src/lint/test_all.dart
@@ -6,6 +6,7 @@
 
 import 'config_test.dart' as config;
 import 'io_test.dart' as io;
+import 'lint_rule_test.dart' as lint_rule;
 import 'linter/test_all.dart' as linter;
 import 'project_test.dart' as project;
 import 'pub_test.dart' as pub;
@@ -14,6 +15,7 @@
   defineReflectiveSuite(() {
     config.main();
     io.main();
+    lint_rule.main();
     linter.main();
     project.main();
     pub.main();
diff --git a/pkg/analyzer/test/src/summary/element_text.dart b/pkg/analyzer/test/src/summary/element_text.dart
index 731f012..14354cc 100644
--- a/pkg/analyzer/test/src/summary/element_text.dart
+++ b/pkg/analyzer/test/src/summary/element_text.dart
@@ -59,7 +59,8 @@
     bool withOffsets: false,
     bool withSyntheticAccessors: false,
     bool withSyntheticFields: false,
-    bool withTypes: false}) {
+    bool withTypes: false,
+    bool annotateNullability: false}) {
   var writer = new _ElementWriter(
       withCodeRanges: withCodeRanges,
       withConstElements: withConstElements,
@@ -67,7 +68,8 @@
       withOffsets: withOffsets,
       withSyntheticAccessors: withSyntheticAccessors,
       withSyntheticFields: withSyntheticFields,
-      withTypes: withTypes);
+      withTypes: withTypes,
+      annotateNullability: annotateNullability);
   writer.writeLibraryElement(library);
 
   String actualText = writer.buffer.toString();
@@ -135,6 +137,7 @@
   final bool withSyntheticAccessors;
   final bool withSyntheticFields;
   final bool withTypes;
+  final bool annotateNullability;
   final StringBuffer buffer = new StringBuffer();
 
   _ElementWriter(
@@ -144,7 +147,8 @@
       this.withOffsets: false,
       this.withSyntheticAccessors: false,
       this.withSyntheticFields: false,
-      this.withTypes: false});
+      this.withTypes: false,
+      this.annotateNullability: false});
 
   bool isDynamicType(DartType type) => type is DynamicTypeImpl;
 
@@ -568,6 +572,17 @@
       }
     } else if (e is DoubleLiteral) {
       buffer.write(e.value);
+    } else if (e is GenericFunctionType) {
+      if (e.returnType != null) {
+        writeNode(e.returnType);
+        buffer.write(' ');
+      }
+      buffer.write('Function');
+      if (e.typeParameters != null) {
+        writeList('<', '>', e.typeParameters.typeParameters, ', ', writeNode);
+      }
+      writeList('(', ')', e.parameters.parameters, ', ', writeNode,
+          includeEmpty: true);
     } else if (e is InstanceCreationExpression) {
       if (e.keyword != null) {
         buffer.write(e.keyword.lexeme);
@@ -657,6 +672,12 @@
       }
       writeList('(', ')', e.argumentList.arguments, ', ', writeNode,
           includeEmpty: true);
+    } else if (e is SimpleFormalParameter) {
+      writeNode(e.type);
+      if (e.identifier != null) {
+        buffer.write(' ');
+        buffer.write(e.identifier.name);
+      }
     } else if (e is SimpleIdentifier) {
       if (withConstElements) {
         buffer.writeln();
@@ -947,6 +968,18 @@
     } else {
       buffer.write(type.displayName);
     }
+    if (annotateNullability) {
+      switch ((type as TypeImpl).nullabilitySuffix) {
+        case NullabilitySuffix.none:
+          break;
+        case NullabilitySuffix.question:
+          buffer.write('?');
+          break;
+        case NullabilitySuffix.star:
+          buffer.write('*');
+          break;
+      }
+    }
   }
 
   void writeType2(DartType type) {
diff --git a/pkg/analyzer/test/src/summary/linker_test.dart b/pkg/analyzer/test/src/summary/linker_test.dart
index ab21dcd..0e738780 100644
--- a/pkg/analyzer/test/src/summary/linker_test.dart
+++ b/pkg/analyzer/test/src/summary/linker_test.dart
@@ -327,7 +327,7 @@
     ClassElementForLink_Class cls = library.getContainedName('C');
     expect(cls.fields, hasLength(1));
     var field = cls.fields[0];
-    expect(field.type.toString(), '(<bottom>) → int');
+    expect(field.type.toString(), '(Never) → int');
   }
 
   void test_inferredType_instanceField_dynamic() {
diff --git a/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart b/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart
index 12b725e..041f812 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart
@@ -2,12 +2,13 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'package:analyzer/dart/analysis/session.dart';
 import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/src/dart/analysis/restricted_analysis_context.dart';
+import 'package:analyzer/src/dart/analysis/session.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/generated/type_system.dart';
 import 'package:analyzer/src/summary/idl.dart';
 import 'package:analyzer/src/summary/summary_sdk.dart';
 import 'package:analyzer/src/summary2/link.dart';
@@ -50,14 +51,25 @@
       );
     }
 
-    var sdkLinkResult = link(
-      AnalysisOptionsImpl(),
-      sourceFactory,
-      declaredVariables,
-      [],
-      inputLibraries,
+    var rootReference = Reference.root();
+    var dartCoreRef = rootReference.getChild('dart:core');
+    dartCoreRef.getChild('dynamic').element = DynamicElementImpl.instance;
+    dartCoreRef.getChild('Never').element = NeverElementImpl.instance;
+
+    var elementFactory = LinkedElementFactory(
+      RestrictedAnalysisContext(
+        SynchronousSession(
+          AnalysisOptionsImpl(),
+          declaredVariables,
+        ),
+        sourceFactory,
+      ),
+      _AnalysisSessionForLinking(),
+      rootReference,
     );
 
+    var sdkLinkResult = link(elementFactory, inputLibraries);
+
     var bytes = sdkLinkResult.bundle.toBuffer();
     return _sdkBundle = LinkedNodeBundle.fromBuffer(bytes);
   }
@@ -70,42 +82,49 @@
     var inputLibraries = <LinkInputLibrary>[];
     _addNonDartLibraries(Set(), inputLibraries, source);
 
-    var linkResult = link(
-      AnalysisOptionsImpl(),
+    var analysisContext = RestrictedAnalysisContext(
+      SynchronousSession(
+        AnalysisOptionsImpl()..contextFeatures = featureSet,
+        declaredVariables,
+      ),
       sourceFactory,
-      declaredVariables,
-      [sdkBundle],
-      inputLibraries,
     );
 
-    var analysisContext = _FakeAnalysisContext(sourceFactory);
-
     var rootReference = Reference.root();
     rootReference.getChild('dart:core').getChild('dynamic').element =
         DynamicElementImpl.instance;
+    rootReference.getChild('dart:core').getChild('Never').element =
+        NeverElementImpl.instance;
 
     var elementFactory = LinkedElementFactory(
       analysisContext,
-      null,
+      _AnalysisSessionForLinking(),
       rootReference,
     );
     elementFactory.addBundle(
       LinkedBundleContext(elementFactory, sdkBundle),
     );
+
+    var linkResult = link(
+      elementFactory,
+      inputLibraries,
+    );
+
     elementFactory.addBundle(
       LinkedBundleContext(elementFactory, linkResult.bundle),
     );
 
-    var dartCore = elementFactory.libraryOfUri('dart:core');
-    var dartAsync = elementFactory.libraryOfUri('dart:async');
-    var typeProvider = SummaryTypeProvider()
-      ..initializeCore(dartCore)
-      ..initializeAsync(dartAsync);
-    analysisContext.typeProvider = typeProvider;
-    analysisContext.typeSystem = Dart2TypeSystem(typeProvider);
+    if (analysisContext.typeProvider == null) {
+      var dartCore = elementFactory.libraryOfUri('dart:core');
+      var dartAsync = elementFactory.libraryOfUri('dart:async');
+      var typeProvider = SummaryTypeProvider()
+        ..initializeCore(dartCore)
+        ..initializeAsync(dartAsync);
+      analysisContext.typeProvider = typeProvider;
 
-    dartCore.createLoadLibraryFunction(typeProvider);
-    dartAsync.createLoadLibraryFunction(typeProvider);
+      dartCore.createLoadLibraryFunction(typeProvider);
+      dartAsync.createLoadLibraryFunction(typeProvider);
+    }
 
     return elementFactory.libraryOfUri('${source.uri}');
   }
@@ -197,17 +216,6 @@
   }
 }
 
-class _FakeAnalysisContext implements AnalysisContext {
-  final SourceFactory sourceFactory;
-  TypeProvider typeProvider;
-  Dart2TypeSystem typeSystem;
-
-  _FakeAnalysisContext(this.sourceFactory);
-
-  @override
-  AnalysisOptions get analysisOptions {
-    return AnalysisOptionsImpl();
-  }
-
+class _AnalysisSessionForLinking implements AnalysisSession {
   noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
diff --git a/pkg/analyzer/test/src/summary/resynthesize_common.dart b/pkg/analyzer/test/src/summary/resynthesize_common.dart
index fa7d3c1..b602cc7 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_common.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_common.dart
@@ -8,9 +8,11 @@
 import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/src/context/context.dart';
 import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/summary/idl.dart';
 import 'package:analyzer/src/summary/resynthesize.dart';
@@ -204,6 +206,8 @@
 /// applied to a class implementing [ResynthesizeTestStrategy], along with the
 /// mixin [ResynthesizeTestHelpers].
 mixin ResynthesizeTestCases implements ResynthesizeTestHelpers {
+  FeatureSet get disableNnbd => FeatureSet.forTesting(sdkVersion: '2.2.2');
+
   FeatureSet get enableNnbd =>
       FeatureSet.forTesting(additionalFeatures: [Feature.non_nullable]);
 
@@ -1476,6 +1480,54 @@
 ''');
   }
 
+  test_class_ref_nullability_none() async {
+    featureSet = enableNnbd;
+    var library = await checkLibrary('''
+class C {}
+C c;
+''');
+    checkElementText(
+        library,
+        '''
+class C {
+}
+C c;
+''',
+        annotateNullability: true);
+  }
+
+  test_class_ref_nullability_question() async {
+    featureSet = enableNnbd;
+    var library = await checkLibrary('''
+class C {}
+C? c;
+''');
+    checkElementText(
+        library,
+        '''
+class C {
+}
+C? c;
+''',
+        annotateNullability: true);
+  }
+
+  test_class_ref_nullability_star() async {
+    featureSet = disableNnbd;
+    var library = await checkLibrary('''
+class C {}
+C c;
+''');
+    checkElementText(
+        library,
+        '''
+class C {
+}
+C* c;
+''',
+        annotateNullability: true);
+  }
+
   test_class_setter_abstract() async {
     var library =
         await checkLibrary('abstract class C { void set x(int value); }');
@@ -2380,6 +2432,26 @@
         withConstElements: false);
   }
 
+  test_compilationUnit_nnbd_disabled_via_dart_directive() async {
+    featureSet = enableNnbd;
+    var library = await checkLibrary('''
+// @dart=2.2
+''');
+    expect(library.isNonNullableByDefault, isFalse);
+  }
+
+  test_compilationUnit_nnbd_disabled_via_feature_set() async {
+    featureSet = disableNnbd;
+    var library = await checkLibrary('');
+    expect(library.isNonNullableByDefault, isFalse);
+  }
+
+  test_compilationUnit_nnbd_enabled() async {
+    featureSet = enableNnbd;
+    var library = await checkLibrary('');
+    expect(library.isNonNullableByDefault, isTrue);
+  }
+
   test_const_classField() async {
     var library = await checkLibrary(r'''
 class C {
@@ -5538,6 +5610,25 @@
         withExportScope: true);
   }
 
+  test_export_show_getter_setter() async {
+    addLibrarySource('/a.dart', '''
+get f => null;
+void set f(value) {}
+''');
+    var library = await checkLibrary('export "a.dart" show f;');
+    checkElementText(
+        library,
+        r'''
+export 'a.dart' show f;
+
+--------------------
+Exports:
+  f: a.dart;f?
+  f=: a.dart;f=
+''',
+        withExportScope: true);
+  }
+
   test_export_typedef() async {
     addLibrarySource('/a.dart', 'typedef F();');
     var library = await checkLibrary('export "a.dart";');
@@ -5706,6 +5797,60 @@
 ''');
   }
 
+  test_field_final_hasInitializer_hasConstConstructor() async {
+    var library = await checkLibrary('''
+class C {
+  final x = 42;
+  const C();
+}
+''');
+    checkElementText(library, r'''
+class C {
+  final int x = 42;
+  const C();
+}
+''');
+  }
+
+  test_field_final_hasInitializer_hasConstConstructor_genericFunctionType() async {
+    var library = await checkLibrary('''
+class A<T> {
+  const A();
+}
+class B {
+  final f = const A<int Function(double a)>();
+  const B();
+}
+''');
+    if (isAstBasedSummary) {
+      checkElementText(library, r'''
+class A<T> {
+  const A();
+}
+class B {
+  final A<int Function(double)> f = const
+        A/*location: test.dart;A*/<
+        int/*location: dart:core;int*/ Function(
+        double/*location: dart:core;double*/ a)>();
+  const B();
+}
+''');
+    }
+  }
+
+  test_field_final_hasInitializer_noConstConstructor() async {
+    var library = await checkLibrary('''
+class C {
+  final x = 42;
+}
+''');
+    checkElementText(library, r'''
+class C {
+  final int x;
+}
+''');
+  }
+
   test_field_formal_param_inferred_type_implicit() async {
     var library = await checkLibrary('class C extends D { var v; C(this.v); }'
         ' abstract class D { int get v; }');
@@ -5939,6 +6084,22 @@
 ''');
   }
 
+  test_function_hasImplicitReturnType_false() async {
+    var library = await checkLibrary('''
+int f() => 0;
+''');
+    var f = library.definingCompilationUnit.functions.single;
+    expect(f.hasImplicitReturnType, isFalse);
+  }
+
+  test_function_hasImplicitReturnType_true() async {
+    var library = await checkLibrary('''
+f() => 0;
+''');
+    var f = library.definingCompilationUnit.functions.single;
+    expect(f.hasImplicitReturnType, isTrue);
+  }
+
   test_function_parameter_final() async {
     var library = await checkLibrary('f(final x) {}');
     checkElementText(library, r'''
@@ -6102,6 +6263,45 @@
     expect(y.type.toString(), 'dynamic');
   }
 
+  test_generic_function_type_nullability_none() async {
+    featureSet = enableNnbd;
+    var library = await checkLibrary('''
+void Function() f;
+''');
+    checkElementText(
+        library,
+        '''
+void Function() f;
+''',
+        annotateNullability: true);
+  }
+
+  test_generic_function_type_nullability_question() async {
+    featureSet = enableNnbd;
+    var library = await checkLibrary('''
+void Function()? f;
+''');
+    checkElementText(
+        library,
+        '''
+void Function()? f;
+''',
+        annotateNullability: true);
+  }
+
+  test_generic_function_type_nullability_star() async {
+    featureSet = disableNnbd;
+    var library = await checkLibrary('''
+void Function() f;
+''');
+    checkElementText(
+        library,
+        '''
+void Function()* f;
+''',
+        annotateNullability: true);
+  }
+
   test_generic_gClass_gMethodStatic() async {
     var library = await checkLibrary('''
 class C<T, U> {
@@ -6726,6 +6926,70 @@
 ''');
   }
 
+  test_inferred_type_nullability_class_ref_none() async {
+    featureSet = enableNnbd;
+    addSource('/a.dart', 'int f() => 0;');
+    var library = await checkLibrary('''
+import 'a.dart';
+var x = f();
+''');
+    checkElementText(
+        library,
+        r'''
+import 'a.dart';
+int x;
+''',
+        annotateNullability: true);
+  }
+
+  test_inferred_type_nullability_class_ref_question() async {
+    featureSet = enableNnbd;
+    addSource('/a.dart', 'int? f() => 0;');
+    var library = await checkLibrary('''
+import 'a.dart';
+var x = f();
+''');
+    checkElementText(
+        library,
+        r'''
+import 'a.dart';
+int? x;
+''',
+        annotateNullability: true);
+  }
+
+  test_inferred_type_nullability_function_type_none() async {
+    featureSet = enableNnbd;
+    addSource('/a.dart', 'void Function() f() => () {};');
+    var library = await checkLibrary('''
+import 'a.dart';
+var x = f();
+''');
+    checkElementText(
+        library,
+        r'''
+import 'a.dart';
+void Function() x;
+''',
+        annotateNullability: true);
+  }
+
+  test_inferred_type_nullability_function_type_question() async {
+    featureSet = enableNnbd;
+    addSource('/a.dart', 'void Function()? f() => () {};');
+    var library = await checkLibrary('''
+import 'a.dart';
+var x = f();
+''');
+    checkElementText(
+        library,
+        r'''
+import 'a.dart';
+void Function()? x;
+''',
+        annotateNullability: true);
+  }
+
   test_inferred_type_refers_to_bound_type_param() async {
     var library = await checkLibrary('''
 class C<T> extends D<int, T> {
@@ -8242,6 +8506,28 @@
 ''');
   }
 
+  test_method_hasImplicitReturnType_false() async {
+    var library = await checkLibrary('''
+class C {
+  int m() => 0;
+}
+''');
+    var c = library.definingCompilationUnit.types.single;
+    var m = c.methods.single;
+    expect(m.hasImplicitReturnType, isFalse);
+  }
+
+  test_method_hasImplicitReturnType_true() async {
+    var library = await checkLibrary('''
+class C {
+  m() => 0;
+}
+''');
+    var c = library.definingCompilationUnit.types.single;
+    var m = c.methods.single;
+    expect(m.hasImplicitReturnType, isTrue);
+  }
+
   test_method_inferred_type_nonStatic_implicit_param() async {
     var library = await checkLibrary('class C extends D { void f(value) {} }'
         ' abstract class D { void f(int value); }');
@@ -8969,7 +9255,7 @@
 bool f() => true;
 ''');
     checkElementText(library, r'''
-final int Function(<bottom>) v;
+final int Function(Never) v;
 bool f() {}
 ''');
   }
@@ -9211,6 +9497,91 @@
 ''');
   }
 
+  test_type_param_generic_function_type_nullability_legacy() async {
+    featureSet = disableNnbd;
+    var library = await checkLibrary('''
+T f<T>(T t) {}
+var g = f;
+''');
+    checkElementText(library, '''
+T Function<T>(T) g;
+T f<T>(T t) {}
+''');
+    var g = library.definingCompilationUnit.topLevelVariables[0];
+    var t = (g.type as FunctionType).typeFormals[0];
+    // TypeParameterElement.type has a nullability suffix of `star` regardless
+    // of whether it appears in a migrated library.
+    expect((t.type as TypeImpl).nullabilitySuffix, NullabilitySuffix.star);
+  }
+
+  test_type_param_generic_function_type_nullability_migrated() async {
+    featureSet = enableNnbd;
+    var library = await checkLibrary('''
+T f<T>(T t) {}
+var g = f;
+''');
+    checkElementText(library, '''
+T Function<T>(T) g;
+T f<T>(T t) {}
+''');
+    var g = library.definingCompilationUnit.topLevelVariables[0];
+    var t = (g.type as FunctionType).typeFormals[0];
+    // TypeParameterElement.type has a nullability suffix of `star` regardless
+    // of whether it appears in a migrated library.
+    expect((t.type as TypeImpl).nullabilitySuffix, NullabilitySuffix.star);
+  }
+
+  test_type_param_ref_nullability_none() async {
+    featureSet = enableNnbd;
+    var library = await checkLibrary('''
+class C<T> {
+  T t;
+}
+''');
+    checkElementText(
+        library,
+        '''
+class C<T> {
+  T t;
+}
+''',
+        annotateNullability: true);
+  }
+
+  test_type_param_ref_nullability_question() async {
+    featureSet = enableNnbd;
+    var library = await checkLibrary('''
+class C<T> {
+  T? t;
+}
+''');
+    checkElementText(
+        library,
+        '''
+class C<T> {
+  T? t;
+}
+''',
+        annotateNullability: true);
+  }
+
+  test_type_param_ref_nullability_star() async {
+    featureSet = disableNnbd;
+    var library = await checkLibrary('''
+class C<T> {
+  T t;
+}
+''');
+    checkElementText(
+        library,
+        '''
+class C<T> {
+  T* t;
+}
+''',
+        annotateNullability: true);
+  }
+
   test_type_reference_lib_to_lib() async {
     var library = await checkLibrary('''
 class C {}
diff --git a/pkg/analyzer/test/src/summary/summary_common.dart b/pkg/analyzer/test/src/summary/summary_common.dart
index 14ddf55..10f6ccd 100644
--- a/pkg/analyzer/test/src/summary/summary_common.dart
+++ b/pkg/analyzer/test/src/summary/summary_common.dart
@@ -1604,6 +1604,26 @@
     }
   }
 
+  test_compilationUnit_nnbd_disabled_via_dart_directive() {
+    featureSet = enableNnbd;
+    serializeLibraryText('''
+// @dart=2.2
+''');
+    expect(unlinkedUnits[0].isNNBD, false);
+  }
+
+  test_compilationUnit_nnbd_disabled_via_feature_set() {
+    featureSet = disableNnbd;
+    serializeLibraryText('');
+    expect(unlinkedUnits[0].isNNBD, false);
+  }
+
+  test_compilationUnit_nnbd_enabled() {
+    featureSet = enableNnbd;
+    serializeLibraryText('');
+    expect(unlinkedUnits[0].isNNBD, true);
+  }
+
   test_constExpr_binary_add() {
     UnlinkedVariable variable = serializeVariableText('const v = 1 + 2;');
     assertUnlinkedConst(variable.initializer.bodyExpr, '1 + 2', operators: [
@@ -9504,7 +9524,7 @@
     UnlinkedVariable variable = serializeVariableText('int v = null;');
     expect(variable.initializer.returnType, isNull);
     checkInferredTypeSlot(
-        variable.initializer.inferredReturnTypeSlot, null, '*bottom*',
+        variable.initializer.inferredReturnTypeSlot, null, 'Never',
         onlyInStrongMode: false);
   }
 
@@ -10827,7 +10847,7 @@
     EntityRef inferredType = getTypeRefForSlot(variable.inferredTypeSlot);
     checkLinkedTypeRef(inferredType.syntheticReturnType, 'dart:core', 'int');
     expect(inferredType.syntheticParams, hasLength(1));
-    checkLinkedTypeRef(inferredType.syntheticParams[0].type, null, '*bottom*');
+    checkLinkedTypeRef(inferredType.syntheticParams[0].type, null, 'Never');
   }
 
   test_syntheticFunctionType_inGenericClass() {
diff --git a/pkg/analyzer/test/src/summary/test_strategies.dart b/pkg/analyzer/test/src/summary/test_strategies.dart
index 9c286c5..7f0aa49 100644
--- a/pkg/analyzer/test/src/summary/test_strategies.dart
+++ b/pkg/analyzer/test/src/summary/test_strategies.dart
@@ -9,6 +9,7 @@
 import 'package:analyzer/error/listener.dart';
 import 'package:analyzer/file_system/memory_file_system.dart';
 import 'package:analyzer/src/dart/analysis/restricted_analysis_context.dart';
+import 'package:analyzer/src/dart/analysis/session.dart';
 import 'package:analyzer/src/dart/scanner/reader.dart';
 import 'package:analyzer/src/dart/scanner/scanner.dart';
 import 'package:analyzer/src/generated/engine.dart';
@@ -44,9 +45,12 @@
       new Scanner(null, reader, AnalysisErrorListener.NULL_LISTENER)
         ..configureFeatures(featureSet);
   Token token = scanner.tokenize();
+  // Pass the feature set from the scanner to the parser
+  // because the scanner may have detected a language version comment
+  // and downgraded the feature set it holds.
   Parser parser = new Parser(
       NonExistingSource.unknown, AnalysisErrorListener.NULL_LISTENER,
-      featureSet: featureSet);
+      featureSet: scanner.featureSet);
   CompilationUnit unit = parser.parseCompilationUnit(token);
   unit.lineInfo = new LineInfo(scanner.lineStarts);
   return unit;
@@ -181,9 +185,10 @@
     Map<String, LinkedLibrary> linkedSummaries = link(nonSdkLibraryUris,
         getDependency, getUnit, declaredVariables, analysisOptions);
 
+    var synchronousSession =
+        SynchronousSession(analysisOptions, declaredVariables);
     var analysisContext = RestrictedAnalysisContext(
-      analysisOptions,
-      declaredVariables,
+      synchronousSession,
       sourceFactory,
     );
 
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
deleted file mode 100644
index 1fc7fae..0000000
--- a/pkg/analyzer/test/src/summary2/ast_binary_writer_integration_test.dart
+++ /dev/null
@@ -1,122 +0,0 @@
-// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:io';
-
-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';
-import 'package:analyzer/src/summary2/ast_text_printer.dart';
-import 'package:analyzer/src/summary2/linked_bundle_context.dart';
-import 'package:analyzer/src/summary2/linked_element_factory.dart';
-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:front_end/src/testing/package_root.dart' as package_root;
-import 'package:test/test.dart';
-
-import '../dart/ast/parse_base.dart';
-
-main() {
-  group('AstBinaryWriter |', () {
-    _buildTests();
-  });
-}
-
-/// Parse the [code] into AST, serialize using [AstBinaryWriter], read using
-/// [AstBinaryReader], and dump back into code. The resulting code must be
-/// the same as the input [code].
-///
-/// Whitespaces and newlines are normalized and ignored.
-/// Files with parsing errors are silently skipped.
-void _assertCode(ParseBase base, String code) {
-  code = code.trimRight();
-  code = code.replaceAll('\t', ' ');
-  code = code.replaceAll('\r\n', '\n');
-  code = code.replaceAll('\r', '\n');
-
-  LineInfo lineInfo;
-  LinkedNodeUnit linkedNodeUnit;
-  {
-    var path = base.newFile('/home/test/lib/test.dart', content: code).path;
-
-    ParseResult parseResult;
-    try {
-      parseResult = base.parseUnit(path);
-    } catch (e) {
-      return;
-    }
-
-    // Code with parsing errors cannot be restored.
-    if (parseResult.errors.isNotEmpty) {
-      return;
-    }
-
-    lineInfo = parseResult.lineInfo;
-    var originalUnit = parseResult.unit;
-
-    var rootReference = Reference.root();
-    var dynamicRef = rootReference.getChild('dart:core').getChild('dynamic');
-
-    var linkingBundleContext = LinkingBundleContext(dynamicRef);
-    var writer = AstBinaryWriter(linkingBundleContext);
-    var unitLinkedNode = writer.writeNode(originalUnit);
-
-    linkedNodeUnit = LinkedNodeUnitBuilder(
-      node: unitLinkedNode,
-      tokens: writer.tokensBuilder,
-    );
-  }
-
-  var rootReference = Reference.root();
-  var bundleContext = LinkedBundleContext(
-    LinkedElementFactory(null, null, rootReference),
-    LinkedNodeBundleBuilder(
-      references: LinkedNodeReferencesBuilder(name: ['']),
-    ),
-  );
-  var unitContext = LinkedUnitContext(
-    bundleContext,
-    null,
-    0,
-    null,
-    null,
-    false,
-    linkedNodeUnit,
-  );
-
-  var reader = AstBinaryReader(unitContext);
-  var deserializedUnit = reader.readNode(linkedNodeUnit.node);
-
-  var buffer = StringBuffer();
-  deserializedUnit.accept(
-    AstTextPrinter(buffer, lineInfo),
-  );
-
-  expect(buffer.toString(), code);
-}
-
-void _buildTests() {
-  var provider = PhysicalResourceProvider.INSTANCE;
-  var pathContext = provider.pathContext;
-
-  var packageRoot = pathContext.normalize(package_root.packageRoot);
-  var dartFiles = Directory(packageRoot)
-      .listSync(recursive: true)
-      .whereType<File>()
-      .where((e) => e.path.endsWith('.dart'))
-      .toList();
-
-  var base = ParseBase();
-  for (var file in dartFiles) {
-    var relPath = pathContext.relative(file.path, from: packageRoot);
-    test(relPath, () {
-      var code = file.readAsStringSync();
-      _assertCode(base, code);
-    });
-  }
-}
diff --git a/pkg/analyzer/test/src/summary2/ast_binary_writer_test.dart b/pkg/analyzer/test/src/summary2/ast_binary_writer_test.dart
deleted file mode 100644
index b195dca..0000000
--- a/pkg/analyzer/test/src/summary2/ast_binary_writer_test.dart
+++ /dev/null
@@ -1,160 +0,0 @@
-// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:analyzer/src/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';
-import 'package:analyzer/src/summary2/linked_element_factory.dart';
-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:test/test.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-import '../dart/resolution/driver_resolution.dart';
-
-main() {
-  defineReflectiveSuite(() {
-    defineReflectiveTests(AstBinaryWriterTest);
-  });
-}
-
-/// Just a very simple test that at least something works.
-@reflectiveTest
-class AstBinaryWriterTest extends DriverResolutionTest {
-  @override
-  AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
-    ..enabledExperiments = [
-      EnableString.non_nullable,
-    ];
-
-  test_classTypeAlias() async {
-    _assertUnresolvedCode('''
-mixin M1 {}
-mixin M2 {}
-
-class I1 {}
-class I2 {}
-
-class X = Object with M1, M2 implements I1, I2;
-''');
-  }
-
-  test_configuration() async {
-    _assertUnresolvedCode('''
-import 'dart:math'
-  if (a.b.c == 'd1') 'e1'
-  if (a.b.c == 'd2') 'e2';
-''');
-  }
-
-  test_emptyStatement() async {
-    _assertUnresolvedCode('''
-main() {
-  if (true);
-}
-''');
-  }
-
-  test_forElement() async {
-    _assertUnresolvedCode('''
-main() {
-  return [1, for (var i = 0; i < 10; i++) i * i, 2];
-}
-''');
-  }
-
-  test_ifElement() async {
-    _assertUnresolvedCode('''
-main(bool b) {
-  return [1, if (b) 2 else 3, 4];
-}
-''');
-  }
-
-  test_labeledStatement() async {
-    _assertUnresolvedCode('''
-main() {
-  a: b: 42;
-}
-''');
-  }
-
-  test_scriptTag() async {
-    _assertUnresolvedCode('''
-#!/bin/dart
-
-main() {}
-''');
-  }
-
-  test_simple() async {
-    _assertUnresolvedCode('''
-const zero = 0;
-
-@zero
-class A<T extends num> {}
-
-class B extends A<int> {}
-
-void f() { // ref
-  1 + 2.0;
-  <double>[1, 2];
-}
-''');
-  }
-
-  test_spreadElement() async {
-    _assertUnresolvedCode('''
-main() {
-var a = [1, 2, 3];
-  return [...a];
-}
-''');
-  }
-
-  void _assertUnresolvedCode(String inputCode) {
-    var path = convertPath('/test/lib/test.dart');
-    newFile(path, content: inputCode);
-
-    var parseResult = driver.parseFileSync(path);
-    var originalUnit = parseResult.unit;
-    var originalCode = originalUnit.toSource();
-
-    var rootReference = Reference.root();
-    var dynamicRef = rootReference.getChild('dart:core').getChild('dynamic');
-
-    var linkingBundleContext = LinkingBundleContext(dynamicRef);
-    var writer = AstBinaryWriter(linkingBundleContext);
-    var builder = writer.writeNode(originalUnit);
-
-    var bundleContext = LinkedBundleContext(
-      LinkedElementFactory(null, null, rootReference),
-      LinkedNodeBundleBuilder(
-        references: LinkedNodeReferencesBuilder(name: ['']),
-      ),
-    );
-    var unitContext = LinkedUnitContext(
-      bundleContext,
-      null,
-      0,
-      null,
-      null,
-      false,
-      LinkedNodeUnitBuilder(
-        node: builder,
-        tokens: writer.tokensBuilder,
-      ),
-    );
-
-    var reader = AstBinaryReader(unitContext);
-    var deserializedUnit = reader.readNode(builder);
-    var deserializedCode = deserializedUnit.toSource();
-
-    expect(deserializedCode, originalCode);
-  }
-}
diff --git a/pkg/analyzer/test/src/summary2/test_all.dart b/pkg/analyzer/test/src/summary2/test_all.dart
index d7b4c0b..bff7e8b 100644
--- a/pkg/analyzer/test/src/summary2/test_all.dart
+++ b/pkg/analyzer/test/src/summary2/test_all.dart
@@ -4,12 +4,10 @@
 
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
-import 'ast_binary_writer_test.dart' as ast_binary_writer;
 import 'ast_text_printer_test.dart' as ast_text_printer;
 
 main() {
   defineReflectiveSuite(() {
-    ast_binary_writer.main();
     ast_text_printer.main();
   }, name: 'summary2');
 }
diff --git a/pkg/analyzer/test/src/workspace/package_build_test.dart b/pkg/analyzer/test/src/workspace/package_build_test.dart
index 223ca20..ef5bd9f 100644
--- a/pkg/analyzer/test/src/workspace/package_build_test.dart
+++ b/pkg/analyzer/test/src/workspace/package_build_test.dart
@@ -2,13 +2,13 @@
 // for details. All 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/package_bundle_reader.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/src/context/builder.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
 import 'package:analyzer/src/workspace/package_build.dart';
 import 'package:package_config/packages.dart';
-import 'package:path/path.dart' as path;
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -252,17 +252,34 @@
 
     var package = workspace
         .findPackageFor(convertPath('/workspace/project/lib/code.dart'));
-    var file2Path =
-        path.separator + path.join('workspace', 'project', 'lib', 'file2.dart');
+    var file2Path = convertPath('/workspace/project/lib/file2.dart');
     expect(package.contains(TestSource(file2Path)), isTrue);
-    var binPath =
-        path.separator + path.join('workspace', 'project', 'bin', 'bin.dart');
+    var binPath = convertPath('/workspace/project/bin/bin.dart');
     expect(package.contains(TestSource(binPath)), isTrue);
-    var testPath =
-        path.separator + path.join('workspace', 'project', 'test', 'test.dart');
+    var testPath = convertPath('/workspace/project/test/test.dart');
     expect(package.contains(TestSource(testPath)), isTrue);
   }
 
+  void test_contains_packageUris() {
+    PackageBuildWorkspace workspace = _createPackageBuildWorkspace();
+    newFile('/workspace/project/lib/file2.dart');
+    var package = workspace
+        .findPackageFor(convertPath('/workspace/project/lib/code.dart'));
+    var file2Source = InSummarySource(
+        Uri.parse('package:project/file2.dart'), '' /* summaryPath */);
+    expect(package.contains(file2Source), isTrue);
+  }
+
+  void test_contains_packageUris_unrelatedFile() {
+    PackageBuildWorkspace workspace = _createPackageBuildWorkspace();
+    newFile('/workspace/project/lib/file2.dart');
+    var package = workspace
+        .findPackageFor(convertPath('/workspace/project/lib/code.dart'));
+    var file2Source = InSummarySource(
+        Uri.parse('package:project2/file2.dart'), '' /* summaryPath */);
+    expect(package.contains(file2Source), isFalse);
+  }
+
   void test_findPackageFor_includedFile() {
     PackageBuildWorkspace workspace = _createPackageBuildWorkspace();
     newFile('/workspace/project/lib/file.dart');
@@ -274,6 +291,17 @@
     expect(package.workspace, equals(workspace));
   }
 
+  void test_findPackageFor_testFile() {
+    PackageBuildWorkspace workspace = _createPackageBuildWorkspace();
+    newFile('/workspace/project/test/test.dart');
+
+    var package = workspace
+        .findPackageFor(convertPath('/workspace/project/test/test.dart'));
+    expect(package, isNotNull);
+    expect(package.root, convertPath('/workspace'));
+    expect(package.workspace, equals(workspace));
+  }
+
   void test_findPackageFor_unrelatedFile() {
     PackageBuildWorkspace workspace = _createPackageBuildWorkspace();
     newFile('/workspace/project/lib/file.dart');
diff --git a/pkg/analyzer_cli/lib/src/build_mode.dart b/pkg/analyzer_cli/lib/src/build_mode.dart
index b2e0dfb..5bb4368 100644
--- a/pkg/analyzer_cli/lib/src/build_mode.dart
+++ b/pkg/analyzer_cli/lib/src/build_mode.dart
@@ -79,8 +79,6 @@
    */
   Future<void> analyze(
       CommandLineOptions options, Map<String, WorkerInput> inputs) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     var packageBundleProvider =
         new WorkerPackageBundleProvider(packageBundleCache, inputs);
     var buildMode = new BuildMode(
@@ -99,11 +97,7 @@
    */
   @override
   Future<WorkResponse> performRequest(WorkRequest request) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     return logger.runAsync('Perform request', () async {
-      // TODO(brianwilkerson) Determine whether this await is necessary.
-      await null;
       errorBuffer.clear();
       outBuffer.clear();
       try {
@@ -148,8 +142,6 @@
    */
   @override
   Future<void> run() async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     errorSink = errorBuffer;
     outSink = outBuffer;
     exitHandler = (int exitCode) {
@@ -213,11 +205,7 @@
    * Perform package analysis according to the given [options].
    */
   Future<ErrorSeverity> analyze() async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     return await logger.runAsync('Analyze', () async {
-      // TODO(brianwilkerson) Determine whether this await is necessary.
-      await null;
       // Write initial progress message.
       if (!options.machineFormat) {
         outSink.writeln("Analyzing ${options.sourceFiles.join(', ')}...");
@@ -266,12 +254,8 @@
       assembler = new PackageBundleAssembler();
       if (_shouldOutputSummary) {
         await logger.runAsync('Build and write output summary', () async {
-          // TODO(brianwilkerson) Determine whether this await is necessary.
-          await null;
           // Prepare all unlinked units.
           await logger.runAsync('Prepare unlinked units', () async {
-            // TODO(brianwilkerson) Determine whether this await is necessary.
-            await null;
             for (var src in explicitSources) {
               await _prepareUnlinkedUnit('${src.uri}');
             }
@@ -368,8 +352,6 @@
   }
 
   Future<ErrorSeverity> _computeMaxSeverity() async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     ErrorSeverity maxSeverity = ErrorSeverity.NONE;
     if (!options.buildSuppressExitCode) {
       for (Source source in explicitSources) {
@@ -507,8 +489,6 @@
    * Otherwise compute it and store into the [uriToUnit] and [assembler].
    */
   Future<void> _prepareUnlinkedUnit(String absoluteUri) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     // Maybe an input package contains the source.
     if (summaryDataStore.unlinkedMap[absoluteUri] != null) {
       return;
@@ -532,11 +512,7 @@
    * is sent to a new file at that path.
    */
   Future<void> _printErrors({String outputPath}) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     await logger.runAsync('Compute and print analysis errors', () async {
-      // TODO(brianwilkerson) Determine whether this await is necessary.
-      await null;
       StringBuffer buffer = new StringBuffer();
       var severityProcessor = (AnalysisError error) =>
           determineProcessedSeverity(error, options, analysisOptions);
@@ -650,6 +626,29 @@
 }
 
 /**
+ * Wrapper for [InSummaryUriResolver] that tracks accesses to summaries.
+ */
+class TrackingInSummaryUriResolver extends UriResolver {
+  // May be null.
+  final DependencyTracker dependencyTracker;
+  final InSummaryUriResolver inSummaryUriResolver;
+
+  TrackingInSummaryUriResolver(
+      this.inSummaryUriResolver, this.dependencyTracker);
+
+  @override
+  Source resolveAbsolute(Uri uri, [Uri actualUri]) {
+    var source = inSummaryUriResolver.resolveAbsolute(uri, actualUri);
+    if (dependencyTracker != null &&
+        source != null &&
+        source is InSummarySource) {
+      dependencyTracker.record(source.summaryPath);
+    }
+    return source;
+  }
+}
+
+/**
  * Worker input.
  *
  * Bazel does not specify the format of the digest, so we cannot assume that
@@ -744,26 +743,3 @@
     return cache.get(inputs, path);
   }
 }
-
-/**
- * Wrapper for [InSummaryUriResolver] that tracks accesses to summaries.
- */
-class TrackingInSummaryUriResolver extends UriResolver {
-  // May be null.
-  final DependencyTracker dependencyTracker;
-  final InSummaryUriResolver inSummaryUriResolver;
-
-  TrackingInSummaryUriResolver(
-      this.inSummaryUriResolver, this.dependencyTracker);
-
-  @override
-  Source resolveAbsolute(Uri uri, [Uri actualUri]) {
-    var source = inSummaryUriResolver.resolveAbsolute(uri, actualUri);
-    if (dependencyTracker != null &&
-        source != null &&
-        source is InSummarySource) {
-      dependencyTracker.record(source.summaryPath);
-    }
-    return source;
-  }
-}
diff --git a/pkg/analyzer_plugin/lib/src/utilities/change_builder/dart/import_library_element.dart b/pkg/analyzer_plugin/lib/src/utilities/change_builder/dart/import_library_element.dart
index d9e764c..f135dd8 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/change_builder/dart/import_library_element.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/change_builder/dart/import_library_element.dart
@@ -27,7 +27,7 @@
   }
 
   var requestedElements = requestedLibrary.exportNamespace.definedNames;
-  _removeEntryForDynamic(requestedElements);
+  _removeEntriesForDynamicAndNever(requestedElements);
 
   // Find URIs of all libraries that import the requested name into the target.
   var unprefixedNameUriSet = Set<Uri>();
@@ -145,11 +145,13 @@
   return ImportLibraryRequest(requestedLibraryUri, prefix);
 }
 
-/// The type `dynamic` is part of 'dart:core', but has no library.
-void _removeEntryForDynamic(Map<String, Element> requestedElements) {
+/// The types `dynamic` and `Never` are part of 'dart:core', but have no
+/// library.
+void _removeEntriesForDynamicAndNever(Map<String, Element> requestedElements) {
   requestedElements.removeWhere((_, element) {
     if (element.librarySource == null) {
-      assert(element.displayName == 'dynamic');
+      assert(
+          element.displayName == 'dynamic' || element.displayName == 'Never');
       return true;
     }
     return false;
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 2f545d1..894e061 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
@@ -142,6 +142,22 @@
   }
 
   @override
+  void visitFieldDeclaration(FieldDeclaration node) {
+    var variableList = node.fields;
+
+    // `Foo^ Foo bar() {}` is recovered as `Foo Foo; bar() {}`, i.e. the
+    // return type of `bar()` gets associated with a new variable declaration.
+    if (node.semicolon.isSynthetic) {
+      if (variableList.variables.length == 1) {
+        var name = variableList.variables[0].name.name;
+        names.remove(name);
+      }
+    }
+
+    super.visitFieldDeclaration(node);
+  }
+
+  @override
   void visitForElement(ForElement node) {
     if (!_isCoveredBy(node)) return;
 
@@ -236,6 +252,15 @@
       return;
     }
 
+    // `Foo^ Foo bar() {}` is recovered as `Foo Foo; bar() {}`, i.e. the
+    // return type of `bar()` gets associated with a new variable declaration.
+    if (node.semicolon.isSynthetic) {
+      if (variableList.variables.length == 1) {
+        var name = variableList.variables[0].name.name;
+        names.remove(name);
+      }
+    }
+
     super.visitTopLevelVariableDeclaration(node);
   }
 
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 8873d2e..fade0d2 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
@@ -161,6 +161,50 @@
 
 @reflectiveTest
 class ImportLibraryElement_incompleteCode_Test extends _Base {
+  test_fieldDeclaration_atEnd() async {
+    newFile('/home/test/lib/a.dart', content: 'class A {}');
+    await _assertImportLibraryElement(
+      initialCode: r'''
+class C {
+  A^
+}
+''',
+      uriStr: 'package:test/a.dart',
+      name: 'A',
+      expectedCode: r'''
+import 'package:test/a.dart';
+
+class C {
+  A
+}
+''',
+    );
+  }
+
+  test_fieldDeclaration_beforeReturnType() async {
+    newFile('/home/test/lib/a.dart', content: 'class A {}');
+    await _assertImportLibraryElement(
+      initialCode: r'''
+class C {
+  A^
+  
+  A foo() => null;
+}
+''',
+      uriStr: 'package:test/a.dart',
+      name: 'A',
+      expectedCode: r'''
+import 'package:test/a.dart';
+
+class C {
+  A
+  
+  A foo() => null;
+}
+''',
+    );
+  }
+
   test_formalParameter() async {
     newFile('/home/test/lib/a.dart', content: 'class A {}');
     newFile('/home/test/lib/b.dart', content: r'''
@@ -180,7 +224,7 @@
     );
   }
 
-  test_topLevelVariable() async {
+  test_topLevelVariable_atEnd() async {
     newFile('/home/test/lib/a.dart', content: 'class A {}');
     newFile('/home/test/lib/b.dart', content: r'''
 export 'a.dart';
@@ -198,6 +242,26 @@
 ''',
     );
   }
+
+  test_topLevelVariable_beforeReturnType() async {
+    newFile('/home/test/lib/a.dart', content: 'class A {}');
+    await _assertImportLibraryElement(
+      initialCode: r'''
+A^
+
+A foo() => null;
+''',
+      uriStr: 'package:test/a.dart',
+      name: 'A',
+      expectedCode: r'''
+import 'package:test/a.dart';
+
+A
+
+A foo() => null;
+''',
+    );
+  }
 }
 
 @reflectiveTest
diff --git a/pkg/expect/lib/async_minitest.dart b/pkg/async_helper/lib/async_minitest.dart
similarity index 100%
rename from pkg/expect/lib/async_minitest.dart
rename to pkg/async_helper/lib/async_minitest.dart
diff --git a/pkg/async_helper/pubspec.yaml b/pkg/async_helper/pubspec.yaml
index ceb2634..df92b53 100644
--- a/pkg/async_helper/pubspec.yaml
+++ b/pkg/async_helper/pubspec.yaml
@@ -7,3 +7,6 @@
  language tests.
  Third parties are discouraged from using this, and should use
  the facilities provided in package:test.
+
+dependencies:
+  expect: any
diff --git a/pkg/compiler/lib/src/backend_strategy.dart b/pkg/compiler/lib/src/backend_strategy.dart
index cb3b545..444937c 100644
--- a/pkg/compiler/lib/src/backend_strategy.dart
+++ b/pkg/compiler/lib/src/backend_strategy.dart
@@ -12,7 +12,6 @@
 import 'inferrer/types.dart';
 import 'io/source_information.dart';
 import 'js_backend/inferred_data.dart';
-import 'js_backend/js_backend.dart';
 import 'js_backend/native_data.dart';
 import 'ssa/ssa.dart';
 import 'universe/codegen_world_builder.dart';
@@ -39,12 +38,11 @@
       SelectorConstraintsStrategy selectorConstraintsStrategy);
 
   /// Creates the [WorkItemBuilder] used by the codegen enqueuer.
-  WorkItemBuilder createCodegenWorkItemBuilder(JClosedWorld closedWorld,
-      GlobalTypeInferenceResults globalInferenceResults, CodegenInputs codegen);
+  WorkItemBuilder createCodegenWorkItemBuilder(JClosedWorld closedWorld);
 
   /// Creates the [SsaBuilder] used for the element model.
-  SsaBuilder createSsaBuilder(CompilerTask task, CodegenInputs codegen,
-      SourceInformationStrategy sourceInformationStrategy);
+  SsaBuilder createSsaBuilder(
+      CompilerTask task, SourceInformationStrategy sourceInformationStrategy);
 
   /// Returns the [SourceInformationStrategy] use for the element model.
   SourceInformationStrategy get sourceInformationStrategy;
diff --git a/pkg/compiler/lib/src/common/codegen.dart b/pkg/compiler/lib/src/common/codegen.dart
index b2dedea..852152d 100644
--- a/pkg/compiler/lib/src/common/codegen.dart
+++ b/pkg/compiler/lib/src/common/codegen.dart
@@ -4,21 +4,39 @@
 
 library dart2js.common.codegen;
 
+import 'package:js_ast/src/precedence.dart' as js show PRIMARY;
+
 import '../common_elements.dart';
+import '../constants/values.dart';
+import '../deferred_load.dart';
 import '../elements/entities.dart';
 import '../elements/types.dart' show DartType, InterfaceType;
+import '../inferrer/abstract_value_domain.dart';
+import '../io/source_information.dart';
+import '../js/js.dart' as js;
+import '../js_backend/namer.dart';
+import '../js_emitter/code_emitter_task.dart' show Emitter;
 import '../native/behavior.dart';
+import '../serialization/serialization.dart';
 import '../universe/feature.dart';
+import '../universe/selector.dart';
 import '../universe/use.dart' show ConstantUse, DynamicUse, StaticUse, TypeUse;
 import '../universe/world_impact.dart'
     show WorldImpact, WorldImpactBuilderImpl, WorldImpactVisitor;
 import '../util/enumset.dart';
-import '../util/util.dart' show Pair, Setlet;
-import 'work.dart' show WorkItem;
+import '../util/util.dart';
+import '../world.dart';
 
 class CodegenImpact extends WorldImpact {
   const CodegenImpact();
 
+  factory CodegenImpact.readFromDataSource(DataSource source) =
+      _CodegenImpact.readFromDataSource;
+
+  void writeToDataSink(DataSink sink) {
+    throw new UnsupportedError('CodegenImpact.writeToDataSink');
+  }
+
   Iterable<Pair<DartType, DartType>> get typeVariableBoundsSubtypeChecks {
     return const <Pair<DartType, DartType>>[];
   }
@@ -42,8 +60,10 @@
 }
 
 class _CodegenImpact extends WorldImpactBuilderImpl implements CodegenImpact {
-  Setlet<Pair<DartType, DartType>> _typeVariableBoundsSubtypeChecks;
-  Setlet<String> _constSymbols;
+  static const String tag = 'codegen-impact';
+
+  Set<Pair<DartType, DartType>> _typeVariableBoundsSubtypeChecks;
+  Set<String> _constSymbols;
   List<Set<ClassEntity>> _specializedGetInterceptors;
   bool _usesInterceptor = false;
   EnumSet<AsyncMarker> _asyncMarkers;
@@ -53,6 +73,108 @@
 
   _CodegenImpact();
 
+  _CodegenImpact.internal(
+      Set<DynamicUse> dynamicUses,
+      Set<StaticUse> staticUses,
+      Set<TypeUse> typeUses,
+      Set<ConstantUse> constantUses,
+      this._typeVariableBoundsSubtypeChecks,
+      this._constSymbols,
+      this._specializedGetInterceptors,
+      this._usesInterceptor,
+      this._asyncMarkers,
+      this._genericInstantiations,
+      this._nativeBehaviors,
+      this._nativeMethods)
+      : super.internal(dynamicUses, staticUses, typeUses, constantUses);
+
+  factory _CodegenImpact.readFromDataSource(DataSource source) {
+    source.begin(tag);
+    Set<DynamicUse> dynamicUses = source
+        .readList(() => DynamicUse.readFromDataSource(source),
+            emptyAsNull: true)
+        ?.toSet();
+    Set<StaticUse> staticUses = source
+        .readList(() => StaticUse.readFromDataSource(source), emptyAsNull: true)
+        ?.toSet();
+    Set<TypeUse> typeUses = source
+        .readList(() => TypeUse.readFromDataSource(source), emptyAsNull: true)
+        ?.toSet();
+    Set<ConstantUse> constantUses = source
+        .readList(() => ConstantUse.readFromDataSource(source),
+            emptyAsNull: true)
+        ?.toSet();
+    Set<Pair<DartType, DartType>> typeVariableBoundsSubtypeChecks =
+        source.readList(() {
+      return new Pair(source.readDartType(), source.readDartType());
+    }, emptyAsNull: true)?.toSet();
+    Set<String> constSymbols = source.readStrings(emptyAsNull: true)?.toSet();
+    List<Set<ClassEntity>> specializedGetInterceptors = source.readList(() {
+      return source.readClasses().toSet();
+    }, emptyAsNull: true);
+    bool usesInterceptor = source.readBool();
+    int asyncMarkersValue = source.readIntOrNull();
+    EnumSet<AsyncMarker> asyncMarkers = asyncMarkersValue != null
+        ? new EnumSet.fromValue(asyncMarkersValue)
+        : null;
+    Set<GenericInstantiation> genericInstantiations = source
+        .readList(() => GenericInstantiation.readFromDataSource(source),
+            emptyAsNull: true)
+        ?.toSet();
+    List<NativeBehavior> nativeBehaviors = source.readList(
+        () => NativeBehavior.readFromDataSource(source),
+        emptyAsNull: true);
+    Set<FunctionEntity> nativeMethods =
+        source.readMembers<FunctionEntity>(emptyAsNull: true)?.toSet();
+    source.end(tag);
+    return new _CodegenImpact.internal(
+        dynamicUses,
+        staticUses,
+        typeUses,
+        constantUses,
+        typeVariableBoundsSubtypeChecks,
+        constSymbols,
+        specializedGetInterceptors,
+        usesInterceptor,
+        asyncMarkers,
+        genericInstantiations,
+        nativeBehaviors,
+        nativeMethods);
+  }
+
+  @override
+  void writeToDataSink(DataSink sink) {
+    sink.begin(tag);
+    sink.writeList(dynamicUses, (DynamicUse use) => use.writeToDataSink(sink),
+        allowNull: true);
+    sink.writeList(staticUses, (StaticUse use) => use.writeToDataSink(sink),
+        allowNull: true);
+    sink.writeList(typeUses, (TypeUse use) => use.writeToDataSink(sink),
+        allowNull: true);
+    sink.writeList(constantUses, (ConstantUse use) => use.writeToDataSink(sink),
+        allowNull: true);
+    sink.writeList<Pair<DartType, DartType>>(_typeVariableBoundsSubtypeChecks,
+        (pair) {
+      sink.writeDartType(pair.a);
+      sink.writeDartType(pair.b);
+    }, allowNull: true);
+    sink.writeStrings(_constSymbols, allowNull: true);
+    sink.writeList(_specializedGetInterceptors, sink.writeClasses,
+        allowNull: true);
+    sink.writeBool(_usesInterceptor);
+    sink.writeIntOrNull(_asyncMarkers?.value);
+    sink.writeList(
+        _genericInstantiations,
+        (GenericInstantiation instantiation) =>
+            instantiation.writeToDataSink(sink),
+        allowNull: true);
+    sink.writeList(_nativeBehaviors,
+        (NativeBehavior behavior) => behavior.writeToDataSink(sink),
+        allowNull: true);
+    sink.writeMembers(_nativeMethods, allowNull: true);
+    sink.end(tag);
+  }
+
   @override
   void apply(WorldImpactVisitor visitor) {
     staticUses.forEach(visitor.visitStaticUse);
@@ -62,7 +184,7 @@
 
   void registerTypeVariableBoundsSubtypeCheck(
       DartType subtype, DartType supertype) {
-    _typeVariableBoundsSubtypeChecks ??= new Setlet<Pair<DartType, DartType>>();
+    _typeVariableBoundsSubtypeChecks ??= {};
     _typeVariableBoundsSubtypeChecks
         .add(new Pair<DartType, DartType>(subtype, supertype));
   }
@@ -75,7 +197,7 @@
   }
 
   void registerConstSymbol(String name) {
-    _constSymbols ??= new Setlet<String>();
+    _constSymbols ??= {};
     _constSymbols.add(name);
   }
 
@@ -116,7 +238,7 @@
   }
 
   void registerGenericInstantiation(GenericInstantiation instantiation) {
-    _genericInstantiations ??= new Set<GenericInstantiation>();
+    _genericInstantiations ??= {};
     _genericInstantiations.add(instantiation);
   }
 
@@ -144,22 +266,49 @@
   Iterable<FunctionEntity> get nativeMethods {
     return _nativeMethods ?? const [];
   }
+
+  @override
+  String toString() {
+    StringBuffer sb = new StringBuffer();
+    sb.write('CodegenImpact:');
+    WorldImpact.printOn(sb, this);
+
+    void add(String title, Iterable iterable) {
+      if (iterable.isNotEmpty) {
+        sb.write('\n $title:');
+        iterable.forEach((e) => sb.write('\n  $e'));
+      }
+    }
+
+    add('typeVariableBoundsSubtypeChecks', typeVariableBoundsSubtypeChecks);
+    add('constSymbols', constSymbols);
+    add('specializedGetInterceptors', specializedGetInterceptors);
+    if (usesInterceptor) {
+      sb.write('\n usesInterceptor: true');
+    }
+    add('asyncMarkers', asyncMarkers);
+    add('genericInstantiations', genericInstantiations);
+    add('nativeBehaviors', nativeBehaviors);
+    add('nativeMethods', nativeMethods);
+
+    return sb.toString();
+  }
 }
 
 // TODO(johnniwinther): Split this class into interface and implementation.
 // TODO(johnniwinther): Move this implementation to the JS backend.
 class CodegenRegistry {
   final ElementEnvironment _elementEnvironment;
-  final MemberEntity currentElement;
-  final _CodegenImpact worldImpact;
+  final MemberEntity _currentElement;
+  final _CodegenImpact _worldImpact;
+  List<ModularName> _names;
+  List<ModularExpression> _expressions;
 
-  CodegenRegistry(this._elementEnvironment, this.currentElement)
-      : this.worldImpact = new _CodegenImpact();
-
-  bool get isForResolution => false;
+  CodegenRegistry(this._elementEnvironment, this._currentElement)
+      : this._worldImpact = new _CodegenImpact();
 
   @override
-  String toString() => 'CodegenRegistry for $currentElement';
+  String toString() => 'CodegenRegistry for $_currentElement';
 
   @deprecated
   void registerInstantiatedClass(ClassEntity element) {
@@ -167,40 +316,40 @@
   }
 
   void registerStaticUse(StaticUse staticUse) {
-    worldImpact.registerStaticUse(staticUse);
+    _worldImpact.registerStaticUse(staticUse);
   }
 
   void registerDynamicUse(DynamicUse dynamicUse) {
-    worldImpact.registerDynamicUse(dynamicUse);
+    _worldImpact.registerDynamicUse(dynamicUse);
   }
 
   void registerTypeUse(TypeUse typeUse) {
-    worldImpact.registerTypeUse(typeUse);
+    _worldImpact.registerTypeUse(typeUse);
   }
 
   void registerConstantUse(ConstantUse constantUse) {
-    worldImpact.registerConstantUse(constantUse);
+    _worldImpact.registerConstantUse(constantUse);
   }
 
   void registerTypeVariableBoundsSubtypeCheck(
       DartType subtype, DartType supertype) {
-    worldImpact.registerTypeVariableBoundsSubtypeCheck(subtype, supertype);
+    _worldImpact.registerTypeVariableBoundsSubtypeCheck(subtype, supertype);
   }
 
   void registerInstantiatedClosure(FunctionEntity element) {
-    worldImpact.registerStaticUse(new StaticUse.callMethod(element));
+    _worldImpact.registerStaticUse(new StaticUse.callMethod(element));
   }
 
   void registerConstSymbol(String name) {
-    worldImpact.registerConstSymbol(name);
+    _worldImpact.registerConstSymbol(name);
   }
 
   void registerSpecializedGetInterceptor(Set<ClassEntity> classes) {
-    worldImpact.registerSpecializedGetInterceptor(classes);
+    _worldImpact.registerSpecializedGetInterceptor(classes);
   }
 
   void registerUseInterceptor() {
-    worldImpact.registerUseInterceptor();
+    _worldImpact.registerUseInterceptor();
   }
 
   void registerInstantiation(InterfaceType type) {
@@ -208,23 +357,1713 @@
   }
 
   void registerAsyncMarker(AsyncMarker asyncMarker) {
-    worldImpact.registerAsyncMarker(asyncMarker);
+    _worldImpact.registerAsyncMarker(asyncMarker);
   }
 
   void registerGenericInstantiation(GenericInstantiation instantiation) {
-    worldImpact.registerGenericInstantiation(instantiation);
+    _worldImpact.registerGenericInstantiation(instantiation);
   }
 
   void registerNativeBehavior(NativeBehavior nativeBehavior) {
-    worldImpact.registerNativeBehavior(nativeBehavior);
+    _worldImpact.registerNativeBehavior(nativeBehavior);
   }
 
   void registerNativeMethod(FunctionEntity function) {
-    worldImpact.registerNativeMethod(function);
+    _worldImpact.registerNativeMethod(function);
+  }
+
+  void registerModularName(ModularName name) {
+    _names ??= [];
+    _names.add(name);
+  }
+
+  void registerModularExpression(ModularExpression expression) {
+    _expressions ??= [];
+    _expressions.add(expression);
+  }
+
+  CodegenResult close(js.Fun code) {
+    return new CodegenResult(
+        code, _worldImpact, _names ?? const [], _expressions ?? const []);
   }
 }
 
-/// [WorkItem] used exclusively by the [CodegenEnqueuer].
-abstract class CodegenWorkItem extends WorkItem {
-  CodegenRegistry get registry;
+class CodegenResult {
+  static const String tag = 'codegen-result';
+
+  final js.Fun code;
+  final CodegenImpact impact;
+  final Iterable<ModularName> modularNames;
+  final Iterable<ModularExpression> modularExpressions;
+
+  CodegenResult(
+      this.code, this.impact, this.modularNames, this.modularExpressions);
+
+  /// Reads a [CodegenResult] object from [source].
+  ///
+  /// The [ModularName] and [ModularExpression] nodes read during
+  /// deserialization are collected in [modularNames] and [modularExpressions]
+  /// to avoid the need for visiting the [code] node post deserialization.
+  factory CodegenResult.readFromDataSource(
+      DataSource source,
+      List<ModularName> modularNames,
+      List<ModularExpression> modularExpressions) {
+    source.begin(tag);
+    js.Fun code = source.readJsNodeOrNull();
+    CodegenImpact impact = CodegenImpact.readFromDataSource(source);
+    source.end(tag);
+    return new CodegenResult(code, impact, modularNames, modularExpressions);
+  }
+
+  /// Writes the [CodegenResult] object to [sink].
+  ///
+  /// The [modularNames] and [modularExpressions] fields are not directly
+  /// serializes because these are embedded in the [code] node and collected
+  /// through this during deserialization.
+  void writeToDataSink(DataSink sink) {
+    sink.begin(tag);
+    sink.writeJsNodeOrNull(code);
+    impact.writeToDataSink(sink);
+    sink.end(tag);
+  }
+
+  void applyModularState(Namer namer, Emitter emitter) {
+    for (ModularName name in modularNames) {
+      switch (name.kind) {
+        case ModularNameKind.rtiField:
+          name.value = namer.rtiFieldJsName;
+          break;
+        case ModularNameKind.runtimeTypeName:
+          name.value = namer.runtimeTypeName(name.data);
+          break;
+        case ModularNameKind.className:
+          name.value = namer.className(name.data);
+          break;
+        case ModularNameKind.aliasedSuperMember:
+          name.value = namer.aliasedSuperMemberPropertyName(name.data);
+          break;
+        case ModularNameKind.staticClosure:
+          name.value = namer.staticClosureName(name.data);
+          break;
+        case ModularNameKind.methodProperty:
+          name.value = namer.methodPropertyName(name.data);
+          break;
+        case ModularNameKind.operatorIs:
+          name.value = namer.operatorIs(name.data);
+          break;
+        case ModularNameKind.operatorIsType:
+          name.value = namer.operatorIsType(name.data);
+          break;
+        case ModularNameKind.substitution:
+          name.value = namer.substitutionName(name.data);
+          break;
+        case ModularNameKind.instanceMethod:
+          name.value = namer.instanceMethodName(name.data);
+          break;
+        case ModularNameKind.instanceField:
+          name.value = namer.instanceFieldPropertyName(name.data);
+          break;
+        case ModularNameKind.invocation:
+          name.value = namer.invocationName(name.data);
+          break;
+        case ModularNameKind.lazyInitializer:
+          name.value = namer.lazyInitializerName(name.data);
+          break;
+        case ModularNameKind.globalPropertyNameForClass:
+          name.value = namer.globalPropertyNameForClass(name.data);
+          break;
+        case ModularNameKind.globalPropertyNameForType:
+          name.value = namer.globalPropertyNameForType(name.data);
+          break;
+        case ModularNameKind.globalPropertyNameForMember:
+          name.value = namer.globalPropertyNameForMember(name.data);
+          break;
+        case ModularNameKind.nameForGetInterceptor:
+          name.value = namer.nameForGetInterceptor(name.set);
+          break;
+        case ModularNameKind.nameForGetOneShotInterceptor:
+          name.value = namer.nameForGetOneShotInterceptor(name.data, name.set);
+          break;
+        case ModularNameKind.asName:
+          name.value = namer.asName(name.data);
+          break;
+      }
+    }
+    for (ModularExpression expression in modularExpressions) {
+      switch (expression.kind) {
+        case ModularExpressionKind.globalObjectForLibrary:
+          expression.value = namer
+              .readGlobalObjectForLibrary(expression.data)
+              .withSourceInformation(expression.sourceInformation);
+          break;
+        case ModularExpressionKind.globalObjectForClass:
+          expression.value = namer
+              .readGlobalObjectForClass(expression.data)
+              .withSourceInformation(expression.sourceInformation);
+          break;
+        case ModularExpressionKind.globalObjectForType:
+          expression.value = namer
+              .readGlobalObjectForType(expression.data)
+              .withSourceInformation(expression.sourceInformation);
+          break;
+        case ModularExpressionKind.globalObjectForMember:
+          expression.value = namer
+              .readGlobalObjectForMember(expression.data)
+              .withSourceInformation(expression.sourceInformation);
+          break;
+        case ModularExpressionKind.constant:
+          expression.value = emitter
+              .constantReference(expression.data)
+              .withSourceInformation(expression.sourceInformation);
+          break;
+        case ModularExpressionKind.embeddedGlobalAccess:
+          expression.value = emitter
+              .generateEmbeddedGlobalAccess(expression.data)
+              .withSourceInformation(expression.sourceInformation);
+          break;
+      }
+    }
+  }
+
+  @override
+  String toString() {
+    StringBuffer sb = new StringBuffer();
+    sb.write('CodegenResult(code=');
+    sb.write(code != null ? js.DebugPrint(code) : '<null>,');
+    sb.write('impact=$impact,');
+    sb.write('modularNames=$modularNames,');
+    sb.write('modularExpressions=$modularExpressions');
+    sb.write(')');
+    return sb.toString();
+  }
+}
+
+enum ModularNameKind {
+  rtiField,
+  runtimeTypeName,
+  className,
+  aliasedSuperMember,
+  staticClosure,
+  methodProperty,
+  operatorIs,
+  operatorIsType,
+  substitution,
+  instanceMethod,
+  instanceField,
+  invocation,
+  lazyInitializer,
+  globalPropertyNameForClass,
+  globalPropertyNameForType,
+  globalPropertyNameForMember,
+  nameForGetInterceptor,
+  nameForGetOneShotInterceptor,
+  asName,
+}
+
+class ModularName extends js.Name implements js.AstContainer {
+  static const String tag = 'modular-name';
+
+  final ModularNameKind kind;
+  js.Name _value;
+  final Object data;
+  final Set<ClassEntity> set;
+
+  ModularName(this.kind, {this.data, this.set});
+
+  factory ModularName.readFromDataSource(DataSource source) {
+    source.begin(tag);
+    ModularNameKind kind = source.readEnum(ModularNameKind.values);
+    Object data;
+    Set<ClassEntity> set;
+    switch (kind) {
+      case ModularNameKind.rtiField:
+        break;
+      case ModularNameKind.globalPropertyNameForType:
+      case ModularNameKind.runtimeTypeName:
+        bool dataIsClassEntity = source.readBool();
+        if (dataIsClassEntity) {
+          data = source.readClass();
+        } else {
+          data = source.readTypedef();
+        }
+        break;
+      case ModularNameKind.className:
+      case ModularNameKind.operatorIs:
+      case ModularNameKind.substitution:
+      case ModularNameKind.globalPropertyNameForClass:
+        data = source.readClass();
+        break;
+      case ModularNameKind.aliasedSuperMember:
+      case ModularNameKind.staticClosure:
+      case ModularNameKind.methodProperty:
+      case ModularNameKind.instanceField:
+      case ModularNameKind.instanceMethod:
+      case ModularNameKind.lazyInitializer:
+      case ModularNameKind.globalPropertyNameForMember:
+        data = source.readMember();
+        break;
+      case ModularNameKind.operatorIsType:
+        data = source.readDartType();
+        break;
+      case ModularNameKind.invocation:
+        data = Selector.readFromDataSource(source);
+        break;
+      case ModularNameKind.nameForGetInterceptor:
+        set = source.readClasses().toSet();
+        break;
+      case ModularNameKind.nameForGetOneShotInterceptor:
+        data = Selector.readFromDataSource(source);
+        set = source.readClasses().toSet();
+        break;
+      case ModularNameKind.asName:
+        data = source.readString();
+        break;
+    }
+    source.end(tag);
+    return new ModularName(kind, data: data, set: set);
+  }
+
+  void writeToDataSink(DataSink sink) {
+    sink.begin(tag);
+    sink.writeEnum(kind);
+    switch (kind) {
+      case ModularNameKind.rtiField:
+        break;
+      case ModularNameKind.globalPropertyNameForType:
+      case ModularNameKind.runtimeTypeName:
+        sink.writeBool(data is ClassEntity);
+        if (data is ClassEntity) {
+          sink.writeClass(data);
+        } else {
+          sink.writeTypedef(data);
+        }
+        break;
+      case ModularNameKind.className:
+      case ModularNameKind.operatorIs:
+      case ModularNameKind.substitution:
+      case ModularNameKind.globalPropertyNameForClass:
+        sink.writeClass(data);
+        break;
+      case ModularNameKind.aliasedSuperMember:
+      case ModularNameKind.staticClosure:
+      case ModularNameKind.methodProperty:
+      case ModularNameKind.instanceField:
+      case ModularNameKind.instanceMethod:
+      case ModularNameKind.lazyInitializer:
+      case ModularNameKind.globalPropertyNameForMember:
+        sink.writeMember(data);
+        break;
+      case ModularNameKind.operatorIsType:
+        sink.writeDartType(data);
+        break;
+      case ModularNameKind.invocation:
+        Selector selector = data;
+        selector.writeToDataSink(sink);
+        break;
+      case ModularNameKind.nameForGetInterceptor:
+        sink.writeClasses(set);
+        break;
+      case ModularNameKind.nameForGetOneShotInterceptor:
+        Selector selector = data;
+        selector.writeToDataSink(sink);
+        sink.writeClasses(set);
+        break;
+      case ModularNameKind.asName:
+        sink.writeString(data);
+        break;
+    }
+    sink.end(tag);
+  }
+
+  js.Name get value {
+    assert(_value != null);
+    return _value;
+  }
+
+  void set value(js.Name node) {
+    assert(_value == null);
+    assert(node != null);
+    _value = node.withSourceInformation(sourceInformation);
+  }
+
+  @override
+  String get key {
+    assert(_value != null);
+    return _value.key;
+  }
+
+  @override
+  String get name {
+    assert(_value != null);
+    return _value.name;
+  }
+
+  @override
+  bool get allowRename {
+    assert(_value != null);
+    return _value.allowRename;
+  }
+
+  @override
+  int compareTo(js.Name other) {
+    assert(_value != null);
+    return _value.compareTo(other);
+  }
+
+  @override
+  Iterable<js.Node> get containedNodes {
+    return _value != null ? [_value] : const [];
+  }
+
+  @override
+  int get hashCode {
+    return Hashing.setHash(set, Hashing.objectsHash(kind, data));
+  }
+
+  @override
+  bool operator ==(Object other) {
+    if (identical(this, other)) return true;
+    return other is ModularName &&
+        kind == other.kind &&
+        data == other.data &&
+        equalSets(set, other.set);
+  }
+
+  @override
+  String toString() => 'ModularName(kind=$kind,data=$data,value=${value?.key})';
+}
+
+enum ModularExpressionKind {
+  globalObjectForLibrary,
+  globalObjectForClass,
+  globalObjectForType,
+  globalObjectForMember,
+  constant,
+  embeddedGlobalAccess,
+}
+
+class ModularExpression extends js.DeferredExpression
+    implements js.AstContainer {
+  static const String tag = 'modular-expression';
+
+  final ModularExpressionKind kind;
+  final Object data;
+  js.Expression _value;
+
+  ModularExpression(this.kind, this.data);
+
+  factory ModularExpression.readFromDataSource(DataSource source) {
+    source.begin(tag);
+    ModularExpressionKind kind = source.readEnum(ModularExpressionKind.values);
+    Object data;
+    switch (kind) {
+      case ModularExpressionKind.globalObjectForLibrary:
+        data = source.readLibrary();
+        break;
+      case ModularExpressionKind.globalObjectForClass:
+        data = source.readClass();
+        break;
+      case ModularExpressionKind.globalObjectForType:
+        bool dataIsClassEntity = source.readBool();
+        if (dataIsClassEntity) {
+          data = source.readClass();
+        } else {
+          data = source.readTypedef();
+        }
+        break;
+      case ModularExpressionKind.globalObjectForMember:
+        data = source.readMember();
+        break;
+      case ModularExpressionKind.constant:
+        data = source.readConstant();
+        break;
+      case ModularExpressionKind.embeddedGlobalAccess:
+        data = source.readString();
+        break;
+    }
+    source.end(tag);
+    return new ModularExpression(kind, data);
+  }
+
+  void writeToDataSink(DataSink sink) {
+    sink.begin(tag);
+    sink.writeEnum(kind);
+    switch (kind) {
+      case ModularExpressionKind.globalObjectForLibrary:
+        sink.writeLibrary(data);
+        break;
+      case ModularExpressionKind.globalObjectForClass:
+        sink.writeClass(data);
+        break;
+      case ModularExpressionKind.globalObjectForType:
+        sink.writeBool(data is ClassEntity);
+        if (data is ClassEntity) {
+          sink.writeClass(data);
+        } else {
+          sink.writeTypedef(data);
+        }
+        break;
+      case ModularExpressionKind.globalObjectForMember:
+        sink.writeMember(data);
+        break;
+      case ModularExpressionKind.constant:
+        sink.writeConstant(data);
+        break;
+      case ModularExpressionKind.embeddedGlobalAccess:
+        sink.writeString(data);
+        break;
+    }
+    sink.end(tag);
+  }
+
+  @override
+  js.Expression get value {
+    assert(_value != null);
+    return _value;
+  }
+
+  void set value(js.Expression node) {
+    assert(_value == null);
+    assert(node != null);
+    _value = node.withSourceInformation(sourceInformation);
+  }
+
+  @override
+  int get precedenceLevel => _value?.precedenceLevel ?? js.PRIMARY;
+
+  @override
+  Iterable<js.Node> get containedNodes {
+    return _value != null ? [_value] : const [];
+  }
+
+  @override
+  int get hashCode {
+    return Hashing.objectsHash(kind, data);
+  }
+
+  @override
+  bool operator ==(Object other) {
+    if (identical(this, other)) return true;
+    return other is ModularExpression &&
+        kind == other.kind &&
+        data == other.data;
+  }
+
+  @override
+  String toString() {
+    StringBuffer sb = new StringBuffer();
+    sb.write('ModularExpression(kind=$kind,data=');
+    if (data is ConstantValue) {
+      sb.write((data as ConstantValue).toStructuredText());
+    } else {
+      sb.write(data);
+    }
+    sb.write(',value=$_value)');
+    return sb.toString();
+  }
+}
+
+enum JsNodeKind {
+  comment,
+  await,
+  regExpLiteral,
+  property,
+  objectInitializer,
+  arrayHole,
+  arrayInitializer,
+  parentheses,
+  modularName,
+  asyncName,
+  stringBackedName,
+  stringConcatenation,
+  literalNull,
+  literalNumber,
+  literalString,
+  literalStringFromName,
+  literalBool,
+  modularExpression,
+  function,
+  namedFunction,
+  access,
+  parameter,
+  variableDeclaration,
+  thisExpression,
+  variableUse,
+  postfix,
+  prefix,
+  binary,
+  callExpression,
+  newExpression,
+  conditional,
+  variableInitialization,
+  assignment,
+  variableDeclarationList,
+  literalExpression,
+  dartYield,
+  literalStatement,
+  labeledStatement,
+  functionDeclaration,
+  switchDefault,
+  switchCase,
+  switchStatement,
+  catchClause,
+  tryStatement,
+  throwStatement,
+  returnStatement,
+  breakStatement,
+  continueStatement,
+  doStatement,
+  whileStatement,
+  forInStatement,
+  forStatement,
+  ifStatement,
+  emptyStatement,
+  expressionStatement,
+  block,
+  program,
+}
+
+/// Tags used for debugging serialization/deserialization boundary mismatches.
+class JsNodeTags {
+  static const String tag = 'js-node';
+  static const String comment = 'js-comment';
+  static const String await = 'js-await';
+  static const String regExpLiteral = 'js-regExpLiteral';
+  static const String property = 'js-property';
+  static const String objectInitializer = 'js-objectInitializer';
+  static const String arrayHole = 'js-arrayHole';
+  static const String arrayInitializer = 'js-arrayInitializer';
+  static const String parentheses = 'js-parentheses';
+  static const String modularName = 'js-modularName';
+  static const String asyncName = 'js-asyncName';
+  static const String stringBackedName = 'js-stringBackedName';
+  static const String stringConcatenation = 'js-stringConcatenation';
+  static const String literalNull = 'js-literalNull';
+  static const String literalNumber = 'js-literalNumber';
+  static const String literalString = 'js-literalString';
+  static const String literalStringFromName = 'js-literalStringFromName';
+  static const String literalBool = 'js-literalBool';
+  static const String modularExpression = 'js-modularExpression';
+  static const String function = 'js-function';
+  static const String namedFunction = 'js-namedFunction';
+  static const String access = 'js-access';
+  static const String parameter = 'js-parameter';
+  static const String variableDeclaration = 'js-variableDeclaration';
+  static const String thisExpression = 'js-thisExpression';
+  static const String variableUse = 'js-variableUse';
+  static const String postfix = 'js-postfix';
+  static const String prefix = 'js-prefix';
+  static const String binary = 'js-binary';
+  static const String callExpression = 'js-callExpression';
+  static const String newExpression = 'js-newExpression';
+  static const String conditional = 'js-conditional';
+  static const String variableInitialization = 'js-variableInitialization';
+  static const String assignment = 'js-assignment';
+  static const String variableDeclarationList = 'js-variableDeclarationList';
+  static const String literalExpression = 'js-literalExpression';
+  static const String dartYield = 'js-dartYield';
+  static const String literalStatement = 'js-literalStatement';
+  static const String labeledStatement = 'js-labeledStatement';
+  static const String functionDeclaration = 'js-functionDeclaration';
+  static const String switchDefault = 'js-switchDefault';
+  static const String switchCase = 'js-switchCase';
+  static const String switchStatement = 'js-switchStatement';
+  static const String catchClause = 'js-catchClause';
+  static const String tryStatement = 'js-tryStatement';
+  static const String throwStatement = 'js-throwStatement';
+  static const String returnStatement = 'js-returnStatement';
+  static const String breakStatement = 'js-breakStatement';
+  static const String continueStatement = 'js-continueStatement';
+  static const String doStatement = 'js-doStatement';
+  static const String whileStatement = 'js-whileStatement';
+  static const String forInStatement = 'js-forInStatement';
+  static const String forStatement = 'js-forStatement';
+  static const String ifStatement = 'js-ifStatement';
+  static const String emptyStatement = 'js-emptyStatement';
+  static const String expressionStatement = 'js-expressionStatement';
+  static const String block = 'js-block';
+  static const String program = 'js-program';
+}
+
+/// Visitor that serializes a [js.Node] into a [DataSink].
+class JsNodeSerializer implements js.NodeVisitor<void> {
+  final DataSink sink;
+
+  JsNodeSerializer._(this.sink);
+
+  static void writeToDataSink(DataSink sink, js.Node node) {
+    sink.begin(JsNodeTags.tag);
+    JsNodeSerializer serializer = new JsNodeSerializer._(sink);
+    serializer.visit(node);
+    sink.end(JsNodeTags.tag);
+  }
+
+  void visit(js.Node node, {bool allowNull: false}) {
+    if (allowNull) {
+      sink.writeBool(node != null);
+      if (node != null) {
+        node.accept(this);
+      }
+    } else {
+      node.accept(this);
+    }
+  }
+
+  void visitList(Iterable<js.Node> nodes) {
+    sink.writeList(nodes, visit);
+  }
+
+  void _writeInfo(js.Node node) {
+    SourceInformation.writeToDataSink(sink, node.sourceInformation);
+  }
+
+  @override
+  void visitInterpolatedDeclaration(js.InterpolatedDeclaration node) {
+    throw new UnsupportedError('JsNodeSerializer.visitInterpolatedDeclaration');
+  }
+
+  @override
+  void visitInterpolatedStatement(js.InterpolatedStatement node) {
+    throw new UnsupportedError('JsNodeSerializer.visitInterpolatedStatement');
+  }
+
+  @override
+  void visitInterpolatedSelector(js.InterpolatedSelector node) {
+    throw new UnsupportedError('JsNodeSerializer.visitInterpolatedDeclaration');
+  }
+
+  @override
+  void visitInterpolatedParameter(js.InterpolatedParameter node) {
+    throw new UnsupportedError('JsNodeSerializer.visitInterpolatedParameter');
+  }
+
+  @override
+  void visitInterpolatedLiteral(js.InterpolatedLiteral node) {
+    throw new UnsupportedError('JsNodeSerializer.visitInterpolatedLiteral');
+  }
+
+  @override
+  void visitInterpolatedExpression(js.InterpolatedExpression node) {
+    throw new UnsupportedError('JsNodeSerializer.visitInterpolatedExpression');
+  }
+
+  @override
+  void visitComment(js.Comment node) {
+    sink.writeEnum(JsNodeKind.comment);
+    sink.begin(JsNodeTags.comment);
+    sink.writeString(node.comment);
+    sink.end(JsNodeTags.comment);
+    _writeInfo(node);
+  }
+
+  @override
+  void visitAwait(js.Await node) {
+    sink.writeEnum(JsNodeKind.await);
+    sink.begin(JsNodeTags.await);
+    visit(node.expression);
+    sink.end(JsNodeTags.await);
+    _writeInfo(node);
+  }
+
+  @override
+  void visitRegExpLiteral(js.RegExpLiteral node) {
+    sink.writeEnum(JsNodeKind.regExpLiteral);
+    sink.begin(JsNodeTags.regExpLiteral);
+    sink.writeString(node.pattern);
+    sink.end(JsNodeTags.regExpLiteral);
+    _writeInfo(node);
+  }
+
+  @override
+  void visitProperty(js.Property node) {
+    sink.writeEnum(JsNodeKind.property);
+    sink.begin(JsNodeTags.property);
+    visit(node.name);
+    visit(node.value);
+    sink.end(JsNodeTags.property);
+    _writeInfo(node);
+  }
+
+  @override
+  void visitObjectInitializer(js.ObjectInitializer node) {
+    sink.writeEnum(JsNodeKind.objectInitializer);
+    sink.begin(JsNodeTags.objectInitializer);
+    visitList(node.properties);
+    sink.writeBool(node.isOneLiner);
+    sink.end(JsNodeTags.objectInitializer);
+    _writeInfo(node);
+  }
+
+  @override
+  void visitArrayHole(js.ArrayHole node) {
+    sink.writeEnum(JsNodeKind.arrayHole);
+    sink.begin(JsNodeTags.arrayHole);
+    sink.end(JsNodeTags.arrayHole);
+    _writeInfo(node);
+  }
+
+  @override
+  void visitArrayInitializer(js.ArrayInitializer node) {
+    sink.writeEnum(JsNodeKind.arrayInitializer);
+    sink.begin(JsNodeTags.arrayInitializer);
+    visitList(node.elements);
+    sink.end(JsNodeTags.arrayInitializer);
+    _writeInfo(node);
+  }
+
+  @override
+  void visitParentheses(js.Parentheses node) {
+    sink.writeEnum(JsNodeKind.parentheses);
+    sink.begin(JsNodeTags.parentheses);
+    visit(node.enclosed);
+    sink.end(JsNodeTags.parentheses);
+    _writeInfo(node);
+  }
+
+  @override
+  void visitName(js.Name node) {
+    if (node is ModularName) {
+      sink.writeEnum(JsNodeKind.modularName);
+      sink.begin(JsNodeTags.modularName);
+      node.writeToDataSink(sink);
+      sink.end(JsNodeTags.modularName);
+      _writeInfo(node);
+    } else if (node is AsyncName) {
+      sink.writeEnum(JsNodeKind.asyncName);
+      sink.begin(JsNodeTags.asyncName);
+      visit(node.prefix);
+      visit(node.base);
+      sink.end(JsNodeTags.asyncName);
+      _writeInfo(node);
+    } else if (node is StringBackedName) {
+      sink.writeEnum(JsNodeKind.stringBackedName);
+      sink.begin(JsNodeTags.stringBackedName);
+      sink.writeString(node.name);
+      sink.end(JsNodeTags.stringBackedName);
+      _writeInfo(node);
+    } else {
+      throw new UnsupportedError(
+          'Unexpected deferred expression: ${node.runtimeType}.');
+    }
+  }
+
+  @override
+  void visitStringConcatenation(js.StringConcatenation node) {
+    sink.writeEnum(JsNodeKind.stringConcatenation);
+    sink.begin(JsNodeTags.stringConcatenation);
+    visitList(node.parts);
+    sink.end(JsNodeTags.stringConcatenation);
+    _writeInfo(node);
+  }
+
+  @override
+  void visitLiteralNull(js.LiteralNull node) {
+    sink.writeEnum(JsNodeKind.literalNull);
+    sink.begin(JsNodeTags.literalNull);
+    sink.end(JsNodeTags.literalNull);
+    _writeInfo(node);
+  }
+
+  @override
+  void visitLiteralNumber(js.LiteralNumber node) {
+    sink.writeEnum(JsNodeKind.literalNumber);
+    sink.begin(JsNodeTags.literalNumber);
+    sink.writeString(node.value);
+    sink.end(JsNodeTags.literalNumber);
+    _writeInfo(node);
+  }
+
+  @override
+  void visitLiteralString(js.LiteralString node) {
+    if (node is js.LiteralStringFromName) {
+      sink.writeEnum(JsNodeKind.literalStringFromName);
+      sink.begin(JsNodeTags.literalStringFromName);
+      visit(node.name);
+      sink.end(JsNodeTags.literalStringFromName);
+    } else {
+      sink.writeEnum(JsNodeKind.literalString);
+      sink.begin(JsNodeTags.literalString);
+      sink.writeString(node.value);
+      sink.end(JsNodeTags.literalString);
+    }
+    _writeInfo(node);
+  }
+
+  @override
+  void visitLiteralBool(js.LiteralBool node) {
+    sink.writeEnum(JsNodeKind.literalBool);
+    sink.begin(JsNodeTags.literalBool);
+    sink.writeBool(node.value);
+    sink.end(JsNodeTags.literalBool);
+    _writeInfo(node);
+  }
+
+  @override
+  void visitDeferredString(js.DeferredString node) {
+    throw new UnsupportedError('JsNodeSerializer.visitDeferredString');
+  }
+
+  @override
+  void visitDeferredNumber(js.DeferredNumber node) {
+    throw new UnsupportedError('JsNodeSerializer.visitDeferredNumber');
+  }
+
+  @override
+  void visitDeferredExpression(js.DeferredExpression node) {
+    if (node is ModularExpression) {
+      sink.writeEnum(JsNodeKind.modularExpression);
+      sink.begin(JsNodeTags.modularExpression);
+      node.writeToDataSink(sink);
+      sink.end(JsNodeTags.modularExpression);
+      _writeInfo(node);
+    } else {
+      throw new UnsupportedError(
+          'Unexpected deferred expression: ${node.runtimeType}.');
+    }
+  }
+
+  @override
+  void visitFun(js.Fun node) {
+    sink.writeEnum(JsNodeKind.function);
+    sink.begin(JsNodeTags.function);
+    visitList(node.params);
+    visit(node.body);
+    sink.writeEnum(node.asyncModifier);
+    sink.end(JsNodeTags.function);
+    _writeInfo(node);
+  }
+
+  @override
+  void visitNamedFunction(js.NamedFunction node) {
+    sink.writeEnum(JsNodeKind.namedFunction);
+    sink.begin(JsNodeTags.namedFunction);
+    visit(node.name);
+    visit(node.function);
+    sink.end(JsNodeTags.namedFunction);
+    _writeInfo(node);
+  }
+
+  @override
+  void visitAccess(js.PropertyAccess node) {
+    sink.writeEnum(JsNodeKind.access);
+    sink.begin(JsNodeTags.access);
+    visit(node.receiver);
+    visit(node.selector);
+    sink.end(JsNodeTags.access);
+    _writeInfo(node);
+  }
+
+  @override
+  void visitParameter(js.Parameter node) {
+    sink.writeEnum(JsNodeKind.parameter);
+    sink.begin(JsNodeTags.parameter);
+    sink.writeString(node.name);
+    sink.end(JsNodeTags.parameter);
+    _writeInfo(node);
+  }
+
+  @override
+  void visitVariableDeclaration(js.VariableDeclaration node) {
+    sink.writeEnum(JsNodeKind.variableDeclaration);
+    sink.begin(JsNodeTags.variableDeclaration);
+    sink.writeString(node.name);
+    sink.writeBool(node.allowRename);
+    sink.end(JsNodeTags.variableDeclaration);
+    _writeInfo(node);
+  }
+
+  @override
+  void visitThis(js.This node) {
+    sink.writeEnum(JsNodeKind.thisExpression);
+    sink.begin(JsNodeTags.thisExpression);
+    sink.end(JsNodeTags.thisExpression);
+    _writeInfo(node);
+  }
+
+  @override
+  void visitVariableUse(js.VariableUse node) {
+    sink.writeEnum(JsNodeKind.variableUse);
+    sink.begin(JsNodeTags.variableUse);
+    sink.writeString(node.name);
+    sink.end(JsNodeTags.variableUse);
+    _writeInfo(node);
+  }
+
+  @override
+  void visitPostfix(js.Postfix node) {
+    sink.writeEnum(JsNodeKind.postfix);
+    sink.begin(JsNodeTags.postfix);
+    sink.writeString(node.op);
+    visit(node.argument);
+    sink.end(JsNodeTags.postfix);
+    _writeInfo(node);
+  }
+
+  @override
+  void visitPrefix(js.Prefix node) {
+    sink.writeEnum(JsNodeKind.prefix);
+    sink.begin(JsNodeTags.prefix);
+    sink.writeString(node.op);
+    visit(node.argument);
+    sink.end(JsNodeTags.prefix);
+    _writeInfo(node);
+  }
+
+  @override
+  void visitBinary(js.Binary node) {
+    sink.writeEnum(JsNodeKind.binary);
+    sink.begin(JsNodeTags.binary);
+    sink.writeString(node.op);
+    visit(node.left);
+    visit(node.right);
+    sink.end(JsNodeTags.binary);
+    _writeInfo(node);
+  }
+
+  @override
+  void visitCall(js.Call node) {
+    sink.writeEnum(JsNodeKind.callExpression);
+    sink.begin(JsNodeTags.callExpression);
+    visit(node.target);
+    visitList(node.arguments);
+    sink.end(JsNodeTags.callExpression);
+    _writeInfo(node);
+  }
+
+  @override
+  void visitNew(js.New node) {
+    sink.writeEnum(JsNodeKind.newExpression);
+    sink.begin(JsNodeTags.newExpression);
+    visit(node.target);
+    visitList(node.arguments);
+    sink.end(JsNodeTags.newExpression);
+    _writeInfo(node);
+  }
+
+  @override
+  void visitConditional(js.Conditional node) {
+    sink.writeEnum(JsNodeKind.conditional);
+    sink.begin(JsNodeTags.conditional);
+    visit(node.condition);
+    visit(node.then);
+    visit(node.otherwise);
+    sink.end(JsNodeTags.conditional);
+    _writeInfo(node);
+  }
+
+  @override
+  void visitVariableInitialization(js.VariableInitialization node) {
+    sink.writeEnum(JsNodeKind.variableInitialization);
+    sink.begin(JsNodeTags.variableInitialization);
+    visit(node.declaration);
+    visit(node.value, allowNull: true);
+    sink.end(JsNodeTags.variableInitialization);
+    _writeInfo(node);
+  }
+
+  @override
+  void visitAssignment(js.Assignment node) {
+    sink.writeEnum(JsNodeKind.assignment);
+    sink.begin(JsNodeTags.assignment);
+    visit(node.leftHandSide);
+    sink.writeStringOrNull(node.op);
+    visit(node.value);
+    sink.end(JsNodeTags.assignment);
+    _writeInfo(node);
+  }
+
+  @override
+  void visitVariableDeclarationList(js.VariableDeclarationList node) {
+    sink.writeEnum(JsNodeKind.variableDeclarationList);
+    sink.begin(JsNodeTags.variableDeclarationList);
+    visitList(node.declarations);
+    sink.writeBool(node.indentSplits);
+    sink.end(JsNodeTags.variableDeclarationList);
+    _writeInfo(node);
+  }
+
+  @override
+  void visitLiteralExpression(js.LiteralExpression node) {
+    sink.writeEnum(JsNodeKind.literalExpression);
+    sink.begin(JsNodeTags.literalExpression);
+    sink.writeString(node.template);
+    visitList(node.inputs);
+    sink.end(JsNodeTags.literalExpression);
+    _writeInfo(node);
+  }
+
+  @override
+  void visitDartYield(js.DartYield node) {
+    sink.writeEnum(JsNodeKind.dartYield);
+    sink.begin(JsNodeTags.dartYield);
+    visit(node.expression);
+    sink.writeBool(node.hasStar);
+    sink.end(JsNodeTags.dartYield);
+    _writeInfo(node);
+  }
+
+  @override
+  void visitLiteralStatement(js.LiteralStatement node) {
+    sink.writeEnum(JsNodeKind.literalStatement);
+    sink.begin(JsNodeTags.literalStatement);
+    sink.writeString(node.code);
+    sink.end(JsNodeTags.literalStatement);
+    _writeInfo(node);
+  }
+
+  @override
+  void visitLabeledStatement(js.LabeledStatement node) {
+    sink.writeEnum(JsNodeKind.labeledStatement);
+    sink.begin(JsNodeTags.labeledStatement);
+    sink.writeString(node.label);
+    visit(node.body);
+    sink.end(JsNodeTags.labeledStatement);
+    _writeInfo(node);
+  }
+
+  @override
+  void visitFunctionDeclaration(js.FunctionDeclaration node) {
+    sink.writeEnum(JsNodeKind.functionDeclaration);
+    sink.begin(JsNodeTags.functionDeclaration);
+    visit(node.name);
+    visit(node.function);
+    sink.end(JsNodeTags.functionDeclaration);
+    _writeInfo(node);
+  }
+
+  @override
+  void visitDefault(js.Default node) {
+    sink.writeEnum(JsNodeKind.switchDefault);
+    sink.begin(JsNodeTags.switchDefault);
+    visit(node.body);
+    sink.end(JsNodeTags.switchDefault);
+    _writeInfo(node);
+  }
+
+  @override
+  void visitCase(js.Case node) {
+    sink.writeEnum(JsNodeKind.switchCase);
+    sink.begin(JsNodeTags.switchCase);
+    visit(node.expression);
+    visit(node.body);
+    sink.end(JsNodeTags.switchCase);
+    _writeInfo(node);
+  }
+
+  @override
+  void visitSwitch(js.Switch node) {
+    sink.writeEnum(JsNodeKind.switchStatement);
+    sink.begin(JsNodeTags.switchStatement);
+    visit(node.key);
+    visitList(node.cases);
+    sink.end(JsNodeTags.switchStatement);
+    _writeInfo(node);
+  }
+
+  @override
+  void visitCatch(js.Catch node) {
+    sink.writeEnum(JsNodeKind.catchClause);
+    sink.begin(JsNodeTags.catchClause);
+    visit(node.declaration);
+    visit(node.body);
+    sink.end(JsNodeTags.catchClause);
+    _writeInfo(node);
+  }
+
+  @override
+  void visitTry(js.Try node) {
+    sink.writeEnum(JsNodeKind.tryStatement);
+    sink.begin(JsNodeTags.tryStatement);
+    visit(node.body);
+    visit(node.catchPart, allowNull: true);
+    visit(node.finallyPart, allowNull: true);
+    sink.end(JsNodeTags.tryStatement);
+    _writeInfo(node);
+  }
+
+  @override
+  void visitThrow(js.Throw node) {
+    sink.writeEnum(JsNodeKind.throwStatement);
+    sink.begin(JsNodeTags.throwStatement);
+    visit(node.expression);
+    sink.end(JsNodeTags.throwStatement);
+    _writeInfo(node);
+  }
+
+  @override
+  void visitReturn(js.Return node) {
+    sink.writeEnum(JsNodeKind.returnStatement);
+    sink.begin(JsNodeTags.returnStatement);
+    visit(node.value, allowNull: true);
+    sink.end(JsNodeTags.returnStatement);
+    _writeInfo(node);
+  }
+
+  @override
+  void visitBreak(js.Break node) {
+    sink.writeEnum(JsNodeKind.breakStatement);
+    sink.begin(JsNodeTags.breakStatement);
+    sink.writeStringOrNull(node.targetLabel);
+    sink.end(JsNodeTags.breakStatement);
+    _writeInfo(node);
+  }
+
+  @override
+  void visitContinue(js.Continue node) {
+    sink.writeEnum(JsNodeKind.continueStatement);
+    sink.begin(JsNodeTags.continueStatement);
+    sink.writeStringOrNull(node.targetLabel);
+    sink.end(JsNodeTags.continueStatement);
+    _writeInfo(node);
+  }
+
+  @override
+  void visitDo(js.Do node) {
+    sink.writeEnum(JsNodeKind.doStatement);
+    sink.begin(JsNodeTags.doStatement);
+    visit(node.body);
+    visit(node.condition);
+    sink.end(JsNodeTags.doStatement);
+    _writeInfo(node);
+  }
+
+  @override
+  void visitWhile(js.While node) {
+    sink.writeEnum(JsNodeKind.whileStatement);
+    sink.begin(JsNodeTags.whileStatement);
+    visit(node.condition);
+    visit(node.body);
+    sink.end(JsNodeTags.whileStatement);
+    _writeInfo(node);
+  }
+
+  @override
+  void visitForIn(js.ForIn node) {
+    sink.writeEnum(JsNodeKind.forInStatement);
+    sink.begin(JsNodeTags.forInStatement);
+    visit(node.leftHandSide);
+    visit(node.object);
+    visit(node.body);
+    sink.end(JsNodeTags.forInStatement);
+    _writeInfo(node);
+  }
+
+  @override
+  void visitFor(js.For node) {
+    sink.writeEnum(JsNodeKind.forStatement);
+    sink.begin(JsNodeTags.forStatement);
+    visit(node.init, allowNull: true);
+    visit(node.condition, allowNull: true);
+    visit(node.update, allowNull: true);
+    visit(node.body);
+    sink.end(JsNodeTags.forStatement);
+    _writeInfo(node);
+  }
+
+  @override
+  void visitIf(js.If node) {
+    sink.writeEnum(JsNodeKind.ifStatement);
+    sink.begin(JsNodeTags.ifStatement);
+    visit(node.condition);
+    visit(node.then);
+    visit(node.otherwise);
+    sink.end(JsNodeTags.ifStatement);
+    _writeInfo(node);
+  }
+
+  @override
+  void visitEmptyStatement(js.EmptyStatement node) {
+    sink.writeEnum(JsNodeKind.emptyStatement);
+    sink.begin(JsNodeTags.emptyStatement);
+    sink.end(JsNodeTags.emptyStatement);
+    _writeInfo(node);
+  }
+
+  @override
+  void visitExpressionStatement(js.ExpressionStatement node) {
+    sink.writeEnum(JsNodeKind.expressionStatement);
+    sink.begin(JsNodeTags.expressionStatement);
+    visit(node.expression);
+    sink.end(JsNodeTags.expressionStatement);
+    _writeInfo(node);
+  }
+
+  @override
+  void visitBlock(js.Block node) {
+    sink.writeEnum(JsNodeKind.block);
+    sink.begin(JsNodeTags.block);
+    visitList(node.statements);
+    sink.end(JsNodeTags.block);
+    _writeInfo(node);
+  }
+
+  @override
+  void visitProgram(js.Program node) {
+    sink.writeEnum(JsNodeKind.program);
+    sink.begin(JsNodeTags.program);
+    visitList(node.body);
+    sink.end(JsNodeTags.program);
+    _writeInfo(node);
+  }
+}
+
+/// Helper class that deserializes a [js.Node] from [DataSource].
+///
+/// Deserialized [ModularName]s and [ModularExpression]s are collected in the
+/// [modularNames] and [modularExpressions] lists.
+class JsNodeDeserializer {
+  final DataSource source;
+  final List<ModularName> modularNames;
+  final List<ModularExpression> modularExpressions;
+
+  JsNodeDeserializer._(this.source, this.modularNames, this.modularExpressions);
+
+  static js.Node readFromDataSource(
+      DataSource source,
+      List<ModularName> modularNames,
+      List<ModularExpression> modularExpressions) {
+    source.begin(JsNodeTags.tag);
+    JsNodeDeserializer deserializer =
+        new JsNodeDeserializer._(source, modularNames, modularExpressions);
+    js.Node node = deserializer.read();
+    source.end(JsNodeTags.tag);
+    return node;
+  }
+
+  T read<T extends js.Node>({bool allowNull: false}) {
+    if (allowNull) {
+      bool hasValue = source.readBool();
+      if (!hasValue) return null;
+    }
+    JsNodeKind kind = source.readEnum(JsNodeKind.values);
+    js.Node node;
+    switch (kind) {
+      case JsNodeKind.comment:
+        source.begin(JsNodeTags.comment);
+        node = new js.Comment(source.readString());
+        source.end(JsNodeTags.comment);
+        break;
+      case JsNodeKind.await:
+        source.begin(JsNodeTags.await);
+        node = new js.Await(read());
+        source.end(JsNodeTags.await);
+        break;
+      case JsNodeKind.regExpLiteral:
+        source.begin(JsNodeTags.regExpLiteral);
+        node = new js.RegExpLiteral(source.readString());
+        source.end(JsNodeTags.regExpLiteral);
+        break;
+      case JsNodeKind.property:
+        source.begin(JsNodeTags.property);
+        js.Expression name = read();
+        js.Expression value = read();
+        node = new js.Property(name, value);
+        source.end(JsNodeTags.property);
+        break;
+      case JsNodeKind.objectInitializer:
+        source.begin(JsNodeTags.objectInitializer);
+        List<js.Property> properties = readList();
+        bool isOneLiner = source.readBool();
+        node = new js.ObjectInitializer(properties, isOneLiner: isOneLiner);
+        source.end(JsNodeTags.objectInitializer);
+        break;
+      case JsNodeKind.arrayHole:
+        source.begin(JsNodeTags.arrayHole);
+        node = new js.ArrayHole();
+        source.end(JsNodeTags.arrayHole);
+        break;
+      case JsNodeKind.arrayInitializer:
+        source.begin(JsNodeTags.arrayInitializer);
+        List<js.Expression> elements = readList();
+        node = new js.ArrayInitializer(elements);
+        source.end(JsNodeTags.arrayInitializer);
+        break;
+      case JsNodeKind.parentheses:
+        source.begin(JsNodeTags.parentheses);
+        node = new js.Parentheses(read());
+        source.end(JsNodeTags.parentheses);
+        break;
+      case JsNodeKind.modularName:
+        source.begin(JsNodeTags.modularName);
+        ModularName modularName = ModularName.readFromDataSource(source);
+        modularNames.add(modularName);
+        node = modularName;
+        source.end(JsNodeTags.modularName);
+        break;
+      case JsNodeKind.asyncName:
+        source.begin(JsNodeTags.asyncName);
+        js.Name prefix = read();
+        js.Name base = read();
+        node = new AsyncName(prefix, base);
+        source.end(JsNodeTags.asyncName);
+        break;
+      case JsNodeKind.stringBackedName:
+        source.begin(JsNodeTags.stringBackedName);
+        node = new StringBackedName(source.readString());
+        source.end(JsNodeTags.stringBackedName);
+        break;
+      case JsNodeKind.stringConcatenation:
+        source.begin(JsNodeTags.stringConcatenation);
+        List<js.Literal> parts = readList();
+        node = new js.StringConcatenation(parts);
+        source.end(JsNodeTags.stringConcatenation);
+        break;
+      case JsNodeKind.literalNull:
+        source.begin(JsNodeTags.literalNull);
+        node = new js.LiteralNull();
+        source.end(JsNodeTags.literalNull);
+        break;
+      case JsNodeKind.literalNumber:
+        source.begin(JsNodeTags.literalNumber);
+        node = new js.LiteralNumber(source.readString());
+        source.end(JsNodeTags.literalNumber);
+        break;
+      case JsNodeKind.literalString:
+        source.begin(JsNodeTags.literalString);
+        node = new js.LiteralString(source.readString());
+        source.end(JsNodeTags.literalString);
+        break;
+      case JsNodeKind.literalStringFromName:
+        source.begin(JsNodeTags.literalStringFromName);
+        js.Name name = read();
+        node = new js.LiteralStringFromName(name);
+        source.end(JsNodeTags.literalStringFromName);
+        break;
+      case JsNodeKind.literalBool:
+        source.begin(JsNodeTags.literalBool);
+        node = new js.LiteralBool(source.readBool());
+        source.end(JsNodeTags.literalBool);
+        break;
+      case JsNodeKind.modularExpression:
+        source.begin(JsNodeTags.modularExpression);
+        ModularExpression modularExpression =
+            ModularExpression.readFromDataSource(source);
+        modularExpressions.add(modularExpression);
+        node = modularExpression;
+        source.end(JsNodeTags.modularExpression);
+        break;
+      case JsNodeKind.function:
+        source.begin(JsNodeTags.function);
+        List<js.Parameter> params = readList();
+        js.Block body = read();
+        js.AsyncModifier asyncModifier =
+            source.readEnum(js.AsyncModifier.values);
+        node = new js.Fun(params, body, asyncModifier: asyncModifier);
+        source.end(JsNodeTags.function);
+        break;
+      case JsNodeKind.namedFunction:
+        source.begin(JsNodeTags.namedFunction);
+        js.Declaration name = read();
+        js.Fun function = read();
+        node = new js.NamedFunction(name, function);
+        source.end(JsNodeTags.namedFunction);
+        break;
+      case JsNodeKind.access:
+        source.begin(JsNodeTags.access);
+        js.Expression receiver = read();
+        js.Expression selector = read();
+        node = new js.PropertyAccess(receiver, selector);
+        source.end(JsNodeTags.access);
+        break;
+      case JsNodeKind.parameter:
+        source.begin(JsNodeTags.parameter);
+        node = new js.Parameter(source.readString());
+        source.end(JsNodeTags.parameter);
+        break;
+      case JsNodeKind.variableDeclaration:
+        source.begin(JsNodeTags.variableDeclaration);
+        String name = source.readString();
+        bool allowRename = source.readBool();
+        node = new js.VariableDeclaration(name, allowRename: allowRename);
+        source.end(JsNodeTags.variableDeclaration);
+        break;
+      case JsNodeKind.thisExpression:
+        source.begin(JsNodeTags.thisExpression);
+        node = new js.This();
+        source.end(JsNodeTags.thisExpression);
+        break;
+      case JsNodeKind.variableUse:
+        source.begin(JsNodeTags.variableUse);
+        node = new js.VariableUse(source.readString());
+        source.end(JsNodeTags.variableUse);
+        break;
+      case JsNodeKind.postfix:
+        source.begin(JsNodeTags.postfix);
+        String op = source.readString();
+        js.Expression argument = read();
+        node = new js.Postfix(op, argument);
+        source.end(JsNodeTags.postfix);
+        break;
+      case JsNodeKind.prefix:
+        source.begin(JsNodeTags.prefix);
+        String op = source.readString();
+        js.Expression argument = read();
+        node = new js.Prefix(op, argument);
+        source.end(JsNodeTags.prefix);
+        break;
+      case JsNodeKind.binary:
+        source.begin(JsNodeTags.binary);
+        String op = source.readString();
+        js.Expression left = read();
+        js.Expression right = read();
+        node = new js.Binary(op, left, right);
+        source.end(JsNodeTags.binary);
+        break;
+      case JsNodeKind.callExpression:
+        source.begin(JsNodeTags.callExpression);
+        js.Expression target = read();
+        List<js.Expression> arguments = readList();
+        node = new js.Call(target, arguments);
+        source.end(JsNodeTags.callExpression);
+        break;
+      case JsNodeKind.newExpression:
+        source.begin(JsNodeTags.newExpression);
+        js.Expression cls = read();
+        List<js.Expression> arguments = readList();
+        node = new js.New(cls, arguments);
+        source.end(JsNodeTags.newExpression);
+        break;
+      case JsNodeKind.conditional:
+        source.begin(JsNodeTags.conditional);
+        js.Expression condition = read();
+        js.Expression then = read();
+        js.Expression otherwise = read();
+        node = new js.Conditional(condition, then, otherwise);
+        source.end(JsNodeTags.conditional);
+        break;
+      case JsNodeKind.variableInitialization:
+        source.begin(JsNodeTags.variableInitialization);
+        js.Declaration declaration = read();
+        js.Expression value = source.readValueOrNull(read);
+        node = new js.VariableInitialization(declaration, value);
+        source.end(JsNodeTags.variableInitialization);
+        break;
+      case JsNodeKind.assignment:
+        source.begin(JsNodeTags.assignment);
+        js.Expression leftHandSide = read();
+        String op = source.readStringOrNull();
+        js.Expression value = read();
+        node = new js.Assignment.compound(leftHandSide, op, value);
+        source.end(JsNodeTags.assignment);
+        break;
+      case JsNodeKind.variableDeclarationList:
+        source.begin(JsNodeTags.variableDeclarationList);
+        List<js.VariableInitialization> declarations = readList();
+        bool indentSplits = source.readBool();
+        node = new js.VariableDeclarationList(declarations,
+            indentSplits: indentSplits);
+        source.end(JsNodeTags.variableDeclarationList);
+        break;
+      case JsNodeKind.literalExpression:
+        source.begin(JsNodeTags.literalExpression);
+        String template = source.readString();
+        List<js.Expression> inputs = readList();
+        node = new js.LiteralExpression.withData(template, inputs);
+        source.end(JsNodeTags.literalExpression);
+        break;
+      case JsNodeKind.dartYield:
+        source.begin(JsNodeTags.dartYield);
+        js.Expression expression = read();
+        bool hasStar = source.readBool();
+        node = new js.DartYield(expression, hasStar);
+        source.end(JsNodeTags.dartYield);
+        break;
+      case JsNodeKind.literalStatement:
+        source.begin(JsNodeTags.literalStatement);
+        node = new js.LiteralStatement(source.readString());
+        source.end(JsNodeTags.literalStatement);
+        break;
+      case JsNodeKind.labeledStatement:
+        source.begin(JsNodeTags.labeledStatement);
+        String label = source.readString();
+        js.Statement body = read();
+        node = new js.LabeledStatement(label, body);
+        source.end(JsNodeTags.labeledStatement);
+        break;
+      case JsNodeKind.functionDeclaration:
+        source.begin(JsNodeTags.functionDeclaration);
+        js.Declaration name = read();
+        js.Fun function = read();
+        node = new js.FunctionDeclaration(name, function);
+        source.end(JsNodeTags.functionDeclaration);
+        break;
+      case JsNodeKind.switchDefault:
+        source.begin(JsNodeTags.switchDefault);
+        js.Block body = read();
+        node = new js.Default(body);
+        source.end(JsNodeTags.switchDefault);
+        break;
+      case JsNodeKind.switchCase:
+        source.begin(JsNodeTags.switchCase);
+        js.Expression expression = read();
+        js.Block body = read();
+        node = new js.Case(expression, body);
+        source.end(JsNodeTags.switchCase);
+        break;
+      case JsNodeKind.switchStatement:
+        source.begin(JsNodeTags.switchStatement);
+        js.Expression key = read();
+        List<js.SwitchClause> cases = readList();
+        node = new js.Switch(key, cases);
+        source.end(JsNodeTags.switchStatement);
+        break;
+      case JsNodeKind.catchClause:
+        source.begin(JsNodeTags.catchClause);
+        js.Declaration declaration = read();
+        js.Block body = read();
+        node = new js.Catch(declaration, body);
+        source.end(JsNodeTags.catchClause);
+        break;
+      case JsNodeKind.tryStatement:
+        source.begin(JsNodeTags.tryStatement);
+        js.Block body = read();
+        js.Catch catchPart = source.readValueOrNull(read);
+        js.Block finallyPart = source.readValueOrNull(read);
+        node = new js.Try(body, catchPart, finallyPart);
+        source.end(JsNodeTags.tryStatement);
+        break;
+      case JsNodeKind.throwStatement:
+        source.begin(JsNodeTags.throwStatement);
+        js.Expression expression = read();
+        node = new js.Throw(expression);
+        source.end(JsNodeTags.throwStatement);
+        break;
+      case JsNodeKind.returnStatement:
+        source.begin(JsNodeTags.returnStatement);
+        js.Expression value = source.readValueOrNull(read);
+        node = new js.Return(value);
+        source.end(JsNodeTags.returnStatement);
+        break;
+      case JsNodeKind.breakStatement:
+        source.begin(JsNodeTags.breakStatement);
+        String targetLabel = source.readStringOrNull();
+        node = new js.Break(targetLabel);
+        source.end(JsNodeTags.breakStatement);
+        break;
+      case JsNodeKind.continueStatement:
+        source.begin(JsNodeTags.continueStatement);
+        String targetLabel = source.readStringOrNull();
+        node = new js.Continue(targetLabel);
+        source.end(JsNodeTags.continueStatement);
+        break;
+      case JsNodeKind.doStatement:
+        source.begin(JsNodeTags.doStatement);
+        js.Statement body = read();
+        js.Expression condition = read();
+        node = new js.Do(body, condition);
+        source.end(JsNodeTags.doStatement);
+        break;
+      case JsNodeKind.whileStatement:
+        source.begin(JsNodeTags.whileStatement);
+        js.Expression condition = read();
+        js.Statement body = read();
+        node = new js.While(condition, body);
+        source.end(JsNodeTags.whileStatement);
+        break;
+      case JsNodeKind.forInStatement:
+        source.begin(JsNodeTags.forInStatement);
+        js.Expression leftHandSide = read();
+        js.Expression object = read();
+        js.Statement body = read();
+        node = new js.ForIn(leftHandSide, object, body);
+        source.end(JsNodeTags.forInStatement);
+        break;
+      case JsNodeKind.forStatement:
+        source.begin(JsNodeTags.forStatement);
+        js.Expression init = read(allowNull: true);
+        js.Expression condition = read(allowNull: true);
+        js.Expression update = read(allowNull: true);
+        js.Statement body = read();
+        node = new js.For(init, condition, update, body);
+        source.end(JsNodeTags.forStatement);
+        break;
+      case JsNodeKind.ifStatement:
+        source.begin(JsNodeTags.ifStatement);
+        js.Expression condition = read();
+        js.Statement then = read();
+        js.Statement otherwise = read();
+        node = new js.If(condition, then, otherwise);
+        source.end(JsNodeTags.ifStatement);
+        break;
+      case JsNodeKind.emptyStatement:
+        source.begin(JsNodeTags.emptyStatement);
+        node = new js.EmptyStatement();
+        source.end(JsNodeTags.emptyStatement);
+        break;
+      case JsNodeKind.expressionStatement:
+        source.begin(JsNodeTags.expressionStatement);
+        node = new js.ExpressionStatement(read());
+        source.end(JsNodeTags.expressionStatement);
+        break;
+      case JsNodeKind.block:
+        source.begin(JsNodeTags.block);
+        List<js.Statement> statements = readList();
+        node = new js.Block(statements);
+        source.end(JsNodeTags.block);
+        break;
+      case JsNodeKind.program:
+        source.begin(JsNodeTags.program);
+        List<js.Statement> body = readList();
+        node = new js.Program(body);
+        source.end(JsNodeTags.program);
+        break;
+    }
+    SourceInformation sourceInformation =
+        SourceInformation.readFromDataSource(source);
+    if (sourceInformation != null) {
+      node = node.withSourceInformation(sourceInformation);
+    }
+    return node;
+  }
+
+  List<T> readList<T extends js.Node>({bool emptyAsNull: false}) {
+    return source.readList(read, emptyAsNull: emptyAsNull);
+  }
+}
+
+class CodegenReaderImpl implements CodegenReader {
+  final JClosedWorld closedWorld;
+  final List<ModularName> modularNames;
+  final List<ModularExpression> modularExpressions;
+
+  CodegenReaderImpl(
+      this.closedWorld, this.modularNames, this.modularExpressions);
+
+  @override
+  AbstractValue readAbstractValue(DataSource source) {
+    return closedWorld.abstractValueDomain
+        .readAbstractValueFromDataSource(source);
+  }
+
+  @override
+  js.Node readJsNode(DataSource source) {
+    return JsNodeDeserializer.readFromDataSource(
+        source, modularNames, modularExpressions);
+  }
+
+  @override
+  OutputUnit readOutputUnitReference(DataSource source) {
+    return closedWorld.outputUnitData.outputUnits[source.readInt()];
+  }
+}
+
+class CodegenWriterImpl implements CodegenWriter {
+  final JClosedWorld closedWorld;
+
+  CodegenWriterImpl(this.closedWorld);
+
+  @override
+  void writeAbstractValue(DataSink sink, AbstractValue value) {
+    closedWorld.abstractValueDomain.writeAbstractValueToDataSink(sink, value);
+  }
+
+  @override
+  void writeJsNode(DataSink sink, js.Node node) {
+    JsNodeSerializer.writeToDataSink(sink, node);
+  }
+
+  @override
+  void writeOutputUnitReference(DataSink sink, OutputUnit value) {
+    sink.writeInt(closedWorld.outputUnitData.outputUnits.indexOf(value));
+  }
 }
diff --git a/pkg/compiler/lib/src/compiler.dart b/pkg/compiler/lib/src/compiler.dart
index a2c1f14..a0b1e01 100644
--- a/pkg/compiler/lib/src/compiler.dart
+++ b/pkg/compiler/lib/src/compiler.dart
@@ -233,7 +233,7 @@
         performGlobalTypeInference(results.closedWorld);
         return;
       }
-      generateJavaScriptCode(results);
+      emitJavaScriptCode(results);
     } else {
       KernelResult result = await kernelLoader.load(uri);
       reporter.log("Kernel load complete");
@@ -355,19 +355,19 @@
         mainFunction, closedWorld, inferredDataBuilder);
   }
 
-  void generateJavaScriptCode(
-      GlobalTypeInferenceResults globalInferenceResults) {
+  void emitJavaScriptCode(GlobalTypeInferenceResults globalInferenceResults) {
     JClosedWorld closedWorld = globalInferenceResults.closedWorld;
     backendStrategy.registerJClosedWorld(closedWorld);
-    FunctionEntity mainFunction = closedWorld.elementEnvironment.mainFunction;
     if (options.showInternalProgress) reporter.log('Compiling...');
     phase = PHASE_COMPILING;
 
-    CodegenInputs codegen = backend.onCodegenStart(closedWorld);
+    CodegenInputs codegen = backend.onCodegenStart(globalInferenceResults);
+    backend.onCodegenEnqueuerStart(globalInferenceResults, codegen);
     Enqueuer codegenEnqueuer = enqueuer.createCodegenEnqueuer(
         closedWorld, globalInferenceResults, codegen);
     _codegenWorldBuilder = codegenEnqueuer.worldBuilder;
 
+    FunctionEntity mainFunction = closedWorld.elementEnvironment.mainFunction;
     processQueue(closedWorld.elementEnvironment, codegenEnqueuer, mainFunction,
         onProgress: showCodegenProgress);
     codegenEnqueuer.logSummary(reporter.log);
@@ -416,7 +416,7 @@
               worldData);
         }
         if (stopAfterTypeInference) return;
-        generateJavaScriptCode(globalInferenceResults);
+        emitJavaScriptCode(globalInferenceResults);
       }
     });
   }
diff --git a/pkg/compiler/lib/src/constants/values.dart b/pkg/compiler/lib/src/constants/values.dart
index ffb7acf..c10956f 100644
--- a/pkg/compiler/lib/src/constants/values.dart
+++ b/pkg/compiler/lib/src/constants/values.dart
@@ -9,6 +9,8 @@
 import '../elements/entities.dart';
 import '../elements/types.dart';
 import '../deferred_load.dart' show OutputUnit;
+import '../inferrer/abstract_value_domain.dart';
+import '../js/js.dart' as js;
 import '../util/util.dart';
 
 enum ConstantValueKind {
@@ -24,7 +26,8 @@
   CONSTRUCTED,
   TYPE,
   INTERCEPTOR,
-  SYNTHETIC,
+  JS_NAME,
+  ABSTRACT_VALUE,
   INSTANTIATION,
   DEFERRED_GLOBAL,
   NON_CONSTANT,
@@ -47,7 +50,9 @@
   R visitType(covariant TypeConstantValue constant, covariant A arg);
   R visitInterceptor(
       covariant InterceptorConstantValue constant, covariant A arg);
-  R visitSynthetic(covariant SyntheticConstantValue constant, covariant A arg);
+  R visitAbstractValue(
+      covariant AbstractValueConstantValue constant, covariant A arg);
+  R visitJsName(covariant JsNameConstantValue constant, covariant A arg);
   R visitDeferredGlobal(
       covariant DeferredGlobalConstantValue constant, covariant A arg);
   R visitNonConstant(covariant NonConstantValue constant, covariant A arg);
@@ -808,42 +813,81 @@
   }
 }
 
-class SyntheticConstantValue extends ConstantValue {
-  final payload;
-  final valueKind;
+class JsNameConstantValue extends ConstantValue {
+  final js.LiteralString name;
 
-  SyntheticConstantValue(this.valueKind, this.payload);
+  JsNameConstantValue(this.name);
 
   @override
   bool get isDummy => true;
 
   @override
   bool operator ==(other) {
-    return other is SyntheticConstantValue && payload == other.payload;
+    return other is JsNameConstantValue && name == other.name;
   }
 
   @override
-  get hashCode => payload.hashCode * 17 + valueKind.hashCode;
+  get hashCode => name.hashCode * 17;
 
   @override
   List<ConstantValue> getDependencies() => const <ConstantValue>[];
 
   @override
   accept(ConstantValueVisitor visitor, arg) {
-    return visitor.visitSynthetic(this, arg);
+    return visitor.visitJsName(this, arg);
   }
 
   @override
   DartType getType(CommonElements types) => types.dynamicType;
 
   @override
-  ConstantValueKind get kind => ConstantValueKind.SYNTHETIC;
+  ConstantValueKind get kind => ConstantValueKind.JS_NAME;
 
   @override
-  String toDartText() => 'synthetic($valueKind, $payload)';
+  String toDartText() => 'js_name(${name})';
 
   @override
-  String toStructuredText() => 'SyntheticConstant($valueKind, $payload)';
+  String toStructuredText() => 'JsNameConstant(${name})';
+}
+
+/// An abstract value as a constant value. This is only used during code
+/// generation.
+class AbstractValueConstantValue extends ConstantValue {
+  final AbstractValue abstractValue;
+
+  AbstractValueConstantValue(this.abstractValue);
+
+  @override
+  bool get isDummy => true;
+
+  @override
+  bool operator ==(other) {
+    return other is AbstractValueConstantValue &&
+        abstractValue == other.abstractValue;
+  }
+
+  @override
+  get hashCode => abstractValue.hashCode * 17;
+
+  @override
+  List<ConstantValue> getDependencies() => const <ConstantValue>[];
+
+  @override
+  accept(ConstantValueVisitor visitor, arg) {
+    return visitor.visitAbstractValue(this, arg);
+  }
+
+  @override
+  DartType getType(CommonElements types) => types.dynamicType;
+
+  @override
+  ConstantValueKind get kind => ConstantValueKind.ABSTRACT_VALUE;
+
+  @override
+  String toDartText() => 'abstract_value($abstractValue)';
+
+  @override
+  String toStructuredText() => 'AbstractValueConstant($abstractValue)';
 }
 
 class ConstructedConstantValue extends ObjectConstantValue {
diff --git a/pkg/compiler/lib/src/deferred_load.dart b/pkg/compiler/lib/src/deferred_load.dart
index dd23b37..5c32df6 100644
--- a/pkg/compiler/lib/src/deferred_load.dart
+++ b/pkg/compiler/lib/src/deferred_load.dart
@@ -1235,7 +1235,7 @@
   final Map<MemberEntity, OutputUnit> _memberToUnit;
   final Map<Local, OutputUnit> _localFunctionToUnit;
   final Map<ConstantValue, OutputUnit> _constantToUnit;
-  final Iterable<OutputUnit> outputUnits;
+  final List<OutputUnit> outputUnits;
   final Map<ImportEntity, String> _importDeferName;
 
   /// A mapping from the name of a defer import to all the output units it
diff --git a/pkg/compiler/lib/src/inferrer/typemasks/constants.dart b/pkg/compiler/lib/src/inferrer/typemasks/constants.dart
index 9b5232f..a453382 100644
--- a/pkg/compiler/lib/src/inferrer/typemasks/constants.dart
+++ b/pkg/compiler/lib/src/inferrer/typemasks/constants.dart
@@ -4,10 +4,8 @@
 
 library types.constants;
 
-import '../../common.dart';
 import '../../constants/constant_system.dart' as constant_system;
 import '../../constants/values.dart';
-import '../../js_backend/js_backend.dart' show SyntheticConstantKind;
 import '../../world.dart' show JClosedWorld;
 import 'masks.dart';
 
@@ -50,21 +48,14 @@
   }
 
   @override
-  TypeMask visitSynthetic(
-      SyntheticConstantValue constant, JClosedWorld closedWorld) {
-    switch (constant.valueKind) {
-      case SyntheticConstantKind.DUMMY_INTERCEPTOR:
-        return constant.payload;
-      case SyntheticConstantKind.EMPTY_VALUE:
-        return constant.payload;
-      case SyntheticConstantKind.TYPEVARIABLE_REFERENCE:
-        return closedWorld.abstractValueDomain.intType;
-      case SyntheticConstantKind.NAME:
-        return closedWorld.abstractValueDomain.stringType;
-      default:
-        throw failedAt(CURRENT_ELEMENT_SPANNABLE,
-            "Unexpected DummyConstantKind: ${constant.toStructuredText()}.");
-    }
+  TypeMask visitAbstractValue(
+      AbstractValueConstantValue constant, JClosedWorld closedWorld) {
+    return constant.abstractValue;
+  }
+
+  @override
+  TypeMask visitJsName(JsNameConstantValue constant, JClosedWorld closedWorld) {
+    return closedWorld.abstractValueDomain.stringType;
   }
 
   @override
diff --git a/pkg/compiler/lib/src/io/position_information.dart b/pkg/compiler/lib/src/io/position_information.dart
index 732b841..a92ab7e 100644
--- a/pkg/compiler/lib/src/io/position_information.dart
+++ b/pkg/compiler/lib/src/io/position_information.dart
@@ -11,12 +11,15 @@
 import '../js/js.dart' as js;
 import '../js/js_debug.dart';
 import '../js/js_source_mapping.dart';
+import '../serialization/serialization.dart';
 import 'code_output.dart' show BufferedCodeOutput;
 import 'source_information.dart';
 
 /// [SourceInformation] that consists of an offset position into the source
 /// code.
 class PositionSourceInformation extends SourceInformation {
+  static const String tag = 'source-information';
+
   @override
   final SourceLocation startPosition;
 
@@ -29,6 +32,28 @@
   PositionSourceInformation(
       this.startPosition, this.innerPosition, this.inliningContext);
 
+  factory PositionSourceInformation.readFromDataSource(DataSource source) {
+    source.begin(tag);
+    SourceLocation startPosition = SourceLocation.readFromDataSource(source);
+    SourceLocation innerPosition = SourceLocation.readFromDataSource(source);
+    List<FrameContext> inliningContext = source.readList(
+        () => FrameContext.readFromDataSource(source),
+        emptyAsNull: true);
+    source.end(tag);
+    return new PositionSourceInformation(
+        startPosition, innerPosition, inliningContext);
+  }
+
+  void writeToDataSinkInternal(DataSink sink) {
+    sink.begin(tag);
+    SourceLocation.writeToDataSink(sink, startPosition);
+    SourceLocation.writeToDataSink(sink, innerPosition);
+    sink.writeList(inliningContext,
+        (FrameContext context) => context.writeToDataSink(sink),
+        allowNull: true);
+    sink.end(tag);
+  }
+
   @override
   List<SourceLocation> get sourceLocations {
     List<SourceLocation> list = <SourceLocation>[];
@@ -647,18 +672,18 @@
   /// (@ marks the current JavaScript position and ^ point to the mapped Dart
   /// code position.)
   static CallPosition getSemanticPositionForCall(js.Call node) {
-    if (node.target is js.PropertyAccess) {
-      js.PropertyAccess access = node.target;
+    js.Expression access = js.undefer(node.target);
+    if (access is js.PropertyAccess) {
       js.Node target = access;
       bool pureAccess = false;
       while (target is js.PropertyAccess) {
         js.PropertyAccess targetAccess = target;
-        if (targetAccess.receiver is js.VariableUse ||
-            targetAccess.receiver is js.This) {
+        js.Node receiver = js.undefer(targetAccess.receiver);
+        if (receiver is js.VariableUse || receiver is js.This) {
           pureAccess = true;
           break;
         } else {
-          target = targetAccess.receiver;
+          target = receiver;
         }
       }
       if (pureAccess) {
@@ -672,19 +697,19 @@
         return new CallPosition(
             access.selector, CodePositionKind.START, SourcePositionKind.INNER);
       }
-    } else if (node.target is js.VariableUse || node.target is js.This) {
+    } else if (access is js.VariableUse || access is js.This) {
       // m()   this()
       // ^     ^
       return new CallPosition(
           node, CodePositionKind.START, SourcePositionKind.START);
-    } else if (node.target is js.Fun ||
-        node.target is js.New ||
-        node.target is js.NamedFunction) {
+    } else if (access is js.Fun ||
+        access is js.New ||
+        access is js.NamedFunction) {
       // function(){}()  new Function("...")()   function foo(){}()
       //             ^                      ^                    ^
       return new CallPosition(
           node.target, CodePositionKind.END, SourcePositionKind.INNER);
-    } else if (node.target is js.Binary || node.target is js.Call) {
+    } else if (access is js.Binary || access is js.Call) {
       // (0,a)()   m()()
       //      ^       ^
       return new CallPosition(
@@ -1271,6 +1296,11 @@
     statementOffset = null;
   }
 
+  @override
+  visitDeferredExpression(js.DeferredExpression node) {
+    visit(node.value);
+  }
+
   Offset getOffsetForNode(js.Node node, int codeOffset) {
     if (codeOffset == null) {
       CodePosition codePosition = codePositions[node];
diff --git a/pkg/compiler/lib/src/io/source_information.dart b/pkg/compiler/lib/src/io/source_information.dart
index 64ca507..bc8f6e7 100644
--- a/pkg/compiler/lib/src/io/source_information.dart
+++ b/pkg/compiler/lib/src/io/source_information.dart
@@ -8,14 +8,41 @@
 import '../common.dart';
 import '../elements/entities.dart';
 import '../js/js.dart' show JavaScriptNodeSourceInformation;
+import '../serialization/serialization.dart';
 import '../universe/call_structure.dart';
 import 'source_file.dart';
+import 'position_information.dart';
 
 /// Interface for passing source information, for instance for use in source
 /// maps, through the backend.
 abstract class SourceInformation extends JavaScriptNodeSourceInformation {
   const SourceInformation();
 
+  static SourceInformation readFromDataSource(DataSource source) {
+    int hasSourceInformation = source.readInt();
+    if (hasSourceInformation == 0) {
+      return null;
+    } else if (hasSourceInformation == 1) {
+      return const SourceMappedMarker();
+    } else {
+      assert(hasSourceInformation == 2);
+      return PositionSourceInformation.readFromDataSource(source);
+    }
+  }
+
+  static void writeToDataSink(
+      DataSink sink, SourceInformation sourceInformation) {
+    if (sourceInformation == null) {
+      sink.writeInt(0);
+    } else if (sourceInformation is SourceMappedMarker) {
+      sink.writeInt(1);
+    } else {
+      sink.writeInt(2);
+      PositionSourceInformation positionSourceInformation = sourceInformation;
+      positionSourceInformation.writeToDataSinkInternal(sink);
+    }
+  }
+
   SourceSpan get sourceSpan;
 
   /// The source location associated with the start of the JS node.
@@ -45,6 +72,8 @@
 /// precise data about inlining that can then be used by defobuscation tools
 /// when reconstructing a source stack from a production stack trace.
 class FrameContext {
+  static const String tag = 'frame-context';
+
   /// Location of the call that was inlined.
   final SourceInformation callInformation;
 
@@ -53,6 +82,22 @@
 
   FrameContext(this.callInformation, this.inlinedMethodName);
 
+  factory FrameContext.readFromDataSource(DataSource source) {
+    source.begin(tag);
+    SourceInformation callInformation =
+        SourceInformation.readFromDataSource(source);
+    String inlinedMethodName = source.readString();
+    source.end(tag);
+    return new FrameContext(callInformation, inlinedMethodName);
+  }
+
+  void writeToDataSink(DataSink sink) {
+    sink.begin(tag);
+    SourceInformation.writeToDataSink(sink, callInformation);
+    sink.writeString(inlinedMethodName);
+    sink.end(tag);
+  }
+
   @override
   String toString() => "(FrameContext: $callInformation, $inlinedMethodName)";
 }
@@ -206,6 +251,8 @@
 
 /// A location in a source file.
 abstract class SourceLocation {
+  static const String tag = 'source-location';
+
   const SourceLocation();
 
   /// The absolute URI of the source file of this source location.
@@ -223,8 +270,42 @@
   /// The name associated with this source location, if any.
   String get sourceName;
 
-  /// `true` if the offset within the length of the source file.
-  bool get isValid;
+  static SourceLocation readFromDataSource(DataSource source) {
+    int hasSourceLocation = source.readInt();
+    if (hasSourceLocation == 0) {
+      return null;
+    } else if (hasSourceLocation == 1) {
+      return const NoSourceLocationMarker();
+    } else {
+      assert(hasSourceLocation == 2);
+      source.begin(tag);
+      Uri sourceUri = source.readUri();
+      int offset = source.readInt();
+      int line = source.readInt();
+      int column = source.readInt();
+      String sourceName = source.readString();
+      source.end(tag);
+      return new DirectSourceLocation(
+          sourceUri, offset, line, column, sourceName);
+    }
+  }
+
+  static void writeToDataSink(DataSink sink, SourceLocation sourceLocation) {
+    if (sourceLocation == null) {
+      sink.writeInt(0);
+    } else if (sourceLocation is NoSourceLocationMarker) {
+      sink.writeInt(1);
+    } else {
+      sink.writeInt(2);
+      sink.begin(tag);
+      sink.writeUri(sourceLocation.sourceUri);
+      sink.writeInt(sourceLocation.offset);
+      sink.writeInt(sourceLocation.line);
+      sink.writeInt(sourceLocation.column);
+      sink.writeString(sourceLocation.sourceName);
+      sink.end(tag);
+    }
+  }
 
   @override
   int get hashCode {
@@ -248,6 +329,26 @@
   String toString() => '${sourceUri}:[${line},${column}]';
 }
 
+class DirectSourceLocation extends SourceLocation {
+  @override
+  final Uri sourceUri;
+
+  @override
+  final int offset;
+
+  @override
+  final int line;
+
+  @override
+  final int column;
+
+  @override
+  final String sourceName;
+
+  DirectSourceLocation(
+      this.sourceUri, this.offset, this.line, this.column, this.sourceName);
+}
+
 /// A location in a source file.
 abstract class AbstractSourceLocation extends SourceLocation {
   final SourceFile _sourceFile;
@@ -255,7 +356,7 @@
 
   AbstractSourceLocation(this._sourceFile) {
     assert(
-        isValid,
+        offset < _sourceFile.length,
         failedAt(
             new SourceSpan(sourceUri, 0, 0),
             "Invalid source location in ${sourceUri}: "
@@ -283,9 +384,6 @@
   String get sourceName;
 
   @override
-  bool get isValid => offset < _sourceFile.length;
-
-  @override
   String get shortText => '${sourceUri.pathSegments.last}:[$line,$column]';
 
   @override
@@ -359,9 +457,6 @@
   Uri get sourceUri => null;
 
   @override
-  bool get isValid => true;
-
-  @override
   String get sourceName => null;
 
   @override
diff --git a/pkg/compiler/lib/src/ir/static_type.dart b/pkg/compiler/lib/src/ir/static_type.dart
index 63eefbc..ba35b89 100644
--- a/pkg/compiler/lib/src/ir/static_type.dart
+++ b/pkg/compiler/lib/src/ir/static_type.dart
@@ -940,7 +940,7 @@
 
   @override
   ir.DartType visitLet(ir.Let node) {
-    visitNode(node.variable.initializer);
+    _processLocalVariable(node.variable);
     return super.visitLet(node);
   }
 
@@ -1097,7 +1097,7 @@
     typeMap = typeMap.remove(variableScopeModel.assignedVariables);
     ir.DartType returnType = super.visitFunctionExpression(node);
     Set<ir.VariableDeclaration> _oldVariables = _currentVariables;
-    _currentVariables = new Set<ir.VariableDeclaration>();
+    _currentVariables = {};
     visitSignature(node.function);
     visitNode(node.function.body);
     handleFunctionExpression(node);
@@ -1342,7 +1342,7 @@
         typeMap.remove(variableScopeModel.getScopeFor(node).assignedVariables);
     typeMap = typeMap.remove(variableScopeModel.assignedVariables);
     Set<ir.VariableDeclaration> _oldVariables = _currentVariables;
-    _currentVariables = new Set<ir.VariableDeclaration>();
+    _currentVariables = {};
     visitSignature(node.function);
     visitNode(node.function.body);
     handleFunctionDeclaration(node);
@@ -1372,7 +1372,7 @@
   @override
   Null visitProcedure(ir.Procedure node) {
     thisType = new ThisInterfaceType.from(node.enclosingClass?.thisType);
-    _currentVariables = new Set<ir.VariableDeclaration>();
+    _currentVariables = {};
     visitSignature(node.function);
     visitNode(node.function.body);
     handleProcedure(node);
@@ -1386,7 +1386,7 @@
   @override
   Null visitConstructor(ir.Constructor node) {
     thisType = new ThisInterfaceType.from(node.enclosingClass.thisType);
-    _currentVariables = new Set<ir.VariableDeclaration>();
+    _currentVariables = {};
     visitSignature(node.function);
     visitNodes(node.initializers);
     visitNode(node.function.body);
@@ -1401,7 +1401,7 @@
   @override
   Null visitField(ir.Field node) {
     thisType = new ThisInterfaceType.from(node.enclosingClass?.thisType);
-    _currentVariables = new Set<ir.VariableDeclaration>();
+    _currentVariables = {};
     visitNode(node.initializer);
     handleField(node);
     _invalidatedVariables.removeAll(_currentVariables);
@@ -1411,8 +1411,7 @@
 
   void handleVariableDeclaration(ir.VariableDeclaration node) {}
 
-  @override
-  Null visitVariableDeclaration(ir.VariableDeclaration node) {
+  void _processLocalVariable(ir.VariableDeclaration node) {
     _currentVariables.add(node);
     ir.DartType type = visitNode(node.initializer);
     if (node.initializer != null &&
@@ -1420,6 +1419,11 @@
         inferEffectivelyFinalVariableTypes) {
       node.type = type;
     }
+  }
+
+  @override
+  Null visitVariableDeclaration(ir.VariableDeclaration node) {
+    _processLocalVariable(node);
     handleVariableDeclaration(node);
   }
 
diff --git a/pkg/compiler/lib/src/js/js.dart b/pkg/compiler/lib/src/js/js.dart
index c62d6f3..c2f8403 100644
--- a/pkg/compiler/lib/src/js/js.dart
+++ b/pkg/compiler/lib/src/js/js.dart
@@ -119,7 +119,7 @@
 }
 
 abstract class ReferenceCountedAstNode implements Node {
-  markSeen(TokenCounter visitor);
+  void markSeen(TokenCounter visitor);
 }
 
 /// Represents the LiteralString resulting from unparsing [expression]. The
diff --git a/pkg/compiler/lib/src/js_backend/backend.dart b/pkg/compiler/lib/src/js_backend/backend.dart
index dc1a2b4..79a1ada 100644
--- a/pkg/compiler/lib/src/js_backend/backend.dart
+++ b/pkg/compiler/lib/src/js_backend/backend.dart
@@ -6,9 +6,10 @@
 
 import '../common.dart';
 import '../common/backend_api.dart' show ImpactTransformer;
-import '../common/codegen.dart' show CodegenWorkItem;
+import '../common/codegen.dart';
 import '../common/names.dart' show Uris;
 import '../common/tasks.dart' show CompilerTask;
+import '../common/work.dart';
 import '../common_elements.dart' show CommonElements, ElementEnvironment;
 import '../compiler.dart' show Compiler;
 import '../deferred_load.dart' show DeferredLoadTask;
@@ -20,9 +21,10 @@
 import '../io/source_information.dart' show SourceInformationStrategy;
 import '../js/js.dart' as jsAst;
 import '../js_model/elements.dart';
-import '../js_emitter/js_emitter.dart' show CodeEmitterTask, Emitter;
+import '../js_emitter/js_emitter.dart' show CodeEmitterTask;
 import '../kernel/dart2js_target.dart';
 import '../native/enqueue.dart';
+import '../serialization/serialization.dart';
 import '../ssa/ssa.dart' show SsaFunctionCompiler;
 import '../tracer.dart';
 import '../universe/class_hierarchy.dart'
@@ -52,14 +54,11 @@
 import 'runtime_types.dart';
 
 abstract class FunctionCompiler {
-  void onCodegenStart(CodegenInputs codegen);
+  void initialize(
+      GlobalTypeInferenceResults globalInferenceResults, CodegenInputs codegen);
 
-  /// Generates JavaScript code for `work.element`.
-  jsAst.Fun compile(
-      CodegenWorkItem work,
-      CodegenInputs codegen,
-      JClosedWorld closedWorld,
-      GlobalTypeInferenceResults globalInferenceResults);
+  /// Generates JavaScript code for [member].
+  CodegenResult compile(MemberEntity member);
 
   Iterable get tasks;
 }
@@ -284,13 +283,6 @@
   }
 }
 
-enum SyntheticConstantKind {
-  DUMMY_INTERCEPTOR,
-  EMPTY_VALUE,
-  TYPEVARIABLE_REFERENCE, // Reference to a type in reflection data.
-  NAME
-}
-
 class JavaScriptBackend {
   static const String JS = 'JS';
   static const String JS_BUILTIN = 'JS_BUILTIN';
@@ -312,11 +304,7 @@
 
   Namer _namer;
 
-  Namer get namer {
-    assert(_namer != null,
-        failedAt(NO_LOCATION_SPANNABLE, "Namer has not been created yet."));
-    return _namer;
-  }
+  Namer get namerForTesting => _namer;
 
   /// Set of classes whose `operator ==` methods handle `null` themselves.
   final Set<ClassEntity> specialOperatorEqClasses = new Set<ClassEntity>();
@@ -329,8 +317,6 @@
 
   RuntimeTypesChecksBuilder _rtiChecksBuilder;
 
-  RuntimeTypesEncoder _rtiEncoder;
-
   /// True if the html library has been loaded.
   bool htmlLibraryIsLoaded = false;
 
@@ -422,22 +408,6 @@
 
   RuntimeTypesChecksBuilder get rtiChecksBuilderForTesting => _rtiChecksBuilder;
 
-  RuntimeTypesEncoder get rtiEncoder {
-    assert(
-        _rtiEncoder != null,
-        failedAt(NO_LOCATION_SPANNABLE,
-            "RuntimeTypesEncoder has not been created."));
-    return _rtiEncoder;
-  }
-
-  Namer determineNamer(JClosedWorld closedWorld) {
-    return compiler.options.enableMinification
-        ? compiler.options.useFrequencyNamer
-            ? new FrequencyBasedNamer(closedWorld)
-            : new MinifyNamer(closedWorld)
-        : new Namer(closedWorld);
-  }
-
   void validateInterceptorImplementsAllObjectMethods(
       ClassEntity interceptorClass) {
     if (interceptorClass == null) return;
@@ -580,8 +550,7 @@
             closedWorld.nativeData,
             closedWorld,
             compiler.abstractValueStrategy.createSelectorStrategy()),
-        compiler.backendStrategy.createCodegenWorkItemBuilder(
-            closedWorld, globalInferenceResults, codegen),
+        compiler.backendStrategy.createCodegenWorkItemBuilder(closedWorld),
         new CodegenEnqueuerListener(
             elementEnvironment,
             commonElements,
@@ -594,34 +563,38 @@
 
   Map<MemberEntity, WorldImpact> codegenImpactsForTesting;
 
-  WorldImpact generateCode(
-      CodegenWorkItem work,
-      JClosedWorld closedWorld,
-      GlobalTypeInferenceResults globalInferenceResults,
-      CodegenInputs codegen) {
-    MemberEntity element = work.element;
-    if (element.isConstructor &&
-        element.enclosingClass == closedWorld.commonElements.jsNullClass) {
-      // Work around a problem compiling JSNull's constructor.
-      return const WorldImpact();
+  WorldImpact generateCode(WorkItem work, JClosedWorld closedWorld,
+      EntityLookup entityLookup, ComponentLookup componentLookup) {
+    MemberEntity member = work.element;
+    CodegenResult result = functionCompiler.compile(member);
+    if (compiler.options.testMode) {
+      bool useDataKinds = true;
+      List<Object> data = [];
+      DataSink sink = new ObjectSink(data, useDataKinds: useDataKinds);
+      sink.registerCodegenWriter(new CodegenWriterImpl(closedWorld));
+      result.writeToDataSink(sink);
+      DataSource source = new ObjectSource(data, useDataKinds: useDataKinds);
+      List<ModularName> modularNames = [];
+      List<ModularExpression> modularExpression = [];
+      source.registerCodegenReader(
+          new CodegenReaderImpl(closedWorld, modularNames, modularExpression));
+      source.registerEntityLookup(entityLookup);
+      source.registerComponentLookup(componentLookup);
+      result = CodegenResult.readFromDataSource(
+          source, modularNames, modularExpression);
     }
-
-    jsAst.Fun function = functionCompiler.compile(
-        work, codegen, closedWorld, globalInferenceResults);
-    if (function != null) {
-      if (function.sourceInformation == null) {
-        function = function.withSourceInformation(
-            sourceInformationStrategy.buildSourceMappedMarker());
-      }
-      generatedCode[element] = function;
+    if (result.code != null) {
+      generatedCode[member] = result.code;
     }
     if (retainDataForTesting) {
       codegenImpactsForTesting ??= <MemberEntity, WorldImpact>{};
-      codegenImpactsForTesting[element] = work.registry.worldImpact;
+      codegenImpactsForTesting[member] = result.impact;
     }
-    WorldImpact worldImpact = _codegenImpactTransformer
-        .transformCodegenImpact(work.registry.worldImpact);
-    compiler.dumpInfoTask.registerImpact(element, worldImpact);
+    WorldImpact worldImpact =
+        _codegenImpactTransformer.transformCodegenImpact(result.impact);
+    compiler.dumpInfoTask.registerImpact(member, worldImpact);
+    result.applyModularState(_namer, emitterTask.emitter);
+    //print('$member:$result');
     return worldImpact;
   }
 
@@ -642,7 +615,7 @@
   int assembleProgram(JClosedWorld closedWorld, InferredData inferredData,
       CodegenInputs codegen, CodegenWorld codegenWorld) {
     int programSize = emitterTask.assembleProgram(
-        namer, closedWorld, inferredData, codegen, codegenWorld);
+        _namer, closedWorld, inferredData, codegen, codegenWorld);
     closedWorld.noSuchMethodData.emitDiagnostic(reporter);
     return programSize;
   }
@@ -662,31 +635,28 @@
     }
   }
 
-  /// Called when the compiler starts running the codegen enqueuer. The
-  /// [WorldImpact] of enabled backend features is returned.
-  CodegenInputs onCodegenStart(JClosedWorld closedWorld) {
-    _namer = determineNamer(closedWorld);
+  /// Called when the compiler starts running the codegen.
+  ///
+  /// Returns the [CodegenInputs] objects with the needed data.
+  CodegenInputs onCodegenStart(
+      GlobalTypeInferenceResults globalTypeInferenceResults) {
+    JClosedWorld closedWorld = globalTypeInferenceResults.closedWorld;
+    RuntimeTypeTags rtiTags = const RuntimeTypeTags();
+    FixedNames fixedNames = compiler.options.enableMinification
+        ? const MinifiedFixedNames()
+        : const FixedNames();
+
     OneShotInterceptorData oneShotInterceptorData = new OneShotInterceptorData(
-        closedWorld.interceptorData, closedWorld.commonElements);
-    Tracer tracer = new Tracer(closedWorld, namer, compiler.outputProvider);
-    _rtiEncoder = _namer.rtiEncoder = new RuntimeTypesEncoderImpl(
-        namer,
+        closedWorld.interceptorData,
+        closedWorld.commonElements,
+        closedWorld.nativeData);
+    Tracer tracer = new Tracer(closedWorld, compiler.outputProvider);
+    RuntimeTypesEncoder rtiEncoder = new RuntimeTypesEncoderImpl(
+        rtiTags,
         closedWorld.nativeData,
         closedWorld.elementEnvironment,
         closedWorld.commonElements,
         closedWorld.rtiNeed);
-    _nativeCodegenEnqueuer = new NativeCodegenEnqueuer(
-        compiler.options,
-        closedWorld.elementEnvironment,
-        closedWorld.commonElements,
-        closedWorld.dartTypes,
-        emitterTask,
-        closedWorld.liveNativeClasses,
-        closedWorld.nativeData);
-    emitterTask.createEmitter(namer, closedWorld);
-    // TODO(johnniwinther): Share the impact object created in
-    // createCodegenEnqueuer.
-    BackendImpacts impacts = new BackendImpacts(closedWorld.commonElements);
     RuntimeTypesSubstitutions rtiSubstitutions;
     if (compiler.options.disableRtiOptimization) {
       rtiSubstitutions = new TrivialRuntimeTypesSubstitutions(closedWorld);
@@ -698,6 +668,38 @@
       rtiSubstitutions = runtimeTypesImpl;
     }
 
+    CodegenInputs codegen = new CodegenInputsImpl(oneShotInterceptorData,
+        rtiSubstitutions, rtiEncoder, tracer, rtiTags, fixedNames);
+
+    functionCompiler.initialize(globalTypeInferenceResults, codegen);
+    return codegen;
+  }
+
+  /// Called before the compiler starts running the codegen enqueuer.
+  void onCodegenEnqueuerStart(
+      GlobalTypeInferenceResults globalTypeInferenceResults,
+      CodegenInputs codegen) {
+    JClosedWorld closedWorld = globalTypeInferenceResults.closedWorld;
+    RuntimeTypeTags rtiTags = codegen.rtiTags;
+    FixedNames fixedNames = codegen.fixedNames;
+    _namer = compiler.options.enableMinification
+        ? compiler.options.useFrequencyNamer
+            ? new FrequencyBasedNamer(closedWorld, rtiTags, fixedNames)
+            : new MinifyNamer(closedWorld, rtiTags, fixedNames)
+        : new Namer(closedWorld, rtiTags, fixedNames);
+    _nativeCodegenEnqueuer = new NativeCodegenEnqueuer(
+        compiler.options,
+        closedWorld.elementEnvironment,
+        closedWorld.commonElements,
+        closedWorld.dartTypes,
+        emitterTask,
+        closedWorld.liveNativeClasses,
+        closedWorld.nativeData);
+    emitterTask.createEmitter(_namer, codegen, closedWorld);
+    // TODO(johnniwinther): Share the impact object created in
+    // createCodegenEnqueuer.
+    BackendImpacts impacts = new BackendImpacts(closedWorld.commonElements);
+
     _codegenImpactTransformer = new CodegenImpactTransformer(
         compiler.options,
         closedWorld.elementEnvironment,
@@ -707,16 +709,10 @@
         closedWorld.backendUsage,
         closedWorld.rtiNeed,
         nativeCodegenEnqueuer,
-        namer,
-        oneShotInterceptorData,
+        _namer,
+        codegen.oneShotInterceptorData,
         rtiChecksBuilder,
         emitterTask.nativeEmitter);
-
-    CodegenInputs codegen = new CodegenImpl(emitterTask.emitter,
-        oneShotInterceptorData, rtiSubstitutions, rtiEncoder, namer, tracer);
-
-    functionCompiler.onCodegenStart(codegen);
-    return codegen;
   }
 
   /// Called when code generation has been completed.
@@ -802,21 +798,17 @@
 
 /// Interface for resources only used during code generation.
 abstract class CodegenInputs {
-  Emitter get emitter;
   CheckedModeHelpers get checkedModeHelpers;
   OneShotInterceptorData get oneShotInterceptorData;
   RuntimeTypesSubstitutions get rtiSubstitutions;
   RuntimeTypesEncoder get rtiEncoder;
-  // TODO(johnniwinther): Should be the modular part of the namer.
-  Namer get namer;
   SuperMemberData get superMemberData;
   Tracer get tracer;
+  RuntimeTypeTags get rtiTags;
+  FixedNames get fixedNames;
 }
 
-class CodegenImpl implements CodegenInputs {
-  @override
-  final Emitter emitter;
-
+class CodegenInputsImpl implements CodegenInputs {
   @override
   final CheckedModeHelpers checkedModeHelpers = new CheckedModeHelpers();
 
@@ -830,14 +822,17 @@
   final RuntimeTypesEncoder rtiEncoder;
 
   @override
-  final Namer namer;
-
-  @override
   final SuperMemberData superMemberData = new SuperMemberData();
 
   @override
   final Tracer tracer;
 
-  CodegenImpl(this.emitter, this.oneShotInterceptorData, this.rtiSubstitutions,
-      this.rtiEncoder, this.namer, this.tracer);
+  @override
+  final RuntimeTypeTags rtiTags;
+
+  @override
+  final FixedNames fixedNames;
+
+  CodegenInputsImpl(this.oneShotInterceptorData, this.rtiSubstitutions,
+      this.rtiEncoder, this.tracer, this.rtiTags, this.fixedNames);
 }
diff --git a/pkg/compiler/lib/src/js_backend/backend_impact.dart b/pkg/compiler/lib/src/js_backend/backend_impact.dart
index 36d9600..290c803 100644
--- a/pkg/compiler/lib/src/js_backend/backend_impact.dart
+++ b/pkg/compiler/lib/src/js_backend/backend_impact.dart
@@ -66,7 +66,8 @@
     }
     for (Selector selector in dynamicUses) {
       assert(selector != null);
-      worldImpactBuilder.registerDynamicUse(new DynamicUse(selector));
+      worldImpactBuilder
+          .registerDynamicUse(new DynamicUse(selector, null, const []));
     }
     for (InterfaceType instantiatedType in instantiatedTypes) {
       worldImpactBuilder
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 751295e..c577600 100644
--- a/pkg/compiler/lib/src/js_backend/checked_mode_helpers.dart
+++ b/pkg/compiler/lib/src/js_backend/checked_mode_helpers.dart
@@ -12,7 +12,7 @@
 import '../ssa/nodes.dart' show HTypeConversion;
 import '../universe/call_structure.dart' show CallStructure;
 import '../universe/use.dart' show StaticUse;
-import 'namer.dart' show Namer;
+import 'namer.dart' show ModularNamer;
 
 class CheckedModeHelper {
   final String name;
@@ -28,7 +28,7 @@
 
   CallStructure get callStructure => CallStructure.ONE_ARG;
 
-  void generateAdditionalArguments(SsaCodeGenerator codegen, Namer namer,
+  void generateAdditionalArguments(SsaCodeGenerator codegen, ModularNamer namer,
       HTypeConversion node, List<jsAst.Expression> arguments) {
     // No additional arguments needed.
   }
@@ -41,7 +41,7 @@
   CallStructure get callStructure => CallStructure.TWO_ARGS;
 
   @override
-  void generateAdditionalArguments(SsaCodeGenerator codegen, Namer namer,
+  void generateAdditionalArguments(SsaCodeGenerator codegen, ModularNamer namer,
       HTypeConversion node, List<jsAst.Expression> arguments) {
     DartType type = node.typeExpression;
     jsAst.Name additionalArgument = namer.operatorIsType(type);
@@ -56,7 +56,7 @@
   CallStructure get callStructure => CallStructure.TWO_ARGS;
 
   @override
-  void generateAdditionalArguments(SsaCodeGenerator codegen, Namer namer,
+  void generateAdditionalArguments(SsaCodeGenerator codegen, ModularNamer namer,
       HTypeConversion node, List<jsAst.Expression> arguments) {
     assert(node.typeExpression.isTypeVariable);
     codegen.use(node.typeRepresentation);
@@ -71,7 +71,7 @@
   CallStructure get callStructure => CallStructure.TWO_ARGS;
 
   @override
-  void generateAdditionalArguments(SsaCodeGenerator codegen, Namer namer,
+  void generateAdditionalArguments(SsaCodeGenerator codegen, ModularNamer namer,
       HTypeConversion node, List<jsAst.Expression> arguments) {
     assert(node.typeExpression.isFunctionType);
     codegen.use(node.typeRepresentation);
@@ -86,7 +86,7 @@
   CallStructure get callStructure => CallStructure.TWO_ARGS;
 
   @override
-  void generateAdditionalArguments(SsaCodeGenerator codegen, Namer namer,
+  void generateAdditionalArguments(SsaCodeGenerator codegen, ModularNamer namer,
       HTypeConversion node, List<jsAst.Expression> arguments) {
     assert(node.typeExpression.isFutureOr);
     codegen.use(node.typeRepresentation);
@@ -101,7 +101,7 @@
   CallStructure get callStructure => const CallStructure.unnamed(4);
 
   @override
-  void generateAdditionalArguments(SsaCodeGenerator codegen, Namer namer,
+  void generateAdditionalArguments(SsaCodeGenerator codegen, ModularNamer namer,
       HTypeConversion node, List<jsAst.Expression> arguments) {
     // TODO(sra): Move these calls into the SSA graph so that the arguments can
     // be optimized, e,g, GVNed.
diff --git a/pkg/compiler/lib/src/js_backend/constant_emitter.dart b/pkg/compiler/lib/src/js_backend/constant_emitter.dart
index b596d65..96bc202 100644
--- a/pkg/compiler/lib/src/js_backend/constant_emitter.dart
+++ b/pkg/compiler/lib/src/js_backend/constant_emitter.dart
@@ -15,47 +15,19 @@
 import '../js_emitter/code_emitter_task.dart';
 import '../options.dart';
 import 'field_analysis.dart' show JFieldAnalysis;
-import 'js_backend.dart';
 import 'runtime_types.dart';
 
 typedef jsAst.Expression _ConstantReferenceGenerator(ConstantValue constant);
 
 typedef jsAst.Expression _ConstantListGenerator(jsAst.Expression array);
 
-/// Generates the JavaScript expressions for constants.
-///
-/// It uses a given [_constantReferenceGenerator] to reference nested constants
-/// (if there are some). It is hence up to that function to decide which
-/// constants should be inlined or not.
-class ConstantEmitter implements ConstantValueVisitor<jsAst.Expression, Null> {
-  // Matches blank lines, comment lines and trailing comments that can't be part
-  // of a string.
-  static final RegExp COMMENT_RE =
-      new RegExp(r'''^ *(//.*)?\n|  *//[^''"\n]*$''', multiLine: true);
-
+/// Visitor that creates [jsAst.Expression]s for constants that are inlined
+/// and therefore can be created during modular code generation.
+class ModularConstantEmitter
+    implements ConstantValueVisitor<jsAst.Expression, Null> {
   final CompilerOptions _options;
-  final JCommonElements _commonElements;
-  final JElementEnvironment _elementEnvironment;
-  final RuntimeTypesNeed _rtiNeed;
-  final RuntimeTypesEncoder _rtiEncoder;
-  final JFieldAnalysis _fieldAnalysis;
-  final Emitter _emitter;
-  final _ConstantReferenceGenerator _constantReferenceGenerator;
-  final _ConstantListGenerator _makeConstantList;
 
-  /// The given [_constantReferenceGenerator] function must, when invoked with a
-  /// constant, either return a reference or return its literal expression if it
-  /// can be inlined.
-  ConstantEmitter(
-      this._options,
-      this._commonElements,
-      this._elementEnvironment,
-      this._rtiNeed,
-      this._rtiEncoder,
-      this._fieldAnalysis,
-      this._emitter,
-      this._constantReferenceGenerator,
-      this._makeConstantList);
+  ModularConstantEmitter(this._options);
 
   /// Constructs a literal expression that evaluates to the constant. Uses a
   /// canonical name unless the constant can be emitted multiple times (as for
@@ -172,6 +144,83 @@
   }
 
   @override
+  jsAst.Expression visitAbstractValue(AbstractValueConstantValue constant,
+      [_]) {
+    return new jsAst.LiteralNumber('0');
+  }
+
+  @override
+  jsAst.Expression visitJsName(JsNameConstantValue constant, [_]) {
+    return constant.name;
+  }
+
+  @override
+  jsAst.Expression visitInstantiation(InstantiationConstantValue constant,
+          [_]) =>
+      null;
+
+  @override
+  jsAst.Expression visitDeferredGlobal(DeferredGlobalConstantValue constant,
+          [_]) =>
+      null;
+
+  @override
+  jsAst.Expression visitInterceptor(InterceptorConstantValue constant, [_]) =>
+      null;
+
+  @override
+  jsAst.Expression visitType(TypeConstantValue constant, [_]) => null;
+
+  @override
+  jsAst.Expression visitConstructed(ConstructedConstantValue constant, [_]) =>
+      null;
+
+  @override
+  jsAst.Expression visitMap(MapConstantValue constant, [_]) => null;
+
+  @override
+  jsAst.Expression visitSet(SetConstantValue constant, [_]) => null;
+
+  @override
+  jsAst.Expression visitList(ListConstantValue constant, [_]) => null;
+}
+
+/// Generates the JavaScript expressions for constants.
+///
+/// It uses a given [_constantReferenceGenerator] to reference nested constants
+/// (if there are some). It is hence up to that function to decide which
+/// constants should be inlined or not.
+class ConstantEmitter extends ModularConstantEmitter {
+  // Matches blank lines, comment lines and trailing comments that can't be part
+  // of a string.
+  static final RegExp COMMENT_RE =
+      new RegExp(r'''^ *(//.*)?\n|  *//[^''"\n]*$''', multiLine: true);
+
+  final JCommonElements _commonElements;
+  final JElementEnvironment _elementEnvironment;
+  final RuntimeTypesNeed _rtiNeed;
+  final RuntimeTypesEncoder _rtiEncoder;
+  final JFieldAnalysis _fieldAnalysis;
+  final Emitter _emitter;
+  final _ConstantReferenceGenerator _constantReferenceGenerator;
+  final _ConstantListGenerator _makeConstantList;
+
+  /// The given [_constantReferenceGenerator] function must, when invoked with a
+  /// constant, either return a reference or return its literal expression if it
+  /// can be inlined.
+  ConstantEmitter(
+      CompilerOptions options,
+      this._commonElements,
+      this._elementEnvironment,
+      this._rtiNeed,
+      this._rtiEncoder,
+      this._fieldAnalysis,
+      this._emitter,
+      this._constantReferenceGenerator,
+      this._makeConstantList)
+      : super(options);
+
+  @override
   jsAst.Expression visitList(ListConstantValue constant, [_]) {
     List<jsAst.Expression> elements = constant.entries
         .map(_constantReferenceGenerator)
@@ -322,21 +371,6 @@
   }
 
   @override
-  jsAst.Expression visitSynthetic(SyntheticConstantValue constant, [_]) {
-    switch (constant.valueKind) {
-      case SyntheticConstantKind.DUMMY_INTERCEPTOR:
-      case SyntheticConstantKind.EMPTY_VALUE:
-        return new jsAst.LiteralNumber('0');
-      case SyntheticConstantKind.TYPEVARIABLE_REFERENCE:
-      case SyntheticConstantKind.NAME:
-        return constant.payload;
-      default:
-        throw failedAt(NO_LOCATION_SPANNABLE,
-            "Unexpected DummyConstantKind ${constant.kind}");
-    }
-  }
-
-  @override
   jsAst.Expression visitConstructed(ConstructedConstantValue constant, [_]) {
     ClassEntity element = constant.type.element;
     if (element == _commonElements.jsConstClass) {
diff --git a/pkg/compiler/lib/src/js_backend/frequency_namer.dart b/pkg/compiler/lib/src/js_backend/frequency_namer.dart
index 7bb0830..1396e15 100644
--- a/pkg/compiler/lib/src/js_backend/frequency_namer.dart
+++ b/pkg/compiler/lib/src/js_backend/frequency_namer.dart
@@ -23,31 +23,15 @@
   bool get shouldMinify => true;
 
   @override
-  final String getterPrefix = 'g';
-  @override
-  final String setterPrefix = 's';
-  @override
-  final String callPrefix = ''; // this will create function names $<n>
-  @override
-  String get operatorIsPrefix => r'$i';
-  @override
-  String get operatorAsPrefix => r'$a';
-  @override
-  String get callCatchAllName => r'$C';
-  @override
-  String get requiredParameterField => r'$R';
-  @override
-  String get defaultValuesField => r'$D';
-  @override
-  String get operatorSignature => r'$S';
-  @override
   String get genericInstantiationPrefix => r'$I';
 
   @override
   jsAst.Name get staticsPropertyName =>
       _staticsPropertyName ??= getFreshName(instanceScope, 'static');
 
-  FrequencyBasedNamer(JClosedWorld closedWorld) : super(closedWorld) {
+  FrequencyBasedNamer(
+      JClosedWorld closedWorld, RuntimeTypeTags rtiTags, FixedNames fixedNames)
+      : super(closedWorld, rtiTags, fixedNames) {
     fieldRegistry = new _FieldNamingRegistry(this);
   }
 
diff --git a/pkg/compiler/lib/src/js_backend/interceptor_data.dart b/pkg/compiler/lib/src/js_backend/interceptor_data.dart
index 1d604c9..b63dae7 100644
--- a/pkg/compiler/lib/src/js_backend/interceptor_data.dart
+++ b/pkg/compiler/lib/src/js_backend/interceptor_data.dart
@@ -14,7 +14,7 @@
 import '../serialization/serialization.dart';
 import '../universe/selector.dart';
 import '../world.dart' show JClosedWorld;
-import 'namer.dart';
+import 'namer.dart' show ModularNamer, suffixForGetInterceptor;
 import 'native_data.dart';
 
 abstract class InterceptorData {
@@ -354,55 +354,79 @@
 class OneShotInterceptorData {
   final InterceptorData _interceptorData;
   final CommonElements _commonElements;
+  final NativeData _nativeData;
 
-  OneShotInterceptorData(this._interceptorData, this._commonElements);
+  OneShotInterceptorData(
+      this._interceptorData, this._commonElements, this._nativeData);
 
-  /// A collection of selectors that must have a one shot interceptor generated.
-  final Map<jsAst.Name, Selector> _oneShotInterceptors =
-      <jsAst.Name, Selector>{};
+  Iterable<OneShotInterceptor> get oneShotInterceptors {
+    List<OneShotInterceptor> interceptors = [];
+    for (var map in _oneShotInterceptors.values) {
+      interceptors.addAll(map.values);
+    }
+    return interceptors;
+  }
 
-  Selector getOneShotInterceptorSelector(jsAst.Name name) =>
-      _oneShotInterceptors[name];
+  Map<Selector, Map<String, OneShotInterceptor>> _oneShotInterceptors = {};
 
-  Iterable<jsAst.Name> get oneShotInterceptorNames =>
-      _oneShotInterceptors.keys.toList()..sort();
-
-  /// A map of specialized versions of the [getInterceptorMethod].
+  /// A set of specialized versions of the [getInterceptorMethod].
   ///
   /// Since [getInterceptorMethod] is a hot method at runtime, we're always
   /// specializing it based on the incoming type. The keys in the map are the
   /// names of these specialized versions. Note that the generic version that
   /// contains all possible type checks is also stored in this map.
-  final Map<jsAst.Name, Set<ClassEntity>> _specializedGetInterceptors =
-      <jsAst.Name, Set<ClassEntity>>{};
+  Iterable<SpecializedGetInterceptor> get specializedGetInterceptors =>
+      _specializedGetInterceptors.values;
 
-  Iterable<jsAst.Name> get specializedGetInterceptorNames =>
-      _specializedGetInterceptors.keys.toList()..sort();
-
-  Set<ClassEntity> getSpecializedGetInterceptorsFor(jsAst.Name name) =>
-      _specializedGetInterceptors[name];
+  Map<String, SpecializedGetInterceptor> _specializedGetInterceptors = {};
 
   jsAst.Name registerOneShotInterceptor(
-      Selector selector, Namer namer, JClosedWorld closedWorld) {
+      Selector selector, ModularNamer namer, JClosedWorld closedWorld) {
+    selector = selector.toNormalized();
     Set<ClassEntity> classes =
         _interceptorData.getInterceptedClassesOn(selector.name, closedWorld);
-    jsAst.Name name = namer.nameForGetOneShotInterceptor(selector, classes);
-    if (!_oneShotInterceptors.containsKey(name)) {
-      registerSpecializedGetInterceptor(classes, namer);
-      _oneShotInterceptors[name] = selector;
-    }
-    return name;
+    String key = suffixForGetInterceptor(_commonElements, _nativeData, classes);
+    Map<String, OneShotInterceptor> interceptors =
+        _oneShotInterceptors[selector] ??= {};
+    OneShotInterceptor interceptor = interceptors.putIfAbsent(
+        key, () => new OneShotInterceptor(key, selector));
+    interceptor.classes.addAll(classes);
+    registerSpecializedGetInterceptor(classes, namer);
+    return namer.nameForGetOneShotInterceptor(selector, classes);
   }
 
   void registerSpecializedGetInterceptor(
-      Set<ClassEntity> classes, Namer namer) {
-    jsAst.Name name = namer.nameForGetInterceptor(classes);
+      Set<ClassEntity> classes, ModularNamer namer) {
     if (classes.contains(_commonElements.jsInterceptorClass)) {
       // We can't use a specialized [getInterceptorMethod], so we make
       // sure we emit the one with all checks.
-      _specializedGetInterceptors[name] = _interceptorData.interceptedClasses;
-    } else {
-      _specializedGetInterceptors[name] = classes;
+      classes = _interceptorData.interceptedClasses;
     }
+    String key = suffixForGetInterceptor(_commonElements, _nativeData, classes);
+    SpecializedGetInterceptor interceptor =
+        _specializedGetInterceptors[key] ??= new SpecializedGetInterceptor(key);
+    interceptor.classes.addAll(classes);
   }
 }
+
+class OneShotInterceptor {
+  final Selector selector;
+  final String key;
+  final Set<ClassEntity> classes = {};
+
+  OneShotInterceptor(this.key, this.selector);
+
+  @override
+  String toString() =>
+      'OneShotInterceptor(selector=$selector,key=$key,classes=$classes)';
+}
+
+class SpecializedGetInterceptor {
+  final String key;
+  final Set<ClassEntity> classes = {};
+
+  SpecializedGetInterceptor(this.key);
+
+  @override
+  String toString() => 'SpecializedGetInterceptor(key=$key,classes=$classes)';
+}
diff --git a/pkg/compiler/lib/src/js_backend/minify_namer.dart b/pkg/compiler/lib/src/js_backend/minify_namer.dart
index 7ae3818..c59f8f4 100644
--- a/pkg/compiler/lib/src/js_backend/minify_namer.dart
+++ b/pkg/compiler/lib/src/js_backend/minify_namer.dart
@@ -10,7 +10,9 @@
         _MinifiedFieldNamer,
         _MinifyConstructorBodyNamer,
         _MinifiedOneShotInterceptorNamer {
-  MinifyNamer(JClosedWorld closedWorld) : super(closedWorld) {
+  MinifyNamer(
+      JClosedWorld closedWorld, RuntimeTypeTags rtiTags, FixedNames fixedNames)
+      : super(closedWorld, rtiTags, fixedNames) {
     reserveBackendNames();
     fieldRegistry = new _FieldNamingRegistry(this);
   }
@@ -24,25 +26,6 @@
   String get isolatePropertiesName => 'p';
   @override
   bool get shouldMinify => true;
-
-  @override
-  final String getterPrefix = 'g';
-  @override
-  final String setterPrefix = 's';
-  @override
-  final String callPrefix = ''; // this will create function names $<n>
-  @override
-  String get operatorIsPrefix => r'$i';
-  @override
-  String get operatorAsPrefix => r'$a';
-  @override
-  String get callCatchAllName => r'$C';
-  @override
-  String get requiredParameterField => r'$R';
-  @override
-  String get defaultValuesField => r'$D';
-  @override
-  String get operatorSignature => r'$S';
   @override
   String get genericInstantiationPrefix => r'$I';
 
@@ -412,7 +395,8 @@
     String callSuffix = selector.isCall
         ? Namer.callSuffixForStructure(selector.callStructure).join()
         : "";
-    String suffix = suffixForGetInterceptor(classes);
+    String suffix =
+        suffixForGetInterceptor(_commonElements, _nativeData, classes);
     String fullName = "\$intercepted$prefix\$$root$callSuffix\$$suffix";
     return _disambiguateInternalGlobal(fullName);
   }
diff --git a/pkg/compiler/lib/src/js_backend/namer.dart b/pkg/compiler/lib/src/js_backend/namer.dart
index c69a928..ee53198 100644
--- a/pkg/compiler/lib/src/js_backend/namer.dart
+++ b/pkg/compiler/lib/src/js_backend/namer.dart
@@ -13,6 +13,7 @@
 
 import '../closure.dart';
 import '../common.dart';
+import '../common/codegen.dart';
 import '../common/names.dart' show Identifiers, Names, Selectors;
 import '../common_elements.dart' show JElementEnvironment;
 import '../constants/constant_system.dart' as constant_system;
@@ -26,15 +27,14 @@
 import '../elements/types.dart';
 import '../js/js.dart' as jsAst;
 import '../js_backend/field_analysis.dart';
+import '../js_backend/runtime_types.dart' show RuntimeTypeTags;
 import '../js_model/closure.dart';
 import '../js_model/elements.dart' show JGeneratorBody;
 import '../universe/call_structure.dart' show CallStructure;
 import '../universe/selector.dart' show Selector, SelectorKind;
 import '../util/util.dart';
 import '../world.dart' show JClosedWorld;
-import 'backend.dart';
 import 'native_data.dart';
-import 'runtime_types.dart';
 
 part 'field_naming_mixin.dart';
 part 'frequency_namer.dart';
@@ -136,7 +136,7 @@
 ///
 /// For local variables, the [Namer] only provides *proposed names*. These names
 /// must be disambiguated elsewhere.
-class Namer {
+class Namer extends ModularNamer {
   static const List<String> javaScriptKeywords = const <String>[
     // ES5 7.6.1.1 Keywords.
     'break',
@@ -421,45 +421,21 @@
     return _jsReserved;
   }
 
-  Set<String> _jsVariableReserved = null;
-
-  /// Names that cannot be used by local variables and parameters.
-  Set<String> get jsVariableReserved {
-    if (_jsVariableReserved == null) {
-      _jsVariableReserved = new Set<String>();
-      _jsVariableReserved.addAll(javaScriptKeywords);
-      _jsVariableReserved.addAll(reservedPropertySymbols);
-      _jsVariableReserved.addAll(reservedGlobalSymbols);
-      _jsVariableReserved.addAll(reservedGlobalObjectNames);
-      // 26 letters in the alphabet, 25 not counting I.
-      assert(reservedGlobalObjectNames.length == 25);
-      _jsVariableReserved.addAll(reservedGlobalHelperFunctions);
-    }
-    return _jsVariableReserved;
-  }
-
-  final String asyncPrefix = r"$async$";
-  final String staticStateHolder = r'$';
-  final String getterPrefix = r'get$';
   final String lazyGetterPrefix = r'$get$';
-  final String setterPrefix = r'set$';
   final String superPrefix = r'super$';
   final String metadataField = '@';
-  final String callPrefix = 'call';
-  String get callCatchAllName => r'call*';
-  final String callNameField = r'$callName';
   final String stubNameField = r'$stubName';
-  final String reflectableField = r'$reflectable';
   final String reflectionInfoField = r'$reflectionInfo';
   final String reflectionNameField = r'$reflectionName';
   final String metadataIndexField = r'$metadataIndex';
-  String get requiredParameterField => r'$requiredArgCount';
-  String get defaultValuesField => r'$defaultValues';
   final String methodsWithOptionalArgumentsField =
       r'$methodsWithOptionalArguments';
-  final String deferredAction = r'$deferredAction';
 
-  final String classDescriptorProperty = r'^';
+  @override
+  final RuntimeTypeTags rtiTags;
+
+  @override
+  final FixedNames fixedNames;
 
   /// The non-minifying namer's [callPrefix] with a dollar after it.
   static const String _callPrefixDollar = r'call$';
@@ -469,7 +445,6 @@
   static final jsAst.Name literalPlus = new StringBackedName('+');
   static final jsAst.Name _literalDynamic = new StringBackedName("dynamic");
 
-  jsAst.Name _literalAsyncPrefix;
   jsAst.Name _literalGetterPrefix;
   jsAst.Name _literalSetterPrefix;
 
@@ -478,11 +453,11 @@
   jsAst.Name get staticsPropertyName =>
       _staticsPropertyName ??= new StringBackedName('static');
 
-  final String rtiName = r'$ti';
-
   jsAst.Name _rtiFieldJsName;
+
+  @override
   jsAst.Name get rtiFieldJsName =>
-      _rtiFieldJsName ??= new StringBackedName(rtiName);
+      _rtiFieldJsName ??= new StringBackedName(fixedNames.rtiName);
 
   // Name of property in a class description for the native dispatch metadata.
   final String nativeSpecProperty = '%';
@@ -492,21 +467,6 @@
 
   final JClosedWorld _closedWorld;
 
-  RuntimeTypesEncoder _rtiEncoder;
-  RuntimeTypesEncoder get rtiEncoder {
-    assert(_rtiEncoder != null,
-        failedAt(NO_LOCATION_SPANNABLE, "Namer.rtiEncoder has not been set."));
-    return _rtiEncoder;
-  }
-
-  void set rtiEncoder(RuntimeTypesEncoder value) {
-    assert(
-        _rtiEncoder == null,
-        failedAt(
-            NO_LOCATION_SPANNABLE, "Namer.rtiEncoder has already been set."));
-    _rtiEncoder = value;
-  }
-
   /// Used disambiguated names in the global namespace, issued by
   /// [_disambiguateGlobal], and [_disambiguateInternalGlobal].
   ///
@@ -596,15 +556,15 @@
   /// key into maps.
   final Map<LibraryEntity, String> _libraryKeys = HashMap();
 
-  Namer(this._closedWorld) {
-    _literalAsyncPrefix = new StringBackedName(asyncPrefix);
-    _literalGetterPrefix = new StringBackedName(getterPrefix);
-    _literalSetterPrefix = new StringBackedName(setterPrefix);
+  Namer(this._closedWorld, this.rtiTags, this.fixedNames) {
+    _literalGetterPrefix = new StringBackedName(fixedNames.getterPrefix);
+    _literalSetterPrefix = new StringBackedName(fixedNames.setterPrefix);
   }
 
   JElementEnvironment get _elementEnvironment =>
       _closedWorld.elementEnvironment;
 
+  @override
   CommonElements get _commonElements => _closedWorld.commonElements;
 
   NativeData get _nativeData => _closedWorld.nativeData;
@@ -626,83 +586,6 @@
         entity.rootOfScope, () => new NamingScope());
   }
 
-  /// Returns the string that is to be used as the result of a call to
-  /// [JS_GET_NAME] at [node] with argument [name].
-  jsAst.Name getNameForJsGetName(Spannable spannable, JsGetName name) {
-    switch (name) {
-      case JsGetName.GETTER_PREFIX:
-        return asName(getterPrefix);
-      case JsGetName.SETTER_PREFIX:
-        return asName(setterPrefix);
-      case JsGetName.CALL_PREFIX:
-        return asName(callPrefix);
-      case JsGetName.CALL_PREFIX0:
-        return asName('${callPrefix}\$0');
-      case JsGetName.CALL_PREFIX1:
-        return asName('${callPrefix}\$1');
-      case JsGetName.CALL_PREFIX2:
-        return asName('${callPrefix}\$2');
-      case JsGetName.CALL_PREFIX3:
-        return asName('${callPrefix}\$3');
-      case JsGetName.CALL_PREFIX4:
-        return asName('${callPrefix}\$4');
-      case JsGetName.CALL_PREFIX5:
-        return asName('${callPrefix}\$5');
-      case JsGetName.CALL_CATCH_ALL:
-        return asName(callCatchAllName);
-      case JsGetName.REFLECTABLE:
-        return asName(reflectableField);
-      case JsGetName.CLASS_DESCRIPTOR_PROPERTY:
-        return asName(classDescriptorProperty);
-      case JsGetName.REQUIRED_PARAMETER_PROPERTY:
-        return asName(requiredParameterField);
-      case JsGetName.DEFAULT_VALUES_PROPERTY:
-        return asName(defaultValuesField);
-      case JsGetName.CALL_NAME_PROPERTY:
-        return asName(callNameField);
-      case JsGetName.DEFERRED_ACTION_PROPERTY:
-        return asName(deferredAction);
-      case JsGetName.OPERATOR_AS_PREFIX:
-        return asName(operatorAsPrefix);
-      case JsGetName.SIGNATURE_NAME:
-        return asName(operatorSignature);
-      case JsGetName.RTI_NAME:
-        return asName(rtiName);
-      case JsGetName.TYPEDEF_TAG:
-        return asName(typedefTag);
-      case JsGetName.FUNCTION_TYPE_TAG:
-        return asName(functionTypeTag);
-      case JsGetName.FUNCTION_TYPE_GENERIC_BOUNDS_TAG:
-        return asName(functionTypeGenericBoundsTag);
-      case JsGetName.FUNCTION_TYPE_VOID_RETURN_TAG:
-        return asName(functionTypeVoidReturnTag);
-      case JsGetName.FUNCTION_TYPE_RETURN_TYPE_TAG:
-        return asName(functionTypeReturnTypeTag);
-      case JsGetName.FUNCTION_TYPE_REQUIRED_PARAMETERS_TAG:
-        return asName(functionTypeRequiredParametersTag);
-      case JsGetName.FUNCTION_TYPE_OPTIONAL_PARAMETERS_TAG:
-        return asName(functionTypeOptionalParametersTag);
-      case JsGetName.FUNCTION_TYPE_NAMED_PARAMETERS_TAG:
-        return asName(functionTypeNamedParametersTag);
-      case JsGetName.FUTURE_OR_TAG:
-        return asName(futureOrTag);
-      case JsGetName.FUTURE_OR_TYPE_ARGUMENT_TAG:
-        return asName(futureOrTypeTag);
-      case JsGetName.IS_INDEXABLE_FIELD_NAME:
-        return operatorIs(_commonElements.jsIndexingBehaviorInterface);
-      case JsGetName.NULL_CLASS_TYPE_NAME:
-        return runtimeTypeName(_commonElements.nullClass);
-      case JsGetName.OBJECT_CLASS_TYPE_NAME:
-        return runtimeTypeName(_commonElements.objectClass);
-      case JsGetName.FUNCTION_CLASS_TYPE_NAME:
-        return runtimeTypeName(_commonElements.functionClass);
-      case JsGetName.FUTURE_CLASS_TYPE_NAME:
-        return runtimeTypeName(_commonElements.futureClass);
-      default:
-        throw failedAt(spannable, 'Error: Namer has no name for "$name".');
-    }
-  }
-
   /// Return a reference to the given [name].
   ///
   /// This is used to ensure that every use site of a name has a unique node so
@@ -732,33 +615,14 @@
   String constantLongName(ConstantValue constant) {
     String longName = _constantLongNames[constant];
     if (longName == null) {
-      _constantHasher ??= new ConstantCanonicalHasher(rtiEncoder, _closedWorld);
-      longName =
-          new ConstantNamingVisitor(rtiEncoder, _closedWorld, _constantHasher)
-              .getName(constant);
+      _constantHasher ??= new ConstantCanonicalHasher(this, _closedWorld);
+      longName = new ConstantNamingVisitor(this, _closedWorld, _constantHasher)
+          .getName(constant);
       _constantLongNames[constant] = longName;
     }
     return longName;
   }
 
-  String breakLabelName(LabelDefinition label) {
-    return '\$${label.labelName}\$${label.target.nestingLevel}';
-  }
-
-  String implicitBreakLabelName(JumpTarget target) {
-    return '\$${target.nestingLevel}';
-  }
-
-  // We sometimes handle continue targets differently from break targets,
-  // so we have special continue-only labels.
-  String continueLabelName(LabelDefinition label) {
-    return 'c\$${label.labelName}\$${label.target.nestingLevel}';
-  }
-
-  String implicitContinueLabelName(JumpTarget target) {
-    return 'c\$${target.nestingLevel}';
-  }
-
   /// If the [originalName] is not private returns [originalName]. Otherwise
   /// mangles the [originalName] so that each library has its own distinguished
   /// version of the name.
@@ -823,7 +687,7 @@
     });
   }
 
-  /// Annotated name for [method] encoding arity and named parameters.
+  @override
   jsAst.Name instanceMethodName(FunctionEntity method) {
     // TODO(johnniwinther): Avoid the use of [ConstructorBodyEntity] and
     // [JGeneratorBody]. The codegen model should be explicit about its
@@ -846,7 +710,8 @@
   /// concatenation at runtime, by applyFunction in js_helper.dart.
   jsAst.Name deriveCallMethodName(List<String> suffix) {
     // TODO(asgerf): Avoid clashes when named parameters contain $ symbols.
-    return new StringBackedName('$callPrefix\$${suffix.join(r'$')}');
+    return new StringBackedName(
+        '${fixedNames.callPrefix}\$${suffix.join(r'$')}');
   }
 
   /// The suffix list for the pattern:
@@ -882,7 +747,7 @@
     return suffixes;
   }
 
-  /// Annotated name for the member being invoked by [selector].
+  @override
   jsAst.Name invocationName(Selector selector) {
     switch (selector.kind) {
       case SelectorKind.GETTER:
@@ -950,31 +815,19 @@
         : _disambiguateGlobalMember(element);
   }
 
-  /// Returns a JavaScript property name used to store the member [element] on
-  /// one of the global objects.
-  ///
-  /// Should be used together with [globalObjectForMember], which denotes the
-  /// object on which the returned property name should be used.
+  @override
   jsAst.Name globalPropertyNameForMember(MemberEntity element) =>
       _disambiguateGlobalMember(element);
 
-  /// Returns a JavaScript property name used to store the class [element] on
-  /// one of the global objects.
-  ///
-  /// Should be used together with [globalObjectForClass], which denotes the
-  /// object on which the returned property name should be used.
+  @override
   jsAst.Name globalPropertyNameForClass(ClassEntity element) =>
       _disambiguateGlobalType(element);
 
-  /// Returns a JavaScript property name used to store the type (typedef)
-  /// [element] on one of the global objects.
-  ///
-  /// Should be used together with [globalObjectForType], which denotes the
-  /// object on which the returned property name should be used.
+  @override
   jsAst.Name globalPropertyNameForType(Entity element) =>
       _disambiguateGlobalType(element);
 
-  /// Returns the JavaScript property name used to store an instance field.
+  @override
   jsAst.Name instanceFieldPropertyName(FieldEntity element) {
     ClassEntity enclosingClass = element.enclosingClass;
 
@@ -1340,8 +1193,8 @@
     // or with one of the `call` stubs, such as `call$1`.
     assert(this is! MinifyNamer);
     if (name.startsWith(r'$') ||
-        name.startsWith(getterPrefix) ||
-        name.startsWith(setterPrefix) ||
+        name.startsWith(fixedNames.getterPrefix) ||
+        name.startsWith(fixedNames.setterPrefix) ||
         name.startsWith(_callPrefixDollar)) {
       name = '\$$name';
     }
@@ -1439,34 +1292,6 @@
     return disambiguated;
   }
 
-  String suffixForGetInterceptor(Iterable<ClassEntity> classes) {
-    String abbreviate(ClassEntity cls) {
-      if (cls == _commonElements.objectClass) return "o";
-      if (cls == _commonElements.jsStringClass) return "s";
-      if (cls == _commonElements.jsArrayClass) return "a";
-      if (cls == _commonElements.jsDoubleClass) return "d";
-      if (cls == _commonElements.jsIntClass) return "i";
-      if (cls == _commonElements.jsNumberClass) return "n";
-      if (cls == _commonElements.jsNullClass) return "u";
-      if (cls == _commonElements.jsBoolClass) return "b";
-      if (cls == _commonElements.jsInterceptorClass) return "I";
-      return cls.name;
-    }
-
-    List<String> names = classes
-        .where((cls) => !_nativeData.isNativeOrExtendsNative(cls))
-        .map(abbreviate)
-        .toList();
-    // There is one dispatch mechanism for all native classes.
-    if (classes.any((cls) => _nativeData.isNativeOrExtendsNative(cls))) {
-      names.add("x");
-    }
-    // Sort the names of the classes after abbreviating them to ensure
-    // the suffix is stable and predictable for the suggested names.
-    names.sort();
-    return names.join();
-  }
-
   String _getSuffixForInterceptedClasses(Iterable<ClassEntity> classes) {
     if (classes.isEmpty) {
       // TODO(johnniwinther,sra): If [classes] is empty it should either have
@@ -1484,15 +1309,11 @@
       // set of classes for most general variant, e.g. "$lt$n" could be "$lt".
       return '';
     } else {
-      return suffixForGetInterceptor(classes);
+      return suffixForGetInterceptor(_commonElements, _nativeData, classes);
     }
   }
 
-  /// Property name used for a specialization of `getInterceptor`.
-  ///
-  /// js_runtime contains a top-level `getInterceptor` method. The
-  /// specializations have the same name, but with a suffix to avoid name
-  /// collisions.
+  @override
   jsAst.Name nameForGetInterceptor(Iterable<ClassEntity> classes) {
     // If the base Interceptor class is in the set of intercepted classes, we
     // need to go through the generic getInterceptor method (any subclass of the
@@ -1501,8 +1322,7 @@
     return _disambiguateInternalGlobal('getInterceptor\$$suffix');
   }
 
-  /// Property name used for the one-shot interceptor method for the given
-  /// [selector] and return-type specialization.
+  @override
   jsAst.Name nameForGetOneShotInterceptor(
       Selector selector, Iterable<ClassEntity> classes) {
     // The one-shot name is a global name derived from the invocation name.  To
@@ -1515,15 +1335,7 @@
         [root, _literalDollar, new StringBackedName(suffix)]);
   }
 
-  /// Returns the runtime name for [element].
-  ///
-  /// This name is used as the basis for deriving `is` and `as` property names
-  /// for the given type.
-  ///
-  /// The result is not always safe as a property name unless prefixing
-  /// [operatorIsPrefix] or [operatorAsPrefix]. If this is a function type,
-  /// then by convention, an underscore must also separate [operatorIsPrefix]
-  /// from the type name.
+  @override
   jsAst.Name runtimeTypeName(Entity element) {
     if (element == null) return _literalDynamic;
     // The returned name affects both the global and instance member namespaces:
@@ -1540,32 +1352,10 @@
     return _disambiguateGlobalType(element);
   }
 
-  /// Returns the disambiguated name of [class_].
-  ///
-  /// This is both the *runtime type* of the class (see [runtimeTypeName])
-  /// and a global property name in which to store its JS constructor.
+  @override
   jsAst.Name className(ClassEntity class_) => _disambiguateGlobalType(class_);
 
-  /// Property name on which [member] can be accessed directly,
-  /// without clashing with another JS property name.
-  ///
-  /// This is used for implementing super-calls, where ordinary dispatch
-  /// semantics must be circumvented. For example:
-  ///
-  ///     class A { foo() }
-  ///     class B extends A {
-  ///         foo() { super.foo() }
-  ///     }
-  ///
-  /// Example translation to JS:
-  ///
-  ///     A.prototype.super$A$foo = function() {...}
-  ///     A.prototype.foo$0 = A.prototype.super$A$foo
-  ///
-  ///     B.prototype.foo$0 = function() {
-  ///         this.super$A$foo(); // super.foo()
-  ///     }
-  ///
+  @override
   jsAst.Name aliasedSuperMemberPropertyName(MemberEntity member) {
     assert(!member.isField); // Fields do not need super aliases.
     return _disambiguateInternalMember(member, () {
@@ -1575,12 +1365,7 @@
     });
   }
 
-  /// Property name in which to store the given static or instance [method].
-  /// For instance methods, this includes the suffix encoding arity and named
-  /// parameters.
-  ///
-  /// The name is not necessarily unique to [method], since a static method
-  /// may share its name with an instance method.
+  @override
   jsAst.Name methodPropertyName(FunctionEntity method) {
     return method.isInstanceMember
         ? instanceMethodName(method)
@@ -1604,10 +1389,23 @@
     return globalObjectForLibrary(element.library);
   }
 
+  @override
+  jsAst.VariableUse readGlobalObjectForMember(MemberEntity element) {
+    if (_isPropertyOfStaticStateHolder(element)) {
+      return new jsAst.VariableUse(staticStateHolder);
+    }
+    return readGlobalObjectForLibrary(element.library);
+  }
+
   String globalObjectForClass(ClassEntity element) {
     return globalObjectForLibrary(element.library);
   }
 
+  @override
+  jsAst.VariableUse readGlobalObjectForClass(ClassEntity element) {
+    return readGlobalObjectForLibrary(element.library);
+  }
+
   String globalObjectForType(Entity element) {
     if (element is TypedefEntity) {
       return globalObjectForLibrary(element.library);
@@ -1615,6 +1413,14 @@
     return globalObjectForClass(element);
   }
 
+  @override
+  jsAst.VariableUse readGlobalObjectForType(Entity element) {
+    if (element is TypedefEntity) {
+      return readGlobalObjectForLibrary(element.library);
+    }
+    return readGlobalObjectForClass(element);
+  }
+
   /// Returns the [reservedGlobalObjectNames] for [library].
   String globalObjectForLibrary(LibraryEntity library) {
     if (library == _commonElements.interceptorsLibrary) return 'J';
@@ -1627,6 +1433,12 @@
     return userGlobalObjects[library.name.hashCode % userGlobalObjects.length];
   }
 
+  @override
+  jsAst.VariableUse readGlobalObjectForLibrary(LibraryEntity library) {
+    return new jsAst.VariableUse(globalObjectForLibrary(library));
+  }
+
+  @override
   jsAst.Name lazyInitializerName(FieldEntity element) {
     assert(element.isTopLevel || element.isStatic);
     jsAst.Name name = _disambiguateGlobal<MemberEntity>(
@@ -1634,6 +1446,7 @@
     return name;
   }
 
+  @override
   jsAst.Name staticClosureName(FunctionEntity element) {
     assert(element.isTopLevel || element.isStatic);
     String enclosing =
@@ -1654,34 +1467,8 @@
 
   String globalObjectForConstant(ConstantValue constant) => 'C';
 
-  String get operatorIsPrefix => r'$is';
-
-  String get operatorAsPrefix => r'$as';
-
-  String get operatorSignature => r'$signature';
-
   String get genericInstantiationPrefix => r'$instantiate';
 
-  String get typedefTag => r'typedef';
-
-  String get functionTypeTag => r'func';
-
-  String get functionTypeVoidReturnTag => r'v';
-
-  String get functionTypeReturnTypeTag => r'ret';
-
-  String get functionTypeRequiredParametersTag => r'args';
-
-  String get functionTypeOptionalParametersTag => r'opt';
-
-  String get functionTypeNamedParametersTag => r'named';
-
-  String get functionTypeGenericBoundsTag => r'bounds';
-
-  String get futureOrTag => r'futureOr';
-
-  String get futureOrTypeTag => r'type';
-
   // The name of the variable used to offset function signatures in deferred
   // parts with the fast-startup emitter.
   String get typesOffsetName => r'typesOffset';
@@ -1692,17 +1479,18 @@
 
   jsAst.Name getFunctionTypeName(FunctionType functionType) {
     return functionTypeNameMap.putIfAbsent(functionType, () {
-      _functionTypeNamer ??= new FunctionTypeNamer(rtiEncoder);
+      _functionTypeNamer ??= new FunctionTypeNamer();
       String proposedName = _functionTypeNamer.computeName(functionType);
       return getFreshName(instanceScope, proposedName);
     });
   }
 
+  @override
   jsAst.Name operatorIsType(DartType type) {
     if (type.isFunctionType) {
       // TODO(erikcorry): Reduce from $isx to ix when we are minifying.
       return new CompoundName([
-        new StringBackedName(operatorIsPrefix),
+        new StringBackedName(fixedNames.operatorIsPrefix),
         _literalUnderscore,
         getFunctionTypeName(type)
       ]);
@@ -1711,10 +1499,13 @@
     return operatorIs(interfaceType.element);
   }
 
+  @override
   jsAst.Name operatorIs(ClassEntity element) {
     // TODO(erikcorry): Reduce from $isx to ix when we are minifying.
-    return new CompoundName(
-        [new StringBackedName(operatorIsPrefix), runtimeTypeName(element)]);
+    return new CompoundName([
+      new StringBackedName(fixedNames.operatorIsPrefix),
+      runtimeTypeName(element)
+    ]);
   }
 
   /// Returns a name that does not clash with reserved JS keywords.
@@ -1726,56 +1517,30 @@
     return name;
   }
 
+  @override
   jsAst.Name substitutionName(ClassEntity element) {
-    return new CompoundName(
-        [new StringBackedName(operatorAsPrefix), runtimeTypeName(element)]);
+    return new CompoundName([
+      new StringBackedName(fixedNames.operatorAsPrefix),
+      runtimeTypeName(element)
+    ]);
   }
 
-  /// Translates a [String] into the corresponding [Name] data structure as
-  /// used by the namer.
-  ///
-  /// If [name] is a setter or getter name, the corresponding [GetterName] or
-  /// [SetterName] data structure is used.
+  @override
   jsAst.Name asName(String name) {
-    if (name.startsWith(getterPrefix) && name.length > getterPrefix.length) {
+    if (name.startsWith(fixedNames.getterPrefix) &&
+        name.length > fixedNames.getterPrefix.length) {
       return new GetterName(_literalGetterPrefix,
-          new StringBackedName(name.substring(getterPrefix.length)));
+          new StringBackedName(name.substring(fixedNames.getterPrefix.length)));
     }
-    if (name.startsWith(setterPrefix) && name.length > setterPrefix.length) {
+    if (name.startsWith(fixedNames.setterPrefix) &&
+        name.length > fixedNames.setterPrefix.length) {
       return new GetterName(_literalSetterPrefix,
-          new StringBackedName(name.substring(setterPrefix.length)));
+          new StringBackedName(name.substring(fixedNames.setterPrefix.length)));
     }
 
     return new StringBackedName(name);
   }
 
-  /// Returns a variable name that cannot clash with a keyword, a global
-  /// variable, or any name starting with a single '$'.
-  ///
-  /// Furthermore, this function is injective, that is, it never returns the
-  /// same name for two different inputs.
-  String safeVariableName(String name) {
-    name = name.replaceAll('#', '_');
-    if (jsVariableReserved.contains(name) || name.startsWith(r'$')) {
-      return '\$$name';
-    }
-    return name;
-  }
-
-  /// Returns a safe variable name for use in async rewriting.
-  ///
-  /// Has the same property as [safeVariableName] but does not clash with
-  /// names returned from there.
-  /// Additionally, when used as a prefix to a variable name, the result
-  /// will be safe to use, as well.
-  String safeVariablePrefixForAsyncRewrite(String name) {
-    return "$asyncPrefix$name";
-  }
-
-  jsAst.Name deriveAsyncBodyName(jsAst.Name original) {
-    return new _AsyncName(_literalAsyncPrefix, original);
-  }
-
   String operatorNameToIdentifier(String name) {
     if (name == null) return null;
     if (name == '==') {
@@ -1822,6 +1587,64 @@
       return name;
     }
   }
+
+  String getTypeRepresentationForTypeConstant(DartType type) {
+    if (type.isDynamic) return "dynamic";
+    if (type is TypedefType) {
+      return uniqueNameForTypeConstantElement(
+          type.element.library, type.element);
+    }
+    if (type is FunctionType) {
+      // TODO(johnniwinther): Add naming scheme for function type literals.
+      // These currently only occur from kernel.
+      return '()->';
+    }
+    InterfaceType interface = type;
+    String name = uniqueNameForTypeConstantElement(
+        interface.element.library, interface.element);
+
+    // Type constants can currently only be raw types, so there is no point
+    // adding ground-term type parameters, as they would just be 'dynamic'.
+    // TODO(sra): Since the result string is used only in constructing constant
+    // names, it would result in more readable names if the final string was a
+    // legal JavaScript identifier.
+    if (interface.typeArguments.isEmpty) return name;
+    String arguments =
+        new List.filled(interface.typeArguments.length, 'dynamic').join(', ');
+    return '$name<$arguments>';
+  }
+}
+
+/// Returns a unique suffix for an intercepted accesses to [classes]. This is
+/// used as the suffix for emitted interceptor methods and as the unique key
+/// used to distinguish equivalences of sets of intercepted classes.
+String suffixForGetInterceptor(CommonElements commonElements,
+    NativeData nativeData, Iterable<ClassEntity> classes) {
+  String abbreviate(ClassEntity cls) {
+    if (cls == commonElements.objectClass) return "o";
+    if (cls == commonElements.jsStringClass) return "s";
+    if (cls == commonElements.jsArrayClass) return "a";
+    if (cls == commonElements.jsDoubleClass) return "d";
+    if (cls == commonElements.jsIntClass) return "i";
+    if (cls == commonElements.jsNumberClass) return "n";
+    if (cls == commonElements.jsNullClass) return "u";
+    if (cls == commonElements.jsBoolClass) return "b";
+    if (cls == commonElements.jsInterceptorClass) return "I";
+    return cls.name;
+  }
+
+  List<String> names = classes
+      .where((cls) => !nativeData.isNativeOrExtendsNative(cls))
+      .map(abbreviate)
+      .toList();
+  // There is one dispatch mechanism for all native classes.
+  if (classes.any((cls) => nativeData.isNativeOrExtendsNative(cls))) {
+    names.add("x");
+  }
+  // Sort the names of the classes after abbreviating them to ensure
+  // the suffix is stable and predictable for the suggested names.
+  names.sort();
+  return names.join();
 }
 
 /// Generator of names for [ConstantValue] values.
@@ -1843,7 +1666,7 @@
   static const MAX_EXTRA_LENGTH = 30;
   static const DEFAULT_TAG_LENGTH = 3;
 
-  final RuntimeTypesEncoder _rtiEncoder;
+  final Namer _namer;
   final JClosedWorld _closedWorld;
   final ConstantCanonicalHasher _hasher;
 
@@ -1852,7 +1675,7 @@
   List<String> fragments = <String>[];
   int length = 0;
 
-  ConstantNamingVisitor(this._rtiEncoder, this._closedWorld, this._hasher);
+  ConstantNamingVisitor(this._namer, this._closedWorld, this._hasher);
 
   JElementEnvironment get _elementEnvironment =>
       _closedWorld.elementEnvironment;
@@ -2047,7 +1870,7 @@
     }
     if (name == null) {
       // e.g. DartType 'dynamic' has no element.
-      name = _rtiEncoder.getTypeRepresentationForTypeConstant(type);
+      name = _namer.getTypeRepresentationForTypeConstant(type);
     }
     addIdentifier(name);
     add(getHashTag(constant, 3));
@@ -2061,21 +1884,13 @@
   }
 
   @override
-  void visitSynthetic(SyntheticConstantValue constant, [_]) {
-    switch (constant.valueKind) {
-      case SyntheticConstantKind.DUMMY_INTERCEPTOR:
-        add('dummy_receiver');
-        break;
-      case SyntheticConstantKind.TYPEVARIABLE_REFERENCE:
-        // Omit. These are opaque deferred indexes with nothing helpful to add.
-        break;
-      case SyntheticConstantKind.NAME:
-        add('name');
-        break;
-      default:
-        failedAt(
-            CURRENT_ELEMENT_SPANNABLE, "Unexpected SyntheticConstantValue");
-    }
+  void visitAbstractValue(AbstractValueConstantValue constant, [_]) {
+    add('dummy_receiver');
+  }
+
+  @override
+  void visitJsName(JsNameConstantValue constant, [_]) {
+    add('name');
   }
 
   @override
@@ -2094,11 +1909,11 @@
   static const _MASK = 0x1fffffff;
   static const _UINT32_LIMIT = 4 * 1024 * 1024 * 1024;
 
-  final RuntimeTypesEncoder _rtiEncoder;
+  final Namer _namer;
   final JClosedWorld _closedWorld;
   final Map<ConstantValue, int> _hashes = {};
 
-  ConstantCanonicalHasher(this._rtiEncoder, this._closedWorld);
+  ConstantCanonicalHasher(this._namer, this._closedWorld);
 
   JElementEnvironment get _elementEnvironment =>
       _closedWorld.elementEnvironment;
@@ -2186,7 +2001,7 @@
   int visitType(TypeConstantValue constant, [_]) {
     DartType type = constant.representedType;
     // This name includes the library name and type parameters.
-    String name = _rtiEncoder.getTypeRepresentationForTypeConstant(type);
+    String name = _namer.getTypeRepresentationForTypeConstant(type);
     return _hashString(4, name);
   }
 
@@ -2197,19 +2012,19 @@
   }
 
   @override
-  int visitSynthetic(SyntheticConstantValue constant, [_]) {
-    switch (constant.valueKind) {
-      case SyntheticConstantKind.TYPEVARIABLE_REFERENCE:
-        // These contain a deferred opaque index into metadata. There is nothing
-        // we can access that is stable between compiles.  Luckily, since they
-        // resolve to integer indexes, they're always part of a larger constant.
-        return 0;
-      default:
-        throw failedAt(
-            NO_LOCATION_SPANNABLE,
-            'SyntheticConstantValue should never be named and '
-            'never be subconstant');
-    }
+  int visitAbstractValue(AbstractValueConstantValue constant, [_]) {
+    throw failedAt(
+        NO_LOCATION_SPANNABLE,
+        'AbstractValueConstantValue should never be named and '
+        'never be subconstant');
+  }
+
+  @override
+  int visitJsName(JsNameConstantValue constant, [_]) {
+    throw failedAt(
+        NO_LOCATION_SPANNABLE,
+        'JsNameConstantValue should never be named and '
+        'never be subconstant');
   }
 
   @override
@@ -2288,10 +2103,9 @@
 }
 
 class FunctionTypeNamer extends BaseDartTypeVisitor {
-  final RuntimeTypesEncoder rtiEncoder;
   StringBuffer sb;
 
-  FunctionTypeNamer(this.rtiEncoder);
+  FunctionTypeNamer();
 
   String computeName(DartType type) {
     sb = new StringBuffer();
@@ -2322,9 +2136,19 @@
     sb.write(type.element.name);
   }
 
+  bool _isSimpleFunctionType(FunctionType type) {
+    if (!type.returnType.isDynamic) return false;
+    if (!type.optionalParameterTypes.isEmpty) return false;
+    if (!type.namedParameterTypes.isEmpty) return false;
+    for (DartType parameter in type.parameterTypes) {
+      if (!parameter.isDynamic) return false;
+    }
+    return true;
+  }
+
   @override
   visitFunctionType(FunctionType type, _) {
-    if (rtiEncoder.isSimpleFunctionType(type)) {
+    if (_isSimpleFunctionType(type)) {
       sb.write('args${type.parameterTypes.length}');
       return;
     }
@@ -2383,3 +2207,557 @@
     return _suggestedNames.containsValue(candidate);
   }
 }
+
+/// Fixed names usage by the namer.
+class FixedNames {
+  const FixedNames();
+
+  String get getterPrefix => r'get$';
+  String get setterPrefix => r'set$';
+  String get callPrefix => 'call';
+  String get callCatchAllName => r'call*';
+  String get callNameField => r'$callName';
+  String get reflectableField => r'$reflectable';
+  String get classDescriptorProperty => r'^';
+  String get defaultValuesField => r'$defaultValues';
+  String get deferredAction => r'$deferredAction';
+  String get operatorIsPrefix => r'$is';
+  String get operatorAsPrefix => r'$as';
+  String get operatorSignature => r'$signature';
+  String get requiredParameterField => r'$requiredArgCount';
+  String get rtiName => r'$ti';
+}
+
+/// Minified version of the fixed names usage by the namer.
+// TODO(johnniwinther): This should implement [FixedNames] and minify all fixed
+// names.
+class MinifiedFixedNames extends FixedNames {
+  const MinifiedFixedNames();
+
+  @override
+  String get getterPrefix => 'g';
+  @override
+  String get setterPrefix => 's';
+  @override
+  String get callPrefix => ''; // this will create function names $<n>
+  @override
+  String get operatorIsPrefix => r'$i';
+  @override
+  String get operatorAsPrefix => r'$a';
+  @override
+  String get callCatchAllName => r'$C';
+  @override
+  String get requiredParameterField => r'$R';
+  @override
+  String get defaultValuesField => r'$D';
+  @override
+  String get operatorSignature => r'$S';
+}
+
+/// Namer interface that can be used in modular code generation.
+abstract class ModularNamer {
+  FixedNames get fixedNames;
+  RuntimeTypeTags get rtiTags;
+
+  /// Returns a variable use for accessing [library].
+  ///
+  /// This is one of the [reservedGlobalObjectNames]
+  jsAst.Expression readGlobalObjectForLibrary(LibraryEntity library);
+
+  /// Returns a variable use for accessing the class [element].
+  ///
+  /// This is one of the [reservedGlobalObjectNames]
+  jsAst.Expression readGlobalObjectForClass(ClassEntity element);
+
+  /// Returns a variable use for accessing the type [element].
+  ///
+  /// This is one of the [reservedGlobalObjectNames]
+  jsAst.Expression readGlobalObjectForType(Entity element);
+
+  /// Returns a variable use for accessing the member [element].
+  ///
+  /// This is either the [staticStateHolder] or one of the
+  /// [reservedGlobalObjectNames]
+  jsAst.Expression readGlobalObjectForMember(MemberEntity element);
+
+  /// Returns a JavaScript property name used to store the class [element] on
+  /// one of the global objects.
+  ///
+  /// Should be used together with [globalObjectForClass], which denotes the
+  /// object on which the returned property name should be used.
+  jsAst.Name globalPropertyNameForClass(ClassEntity element);
+
+  /// Returns a JavaScript property name used to store the member [element] on
+  /// one of the global objects.
+  ///
+  /// Should be used together with [globalObjectForMember], which denotes the
+  /// object on which the returned property name should be used.
+  jsAst.Name globalPropertyNameForMember(MemberEntity element);
+
+  /// Returns a JavaScript property name used to store the type (typedef)
+  /// [element] on one of the global objects.
+  ///
+  /// Should be used together with [globalObjectForType], which denotes the
+  /// object on which the returned property name should be used.
+  jsAst.Name globalPropertyNameForType(Entity element);
+
+  /// Returns the name for the instance field that holds runtime type arguments
+  /// on generic classes.
+  jsAst.Name get rtiFieldJsName;
+
+  /// Property name on which [member] can be accessed directly,
+  /// without clashing with another JS property name.
+  ///
+  /// This is used for implementing super-calls, where ordinary dispatch
+  /// semantics must be circumvented. For example:
+  ///
+  ///     class A { foo() }
+  ///     class B extends A {
+  ///         foo() { super.foo() }
+  ///     }
+  ///
+  /// Example translation to JS:
+  ///
+  ///     A.prototype.super$A$foo = function() {...}
+  ///     A.prototype.foo$0 = A.prototype.super$A$foo
+  ///
+  ///     B.prototype.foo$0 = function() {
+  ///         this.super$A$foo(); // super.foo()
+  ///     }
+  ///
+  jsAst.Name aliasedSuperMemberPropertyName(MemberEntity member);
+
+  /// Returns the JavaScript property name used to store an instance field.
+  jsAst.Name instanceFieldPropertyName(FieldEntity element);
+
+  /// Annotated name for [method] encoding arity and named parameters.
+  jsAst.Name instanceMethodName(FunctionEntity method);
+
+  /// Translates a [String] into the corresponding [Name] data structure as
+  /// used by the namer.
+  ///
+  /// If [name] is a setter or getter name, the corresponding [GetterName] or
+  /// [SetterName] data structure is used.
+  jsAst.Name asName(String name);
+
+  /// Annotated name for the member being invoked by [selector].
+  jsAst.Name invocationName(Selector selector);
+
+  /// Property name used for a specialization of `getInterceptor`.
+  ///
+  /// js_runtime contains a top-level `getInterceptor` method. The
+  /// specializations have the same name, but with a suffix to avoid name
+  /// collisions.
+  jsAst.Name nameForGetInterceptor(Set<ClassEntity> classes);
+
+  /// Property name used for the one-shot interceptor method for the given
+  /// [selector] and return-type specialization.
+  jsAst.Name nameForGetOneShotInterceptor(
+      Selector selector, Set<ClassEntity> classes);
+
+  /// Returns the runtime name for [element].
+  ///
+  /// This name is used as the basis for deriving `is` and `as` property names
+  /// for the given type.
+  ///
+  /// The result is not always safe as a property name unless prefixing
+  /// [operatorIsPrefix] or [operatorAsPrefix]. If this is a function type,
+  /// then by convention, an underscore must also separate [operatorIsPrefix]
+  /// from the type name.
+  jsAst.Name runtimeTypeName(Entity element);
+
+  /// Property name in which to store the given static or instance [method].
+  /// For instance methods, this includes the suffix encoding arity and named
+  /// parameters.
+  ///
+  /// The name is not necessarily unique to [method], since a static method
+  /// may share its name with an instance method.
+  jsAst.Name methodPropertyName(FunctionEntity method);
+
+  /// Returns the name of the `isX` property for classes that implement
+  /// [element].
+  jsAst.Name operatorIs(ClassEntity element);
+
+  /// Return the name of the `isX` property for classes that implement [type].
+  jsAst.Name operatorIsType(DartType type);
+
+  /// Returns the name of the `asX` function for classes that implement the
+  /// generic class [element].
+  jsAst.Name substitutionName(ClassEntity element);
+
+  /// Returns the name of the lazy initializer for the static field [element].
+  jsAst.Name lazyInitializerName(FieldEntity element);
+
+  /// Returns the name of the closure of the static method [element].
+  jsAst.Name staticClosureName(FunctionEntity element);
+
+  /// Returns the disambiguated name of [class_].
+  ///
+  /// This is both the *runtime type* of the class (see [runtimeTypeName])
+  /// and a global property name in which to store its JS constructor.
+  jsAst.Name className(ClassEntity class_);
+
+  /// The prefix used for encoding async properties.
+  final String asyncPrefix = r"$async$";
+
+  /// Returns the name for the holder of static state.
+  ///
+  /// This is used for mutable static fields.
+  final String staticStateHolder = r'$';
+
+  jsAst.Name _literalAsyncPrefix;
+
+  ModularNamer() {
+    _literalAsyncPrefix = new StringBackedName(asyncPrefix);
+  }
+
+  /// Returns a safe variable name for use in async rewriting.
+  ///
+  /// Has the same property as [safeVariableName] but does not clash with
+  /// names returned from there.
+  /// Additionally, when used as a prefix to a variable name, the result
+  /// will be safe to use, as well.
+  String safeVariablePrefixForAsyncRewrite(String name) {
+    return "$asyncPrefix$name";
+  }
+
+  /// Returns the name for the async body of the method with the [original]
+  /// name.
+  jsAst.Name deriveAsyncBodyName(jsAst.Name original) {
+    return new AsyncName(_literalAsyncPrefix, original);
+  }
+
+  /// Returns the label name for [label] used as a break target.
+  String breakLabelName(LabelDefinition label) {
+    return '\$${label.labelName}\$${label.target.nestingLevel}';
+  }
+
+  /// Returns the label name for the implicit break label needed for the jump
+  /// [target].
+  String implicitBreakLabelName(JumpTarget target) {
+    return '\$${target.nestingLevel}';
+  }
+
+  /// Returns the label name for [label] used as a continue target.
+  ///
+  /// We sometimes handle continue targets differently from break targets,
+  /// so we have special continue-only labels.
+  String continueLabelName(LabelDefinition label) {
+    return 'c\$${label.labelName}\$${label.target.nestingLevel}';
+  }
+
+  /// Returns the label name for the implicit continue label needed for the jump
+  /// [target].
+  String implicitContinueLabelName(JumpTarget target) {
+    return 'c\$${target.nestingLevel}';
+  }
+
+  Set<String> _jsVariableReservedCache = null;
+
+  /// Names that cannot be used by local variables and parameters.
+  Set<String> get _jsVariableReserved {
+    if (_jsVariableReservedCache == null) {
+      _jsVariableReservedCache = new Set<String>();
+      _jsVariableReservedCache.addAll(Namer.javaScriptKeywords);
+      _jsVariableReservedCache.addAll(Namer.reservedPropertySymbols);
+      _jsVariableReservedCache.addAll(Namer.reservedGlobalSymbols);
+      _jsVariableReservedCache.addAll(Namer.reservedGlobalObjectNames);
+      // 26 letters in the alphabet, 25 not counting I.
+      assert(Namer.reservedGlobalObjectNames.length == 25);
+      _jsVariableReservedCache.addAll(Namer.reservedGlobalHelperFunctions);
+    }
+    return _jsVariableReservedCache;
+  }
+
+  /// Returns a variable name that cannot clash with a keyword, a global
+  /// variable, or any name starting with a single '$'.
+  ///
+  /// Furthermore, this function is injective, that is, it never returns the
+  /// same name for two different inputs.
+  String safeVariableName(String name) {
+    name = name.replaceAll('#', '_');
+    if (_jsVariableReserved.contains(name) || name.startsWith(r'$')) {
+      return '\$$name';
+    }
+    return name;
+  }
+
+  CommonElements get _commonElements;
+
+  /// Returns the string that is to be used as the result of a call to
+  /// [JS_GET_NAME] at [node] with argument [name].
+  jsAst.Name getNameForJsGetName(Spannable spannable, JsGetName name) {
+    switch (name) {
+      case JsGetName.GETTER_PREFIX:
+        return asName(fixedNames.getterPrefix);
+      case JsGetName.SETTER_PREFIX:
+        return asName(fixedNames.setterPrefix);
+      case JsGetName.CALL_PREFIX:
+        return asName(fixedNames.callPrefix);
+      case JsGetName.CALL_PREFIX0:
+        return asName('${fixedNames.callPrefix}\$0');
+      case JsGetName.CALL_PREFIX1:
+        return asName('${fixedNames.callPrefix}\$1');
+      case JsGetName.CALL_PREFIX2:
+        return asName('${fixedNames.callPrefix}\$2');
+      case JsGetName.CALL_PREFIX3:
+        return asName('${fixedNames.callPrefix}\$3');
+      case JsGetName.CALL_PREFIX4:
+        return asName('${fixedNames.callPrefix}\$4');
+      case JsGetName.CALL_PREFIX5:
+        return asName('${fixedNames.callPrefix}\$5');
+      case JsGetName.CALL_CATCH_ALL:
+        return asName(fixedNames.callCatchAllName);
+      case JsGetName.REFLECTABLE:
+        return asName(fixedNames.reflectableField);
+      case JsGetName.CLASS_DESCRIPTOR_PROPERTY:
+        return asName(fixedNames.classDescriptorProperty);
+      case JsGetName.REQUIRED_PARAMETER_PROPERTY:
+        return asName(fixedNames.requiredParameterField);
+      case JsGetName.DEFAULT_VALUES_PROPERTY:
+        return asName(fixedNames.defaultValuesField);
+      case JsGetName.CALL_NAME_PROPERTY:
+        return asName(fixedNames.callNameField);
+      case JsGetName.DEFERRED_ACTION_PROPERTY:
+        return asName(fixedNames.deferredAction);
+      case JsGetName.OPERATOR_AS_PREFIX:
+        return asName(fixedNames.operatorAsPrefix);
+      case JsGetName.SIGNATURE_NAME:
+        return asName(fixedNames.operatorSignature);
+      case JsGetName.RTI_NAME:
+        return asName(fixedNames.rtiName);
+      case JsGetName.TYPEDEF_TAG:
+        return asName(rtiTags.typedefTag);
+      case JsGetName.FUNCTION_TYPE_TAG:
+        return asName(rtiTags.functionTypeTag);
+      case JsGetName.FUNCTION_TYPE_GENERIC_BOUNDS_TAG:
+        return asName(rtiTags.functionTypeGenericBoundsTag);
+      case JsGetName.FUNCTION_TYPE_VOID_RETURN_TAG:
+        return asName(rtiTags.functionTypeVoidReturnTag);
+      case JsGetName.FUNCTION_TYPE_RETURN_TYPE_TAG:
+        return asName(rtiTags.functionTypeReturnTypeTag);
+      case JsGetName.FUNCTION_TYPE_REQUIRED_PARAMETERS_TAG:
+        return asName(rtiTags.functionTypeRequiredParametersTag);
+      case JsGetName.FUNCTION_TYPE_OPTIONAL_PARAMETERS_TAG:
+        return asName(rtiTags.functionTypeOptionalParametersTag);
+      case JsGetName.FUNCTION_TYPE_NAMED_PARAMETERS_TAG:
+        return asName(rtiTags.functionTypeNamedParametersTag);
+      case JsGetName.FUTURE_OR_TAG:
+        return asName(rtiTags.futureOrTag);
+      case JsGetName.FUTURE_OR_TYPE_ARGUMENT_TAG:
+        return asName(rtiTags.futureOrTypeTag);
+      case JsGetName.IS_INDEXABLE_FIELD_NAME:
+        return operatorIs(_commonElements.jsIndexingBehaviorInterface);
+      case JsGetName.NULL_CLASS_TYPE_NAME:
+        return runtimeTypeName(_commonElements.nullClass);
+      case JsGetName.OBJECT_CLASS_TYPE_NAME:
+        return runtimeTypeName(_commonElements.objectClass);
+      case JsGetName.FUNCTION_CLASS_TYPE_NAME:
+        return runtimeTypeName(_commonElements.functionClass);
+      case JsGetName.FUTURE_CLASS_TYPE_NAME:
+        return runtimeTypeName(_commonElements.futureClass);
+      default:
+        throw failedAt(spannable, 'Error: Namer has no name for "$name".');
+    }
+  }
+}
+
+class ModularNamerImpl extends ModularNamer {
+  final CodegenRegistry _registry;
+  @override
+  final RuntimeTypeTags rtiTags;
+  @override
+  final FixedNames fixedNames;
+
+  @override
+  final CommonElements _commonElements;
+
+  ModularNamerImpl(
+      this._registry, this._commonElements, this.rtiTags, this.fixedNames);
+
+  @override
+  jsAst.Name get rtiFieldJsName {
+    jsAst.Name name = new ModularName(ModularNameKind.rtiField);
+    _registry.registerModularName(name);
+    return name;
+  }
+
+  @override
+  jsAst.Name runtimeTypeName(Entity element) {
+    jsAst.Name name =
+        new ModularName(ModularNameKind.runtimeTypeName, data: element);
+    _registry.registerModularName(name);
+    return name;
+  }
+
+  @override
+  jsAst.Name className(ClassEntity element) {
+    jsAst.Name name = new ModularName(ModularNameKind.className, data: element);
+    _registry.registerModularName(name);
+    return name;
+  }
+
+  @override
+  jsAst.Expression readGlobalObjectForLibrary(LibraryEntity library) {
+    jsAst.Expression expression = new ModularExpression(
+        ModularExpressionKind.globalObjectForLibrary, library);
+    _registry.registerModularExpression(expression);
+    return expression;
+  }
+
+  @override
+  jsAst.Expression readGlobalObjectForClass(ClassEntity element) {
+    jsAst.Expression expression = new ModularExpression(
+        ModularExpressionKind.globalObjectForClass, element);
+    _registry.registerModularExpression(expression);
+    return expression;
+  }
+
+  @override
+  jsAst.Expression readGlobalObjectForType(Entity element) {
+    jsAst.Expression expression = new ModularExpression(
+        ModularExpressionKind.globalObjectForType, element);
+    _registry.registerModularExpression(expression);
+    return expression;
+  }
+
+  @override
+  jsAst.Expression readGlobalObjectForMember(MemberEntity element) {
+    jsAst.Expression expression = new ModularExpression(
+        ModularExpressionKind.globalObjectForMember, element);
+    _registry.registerModularExpression(expression);
+    return expression;
+  }
+
+  @override
+  jsAst.Name aliasedSuperMemberPropertyName(MemberEntity member) {
+    jsAst.Name name =
+        new ModularName(ModularNameKind.aliasedSuperMember, data: member);
+    _registry.registerModularName(name);
+    return name;
+  }
+
+  @override
+  jsAst.Name staticClosureName(FunctionEntity element) {
+    jsAst.Name name =
+        new ModularName(ModularNameKind.staticClosure, data: element);
+    _registry.registerModularName(name);
+    return name;
+  }
+
+  @override
+  jsAst.Name methodPropertyName(FunctionEntity method) {
+    jsAst.Name name =
+        new ModularName(ModularNameKind.methodProperty, data: method);
+    _registry.registerModularName(name);
+    return name;
+  }
+
+  @override
+  jsAst.Name instanceFieldPropertyName(FieldEntity element) {
+    jsAst.Name name =
+        new ModularName(ModularNameKind.instanceField, data: element);
+    _registry.registerModularName(name);
+    return name;
+  }
+
+  @override
+  jsAst.Name operatorIsType(DartType type) {
+    jsAst.Name name =
+        new ModularName(ModularNameKind.operatorIsType, data: type);
+    _registry.registerModularName(name);
+    return name;
+  }
+
+  @override
+  jsAst.Name instanceMethodName(FunctionEntity method) {
+    jsAst.Name name =
+        new ModularName(ModularNameKind.instanceMethod, data: method);
+    _registry.registerModularName(name);
+    return name;
+  }
+
+  @override
+  jsAst.Name invocationName(Selector selector) {
+    jsAst.Name name =
+        new ModularName(ModularNameKind.invocation, data: selector);
+    _registry.registerModularName(name);
+    return name;
+  }
+
+  @override
+  jsAst.Name lazyInitializerName(FieldEntity element) {
+    jsAst.Name name =
+        new ModularName(ModularNameKind.lazyInitializer, data: element);
+    _registry.registerModularName(name);
+    return name;
+  }
+
+  @override
+  jsAst.Name operatorIs(ClassEntity element) {
+    jsAst.Name name =
+        new ModularName(ModularNameKind.operatorIs, data: element);
+    _registry.registerModularName(name);
+    return name;
+  }
+
+  @override
+  jsAst.Name globalPropertyNameForType(Entity element) {
+    jsAst.Name name = new ModularName(ModularNameKind.globalPropertyNameForType,
+        data: element);
+    _registry.registerModularName(name);
+    return name;
+  }
+
+  @override
+  jsAst.Name globalPropertyNameForClass(ClassEntity element) {
+    jsAst.Name name = new ModularName(
+        ModularNameKind.globalPropertyNameForClass,
+        data: element);
+    _registry.registerModularName(name);
+    return name;
+  }
+
+  @override
+  jsAst.Name globalPropertyNameForMember(MemberEntity element) {
+    jsAst.Name name = new ModularName(
+        ModularNameKind.globalPropertyNameForMember,
+        data: element);
+    _registry.registerModularName(name);
+    return name;
+  }
+
+  @override
+  jsAst.Name nameForGetInterceptor(Set<ClassEntity> classes) {
+    jsAst.Name name =
+        new ModularName(ModularNameKind.nameForGetInterceptor, set: classes);
+    _registry.registerModularName(name);
+    return name;
+  }
+
+  @override
+  jsAst.Name nameForGetOneShotInterceptor(
+      Selector selector, Set<ClassEntity> classes) {
+    jsAst.Name name = new ModularName(
+        ModularNameKind.nameForGetOneShotInterceptor,
+        data: selector,
+        set: classes);
+    _registry.registerModularName(name);
+    return name;
+  }
+
+  @override
+  jsAst.Name asName(String text) {
+    jsAst.Name name = new ModularName(ModularNameKind.asName, data: text);
+    _registry.registerModularName(name);
+    return name;
+  }
+
+  @override
+  jsAst.Name substitutionName(ClassEntity element) {
+    jsAst.Name name =
+        new ModularName(ModularNameKind.substitution, data: element);
+    _registry.registerModularName(name);
+    return name;
+  }
+}
diff --git a/pkg/compiler/lib/src/js_backend/namer_names.dart b/pkg/compiler/lib/src/js_backend/namer_names.dart
index db0819d..f74a30a 100644
--- a/pkg/compiler/lib/src/js_backend/namer_names.dart
+++ b/pkg/compiler/lib/src/js_backend/namer_names.dart
@@ -4,7 +4,6 @@
 
 part of js_backend.namer;
 
-// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
 abstract class _NamerName extends jsAst.Name {
   int get _kind;
   _NamerName get _target => this;
@@ -20,7 +19,6 @@
 
 enum _NamerNameKinds { StringBacked, Getter, Setter, Async, Compound, Token }
 
-// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
 class StringBackedName extends _NamerName {
   @override
   final String name;
@@ -43,14 +41,19 @@
   int get hashCode => name.hashCode;
 
   @override
-  int compareTo(covariant _NamerName other) {
-    other = other._target;
-    if (other._kind != _kind) return other._kind - _kind;
-    return name.compareTo(other.name);
+  int compareTo(jsAst.Name other) {
+    _NamerName otherNamerName;
+    if (other is ModularName) {
+      otherNamerName = other.value;
+    } else {
+      otherNamerName = other;
+    }
+    otherNamerName = otherNamerName._target;
+    if (otherNamerName._kind != _kind) return otherNamerName._kind - _kind;
+    return name.compareTo(otherNamerName.name);
   }
 }
 
-// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
 abstract class _PrefixedName extends _NamerName implements jsAst.AstContainer {
   final jsAst.Name prefix;
   final jsAst.Name base;
@@ -80,10 +83,16 @@
   int get hashCode => base.hashCode * 13 + prefix.hashCode;
 
   @override
-  int compareTo(covariant _NamerName other) {
-    other = other._target;
-    if (other._kind != _kind) return other._kind - _kind;
-    _PrefixedName otherSameKind = other;
+  int compareTo(jsAst.Name other) {
+    _NamerName otherNamerName;
+    if (other is ModularName) {
+      otherNamerName = other.value;
+    } else {
+      otherNamerName = other;
+    }
+    otherNamerName = otherNamerName._target;
+    if (otherNamerName._kind != _kind) return otherNamerName._kind - _kind;
+    _PrefixedName otherSameKind = otherNamerName;
     int result = prefix.compareTo(otherSameKind.prefix);
     if (result == 0) {
       result = prefix.compareTo(otherSameKind.prefix);
@@ -95,7 +104,6 @@
   }
 }
 
-// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
 class GetterName extends _PrefixedName {
   @override
   int get _kind => _NamerNameKinds.Getter.index;
@@ -103,7 +111,6 @@
   GetterName(jsAst.Name prefix, jsAst.Name base) : super(prefix, base);
 }
 
-// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
 class SetterName extends _PrefixedName {
   @override
   int get _kind => _NamerNameKinds.Setter.index;
@@ -111,18 +118,16 @@
   SetterName(jsAst.Name prefix, jsAst.Name base) : super(prefix, base);
 }
 
-// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
-class _AsyncName extends _PrefixedName {
+class AsyncName extends _PrefixedName {
   @override
   int get _kind => _NamerNameKinds.Async.index;
 
-  _AsyncName(jsAst.Name prefix, jsAst.Name base) : super(prefix, base);
+  AsyncName(jsAst.Name prefix, jsAst.Name base) : super(prefix, base);
 
   @override
   bool get allowRename => true;
 }
 
-// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
 class CompoundName extends _NamerName implements jsAst.AstContainer {
   final List<_NamerName> _parts;
   @override
@@ -170,10 +175,16 @@
   }
 
   @override
-  int compareTo(covariant _NamerName other) {
-    other = other._target;
-    if (other._kind != _kind) return other._kind - _kind;
-    CompoundName otherSameKind = other;
+  int compareTo(jsAst.Name other) {
+    _NamerName otherNamerName;
+    if (other is ModularName) {
+      otherNamerName = other.value;
+    } else {
+      otherNamerName = other;
+    }
+    otherNamerName = otherNamerName._target;
+    if (otherNamerName._kind != _kind) return otherNamerName._kind - _kind;
+    CompoundName otherSameKind = otherNamerName;
     if (otherSameKind._parts.length != _parts.length) {
       return otherSameKind._parts.length - _parts.length;
     }
@@ -185,7 +196,6 @@
   }
 }
 
-// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
 class TokenName extends _NamerName implements jsAst.ReferenceCountedAstNode {
   @override
   int get _kind => _NamerNameKinds.Token.index;
@@ -201,8 +211,8 @@
 
   @override
   String get name {
-    assert(isFinalized);
-    return _name;
+    assert(isFinalized, "TokenName($key) has not been finalized.");
+    return _name ?? key;
   }
 
   @override
@@ -214,7 +224,7 @@
   }
 
   @override
-  markSeen(jsAst.TokenCounter counter) => _rc++;
+  void markSeen(jsAst.TokenCounter counter) => _rc++;
 
   @override
   bool operator ==(other) {
@@ -226,7 +236,7 @@
   @override
   int get hashCode => super.hashCode;
 
-  finalize() {
+  void finalize() {
     assert(
         !isFinalized,
         failedAt(NO_LOCATION_SPANNABLE,
@@ -235,7 +245,6 @@
   }
 }
 
-// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
 class _NameReference extends _NamerName implements jsAst.AstContainer {
   @override
   _NamerName _target;
@@ -254,7 +263,15 @@
   String get name => _target.name;
 
   @override
-  int compareTo(covariant _NamerName other) => _target.compareTo(other);
+  int compareTo(jsAst.Name other) {
+    _NamerName otherNamerName;
+    if (other is ModularName) {
+      otherNamerName = other.value;
+    } else {
+      otherNamerName = other;
+    }
+    return _target.compareTo(otherNamerName);
+  }
 
   @override
   bool operator ==(other) => _target == other;
diff --git a/pkg/compiler/lib/src/js_backend/runtime_types.dart b/pkg/compiler/lib/src/js_backend/runtime_types.dart
index 87c984e..3dd3633 100644
--- a/pkg/compiler/lib/src/js_backend/runtime_types.dart
+++ b/pkg/compiler/lib/src/js_backend/runtime_types.dart
@@ -18,7 +18,7 @@
 import '../ir/runtime_type_analysis.dart';
 import '../js/js.dart' as jsAst;
 import '../js/js.dart' show js;
-import '../js_emitter/js_emitter.dart' show Emitter;
+import '../js_emitter/js_emitter.dart' show ModularEmitter;
 import '../options.dart';
 import '../serialization/serialization.dart';
 import '../universe/class_hierarchy.dart';
@@ -656,15 +656,8 @@
 }
 
 abstract class RuntimeTypesEncoder {
-  bool isSimpleFunctionType(FunctionType type);
-
-  jsAst.Expression getSignatureEncoding(
-      Emitter emitter, DartType type, jsAst.Expression this_);
-
-  jsAst.Expression getSubstitutionRepresentation(
-      Emitter emitter, List<DartType> types, OnVariableCallback onVariable);
-  jsAst.Expression getSubstitutionCode(
-      Emitter emitter, Substitution substitution);
+  jsAst.Expression getSignatureEncoding(ModularNamer namer,
+      ModularEmitter emitter, DartType type, jsAst.Expression this_);
 
   /// Returns the JavaScript template to determine at runtime if a type object
   /// is a function type.
@@ -686,15 +679,16 @@
   /// is a type argument of js-interop class.
   jsAst.Template get templateForIsJsInteropTypeArgument;
 
-  jsAst.Name get getFunctionThatReturnsNullName;
-
   /// Returns a [jsAst.Expression] representing the given [type]. Type variables
   /// are replaced by the [jsAst.Expression] returned by [onVariable].
   jsAst.Expression getTypeRepresentation(
-      Emitter emitter, DartType type, OnVariableCallback onVariable,
+      ModularEmitter emitter, DartType type, OnVariableCallback onVariable,
       [ShouldEncodeTypedefCallback shouldEncodeTypedef]);
 
-  String getTypeRepresentationForTypeConstant(DartType type);
+  jsAst.Expression getJsInteropTypeArguments(int count);
+
+  /// Fixed strings used for runtime types encoding.
+  RuntimeTypeTags get rtiTags;
 }
 
 /// Common functionality for [_RuntimeTypesNeedBuilder] and [_RuntimeTypes].
@@ -2206,27 +2200,17 @@
 }
 
 class RuntimeTypesEncoderImpl implements RuntimeTypesEncoder {
-  final Namer namer;
   final ElementEnvironment _elementEnvironment;
   final CommonElements commonElements;
   final TypeRepresentationGenerator _representationGenerator;
   final RuntimeTypesNeed _rtiNeed;
+  @override
+  final RuntimeTypeTags rtiTags;
 
-  RuntimeTypesEncoderImpl(this.namer, NativeBasicData nativeData,
+  RuntimeTypesEncoderImpl(this.rtiTags, NativeBasicData nativeData,
       this._elementEnvironment, this.commonElements, this._rtiNeed)
       : _representationGenerator =
-            new TypeRepresentationGenerator(namer, nativeData);
-
-  @override
-  bool isSimpleFunctionType(FunctionType type) {
-    if (!type.returnType.isDynamic) return false;
-    if (!type.optionalParameterTypes.isEmpty) return false;
-    if (!type.namedParameterTypes.isEmpty) return false;
-    for (DartType parameter in type.parameterTypes) {
-      if (!parameter.isDynamic) return false;
-    }
-    return true;
-  }
+            new TypeRepresentationGenerator(rtiTags, nativeData);
 
   /// Returns the JavaScript template to determine at runtime if a type object
   /// is a function type.
@@ -2263,28 +2247,18 @@
 
   @override
   jsAst.Expression getTypeRepresentation(
-      Emitter emitter, DartType type, OnVariableCallback onVariable,
+      ModularEmitter emitter, DartType type, OnVariableCallback onVariable,
       [ShouldEncodeTypedefCallback shouldEncodeTypedef]) {
     return _representationGenerator.getTypeRepresentation(
         emitter, type, onVariable, shouldEncodeTypedef);
   }
 
-  @override
-  jsAst.Expression getSubstitutionRepresentation(
-      Emitter emitter, List<DartType> types, OnVariableCallback onVariable) {
-    List<jsAst.Expression> elements = types
-        .map(
-            (DartType type) => getTypeRepresentation(emitter, type, onVariable))
-        .toList(growable: false);
-    return new jsAst.ArrayInitializer(elements);
-  }
-
   String getTypeVariableName(TypeVariableType type) {
     String name = type.element.name;
     return name.replaceAll('#', '_');
   }
 
-  jsAst.Expression getTypeEncoding(Emitter emitter, DartType type,
+  jsAst.Expression getTypeEncoding(ModularEmitter emitter, DartType type,
       {bool alwaysGenerateFunction: false}) {
     ClassEntity contextClass = DartTypes.getClassContext(type);
     jsAst.Expression onVariable(TypeVariableType v) {
@@ -2311,8 +2285,8 @@
   }
 
   @override
-  jsAst.Expression getSignatureEncoding(
-      Emitter emitter, DartType type, jsAst.Expression this_) {
+  jsAst.Expression getSignatureEncoding(ModularNamer namer,
+      ModularEmitter emitter, DartType type, jsAst.Expression this_) {
     ClassEntity contextClass = DartTypes.getClassContext(type);
     jsAst.Expression encoding =
         getTypeEncoding(emitter, type, alwaysGenerateFunction: true);
@@ -2338,100 +2312,41 @@
     }
   }
 
-  /// Compute a JavaScript expression that describes the necessary substitution
-  /// for type arguments in a subtype test.
-  ///
-  /// The result can be:
-  ///  1) `null`, if no substituted check is necessary, because the type
-  ///     variables are the same or there are no type variables in the class
-  ///     that is checked for.
-  ///  2) A list expression describing the type arguments to be used in the
-  ///     subtype check, if the type arguments to be used in the check do not
-  ///     depend on the type arguments of the object.
-  ///  3) A function mapping the type variables of the object to be checked to
-  ///     a list expression.
   @override
-  jsAst.Expression getSubstitutionCode(
-      Emitter emitter, Substitution substitution) {
-    if (substitution.isTrivial) {
-      return new jsAst.LiteralNull();
-    }
-
-    if (substitution.isJsInterop) {
-      return js(
-          'function() { return # }',
-          _representationGenerator
-              .getJsInteropTypeArguments(substitution.length));
-    }
-
-    jsAst.Expression declaration(TypeVariableType variable) {
-      return new jsAst.Parameter(getVariableName(variable.element.name));
-    }
-
-    jsAst.Expression use(TypeVariableType variable) {
-      return new jsAst.VariableUse(getVariableName(variable.element.name));
-    }
-
-    if (substitution.arguments.every((DartType type) => type.isDynamic)) {
-      return emitter.generateFunctionThatReturnsNull();
-    } else {
-      jsAst.Expression value =
-          getSubstitutionRepresentation(emitter, substitution.arguments, use);
-      if (substitution.isFunction) {
-        Iterable<jsAst.Expression> formals =
-            // TODO(johnniwinther): Pass [declaration] directly to `map` when
-            // `substitution.parameters` can no longer be a
-            // `List<ResolutionDartType>`.
-            substitution.parameters.map((type) => declaration(type));
-        return js('function(#) { return # }', [formals, value]);
-      } else {
-        return js('function() { return # }', value);
-      }
-    }
-  }
-
-  String getVariableName(String name) {
-    // Kernel type variable names for anonymous mixin applications have names
-    // canonicalized to a non-identified, e.g. '#U0'.
-    name = name.replaceAll('#', '_');
-    return namer.safeVariableName(name);
-  }
-
-  @override
-  jsAst.Name get getFunctionThatReturnsNullName =>
-      namer.internalGlobal('functionThatReturnsNull');
-
-  @override
-  String getTypeRepresentationForTypeConstant(DartType type) {
-    if (type.isDynamic) return "dynamic";
-    if (type is TypedefType) {
-      return namer.uniqueNameForTypeConstantElement(
-          type.element.library, type.element);
-    }
-    if (type is FunctionType) {
-      // TODO(johnniwinther): Add naming scheme for function type literals.
-      // These currently only occur from kernel.
-      return '()->';
-    }
-    InterfaceType interface = type;
-    String name = namer.uniqueNameForTypeConstantElement(
-        interface.element.library, interface.element);
-
-    // Type constants can currently only be raw types, so there is no point
-    // adding ground-term type parameters, as they would just be 'dynamic'.
-    // TODO(sra): Since the result string is used only in constructing constant
-    // names, it would result in more readable names if the final string was a
-    // legal JavaScript identifier.
-    if (interface.typeArguments.isEmpty) return name;
-    String arguments =
-        new List.filled(interface.typeArguments.length, 'dynamic').join(', ');
-    return '$name<$arguments>';
+  jsAst.Expression getJsInteropTypeArguments(int count) {
+    return _representationGenerator.getJsInteropTypeArguments(count);
   }
 }
 
+/// Fixed strings used for runtime types encoding.
+// TODO(johnniwinther): Use different names for minified code?
+class RuntimeTypeTags {
+  const RuntimeTypeTags();
+
+  String get typedefTag => r'typedef';
+
+  String get functionTypeTag => r'func';
+
+  String get functionTypeVoidReturnTag => r'v';
+
+  String get functionTypeReturnTypeTag => r'ret';
+
+  String get functionTypeRequiredParametersTag => r'args';
+
+  String get functionTypeOptionalParametersTag => r'opt';
+
+  String get functionTypeNamedParametersTag => r'named';
+
+  String get functionTypeGenericBoundsTag => r'bounds';
+
+  String get futureOrTag => r'futureOr';
+
+  String get futureOrTypeTag => r'type';
+}
+
 class TypeRepresentationGenerator
-    implements DartTypeVisitor<jsAst.Expression, Emitter> {
-  final Namer namer;
+    implements DartTypeVisitor<jsAst.Expression, ModularEmitter> {
+  final RuntimeTypeTags _rtiTags;
   final NativeBasicData _nativeData;
 
   OnVariableCallback onVariable;
@@ -2439,12 +2354,12 @@
   Map<TypeVariableType, jsAst.Expression> typedefBindings;
   List<FunctionTypeVariable> functionTypeVariables = <FunctionTypeVariable>[];
 
-  TypeRepresentationGenerator(this.namer, this._nativeData);
+  TypeRepresentationGenerator(this._rtiTags, this._nativeData);
 
   /// Creates a type representation for [type]. [onVariable] is called to
   /// provide the type representation for type variables.
   jsAst.Expression getTypeRepresentation(
-      Emitter emitter,
+      ModularEmitter emitter,
       DartType type,
       OnVariableCallback onVariable,
       ShouldEncodeTypedefCallback encodeTypedef) {
@@ -2459,7 +2374,8 @@
     return representation;
   }
 
-  jsAst.Expression getJavaScriptClassName(Entity element, Emitter emitter) {
+  jsAst.Expression getJavaScriptClassName(
+      Entity element, ModularEmitter emitter) {
     return emitter.typeAccess(element);
   }
 
@@ -2469,12 +2385,12 @@
 
   jsAst.Expression getJsInteropTypeArgumentValue() => js('-2');
   @override
-  jsAst.Expression visit(DartType type, Emitter emitter) =>
+  jsAst.Expression visit(DartType type, ModularEmitter emitter) =>
       type.accept(this, emitter);
 
   @override
   jsAst.Expression visitTypeVariableType(
-      TypeVariableType type, Emitter emitter) {
+      TypeVariableType type, ModularEmitter emitter) {
     if (typedefBindings != null) {
       assert(typedefBindings[type] != null);
       return typedefBindings[type];
@@ -2484,14 +2400,14 @@
 
   @override
   jsAst.Expression visitFunctionTypeVariable(
-      FunctionTypeVariable type, Emitter emitter) {
+      FunctionTypeVariable type, ModularEmitter emitter) {
     int position = functionTypeVariables.indexOf(type);
     assert(position >= 0);
     return js.number(functionTypeVariables.length - position - 1);
   }
 
   @override
-  jsAst.Expression visitDynamicType(DynamicType type, Emitter emitter) {
+  jsAst.Expression visitDynamicType(DynamicType type, ModularEmitter emitter) {
     return getDynamicValue();
   }
 
@@ -2508,7 +2424,8 @@
   }
 
   @override
-  jsAst.Expression visitInterfaceType(InterfaceType type, Emitter emitter) {
+  jsAst.Expression visitInterfaceType(
+      InterfaceType type, ModularEmitter emitter) {
     jsAst.Expression name = getJavaScriptClassName(type.element, emitter);
     jsAst.Expression result;
     if (type.typeArguments.isEmpty) {
@@ -2527,7 +2444,7 @@
     return result;
   }
 
-  jsAst.Expression visitList(List<DartType> types, Emitter emitter,
+  jsAst.Expression visitList(List<DartType> types, ModularEmitter emitter,
       {jsAst.Expression head}) {
     List<jsAst.Expression> elements = <jsAst.Expression>[];
     if (head != null) {
@@ -2547,13 +2464,13 @@
   /// Returns the JavaScript template to determine at runtime if a type object
   /// is a function type.
   jsAst.Template get templateForIsFunctionType {
-    return jsAst.js.expressionTemplateFor("'${namer.functionTypeTag}' in #");
+    return jsAst.js.expressionTemplateFor("'${_rtiTags.functionTypeTag}' in #");
   }
 
   /// Returns the JavaScript template to determine at runtime if a type object
   /// is a FutureOr type.
   jsAst.Template get templateForIsFutureOrType {
-    return jsAst.js.expressionTemplateFor("'${namer.futureOrTag}' in #");
+    return jsAst.js.expressionTemplateFor("'${_rtiTags.futureOrTag}' in #");
   }
 
   /// Returns the JavaScript template to determine at runtime if a type object
@@ -2573,7 +2490,8 @@
   }
 
   @override
-  jsAst.Expression visitFunctionType(FunctionType type, Emitter emitter) {
+  jsAst.Expression visitFunctionType(
+      FunctionType type, ModularEmitter emitter) {
     List<jsAst.Property> properties = <jsAst.Property>[];
 
     void addProperty(String name, jsAst.Expression value) {
@@ -2582,7 +2500,7 @@
 
     // Type representations for functions have a property which is a tag marking
     // them as function types. The value is not used, so '1' is just a dummy.
-    addProperty(namer.functionTypeTag, js.number(1));
+    addProperty(_rtiTags.functionTypeTag, js.number(1));
 
     if (type.typeVariables.isNotEmpty) {
       // Generic function types have type parameters which are reduced to de
@@ -2593,20 +2511,20 @@
       // TODO(sra): This emits `P.Object` for the common unbounded case. We
       // could replace the Object bounds with an array hole for a compact `[,,]`
       // representation.
-      addProperty(namer.functionTypeGenericBoundsTag,
+      addProperty(_rtiTags.functionTypeGenericBoundsTag,
           visitList(type.typeVariables.map((v) => v.bound).toList(), emitter));
     }
 
     if (!type.returnType.treatAsDynamic) {
       addProperty(
-          namer.functionTypeReturnTypeTag, visit(type.returnType, emitter));
+          _rtiTags.functionTypeReturnTypeTag, visit(type.returnType, emitter));
     }
     if (!type.parameterTypes.isEmpty) {
-      addProperty(namer.functionTypeRequiredParametersTag,
+      addProperty(_rtiTags.functionTypeRequiredParametersTag,
           visitList(type.parameterTypes, emitter));
     }
     if (!type.optionalParameterTypes.isEmpty) {
-      addProperty(namer.functionTypeOptionalParametersTag,
+      addProperty(_rtiTags.functionTypeOptionalParametersTag,
           visitList(type.optionalParameterTypes, emitter));
     }
     if (!type.namedParameterTypes.isEmpty) {
@@ -2619,7 +2537,7 @@
         namedArguments
             .add(new jsAst.Property(name, visit(types[index], emitter)));
       }
-      addProperty(namer.functionTypeNamedParametersTag,
+      addProperty(_rtiTags.functionTypeNamedParametersTag,
           new jsAst.ObjectInitializer(namedArguments));
     }
 
@@ -2632,12 +2550,12 @@
   }
 
   @override
-  jsAst.Expression visitVoidType(VoidType type, Emitter emitter) {
+  jsAst.Expression visitVoidType(VoidType type, ModularEmitter emitter) {
     return getVoidValue();
   }
 
   @override
-  jsAst.Expression visitTypedefType(TypedefType type, Emitter emitter) {
+  jsAst.Expression visitTypedefType(TypedefType type, ModularEmitter emitter) {
     bool shouldEncode = shouldEncodeTypedef(type);
     DartType unaliasedType = type.unaliased;
 
@@ -2683,7 +2601,7 @@
           : visitList(type.typeArguments, emitter, head: name);
 
       // Add it to the function-type object.
-      jsAst.LiteralString tag = js.string(namer.typedefTag);
+      jsAst.LiteralString tag = js.string(_rtiTags.typedefTag);
       initializer.properties.add(new jsAst.Property(tag, encodedTypedef));
       return finish(initializer);
     } else {
@@ -2692,7 +2610,8 @@
   }
 
   @override
-  jsAst.Expression visitFutureOrType(FutureOrType type, Emitter emitter) {
+  jsAst.Expression visitFutureOrType(
+      FutureOrType type, ModularEmitter emitter) {
     List<jsAst.Property> properties = <jsAst.Property>[];
 
     void addProperty(String name, jsAst.Expression value) {
@@ -2701,9 +2620,9 @@
 
     // Type representations for FutureOr have a property which is a tag marking
     // them as FutureOr types. The value is not used, so '1' is just a dummy.
-    addProperty(namer.futureOrTag, js.number(1));
+    addProperty(_rtiTags.futureOrTag, js.number(1));
     if (!type.typeArgument.treatAsDynamic) {
-      addProperty(namer.futureOrTypeTag, visit(type.typeArgument, emitter));
+      addProperty(_rtiTags.futureOrTypeTag, visit(type.typeArgument, emitter));
     }
 
     return new jsAst.ObjectInitializer(properties);
diff --git a/pkg/compiler/lib/src/js_emitter/class_stub_generator.dart b/pkg/compiler/lib/src/js_emitter/class_stub_generator.dart
index 9e49e92..b6f90d4 100644
--- a/pkg/compiler/lib/src/js_emitter/class_stub_generator.dart
+++ b/pkg/compiler/lib/src/js_emitter/class_stub_generator.dart
@@ -62,7 +62,7 @@
       typeParameters,
       fieldInitializers,
       typeInits,
-      _namer.deferredAction
+      _namer.fixedNames.deferredAction
     ]);
   }
 
diff --git a/pkg/compiler/lib/src/js_emitter/code_emitter_task.dart b/pkg/compiler/lib/src/js_emitter/code_emitter_task.dart
index 74afc24..f0ed8a1 100644
--- a/pkg/compiler/lib/src/js_emitter/code_emitter_task.dart
+++ b/pkg/compiler/lib/src/js_emitter/code_emitter_task.dart
@@ -4,8 +4,6 @@
 
 library dart2js.js_emitter.code_emitter_task;
 
-import 'package:js_runtime/shared/embedded_names.dart' show JsBuiltin;
-
 import '../common.dart';
 import '../common/tasks.dart' show CompilerTask;
 import '../compiler.dart' show Compiler;
@@ -13,9 +11,9 @@
 import '../deferred_load.dart' show OutputUnit;
 import '../elements/entities.dart';
 import '../js/js.dart' as jsAst;
-import '../js_backend/js_backend.dart'
-    show CodegenInputs, JavaScriptBackend, Namer;
+import '../js_backend/backend.dart' show CodegenInputs, JavaScriptBackend;
 import '../js_backend/inferred_data.dart';
+import '../js_backend/namer.dart' show Namer;
 import '../universe/codegen_world_builder.dart';
 import '../world.dart' show JClosedWorld;
 import 'program_builder/program_builder.dart';
@@ -78,7 +76,8 @@
   }
 
   /// Creates the [Emitter] for this task.
-  void createEmitter(Namer namer, JClosedWorld closedWorld) {
+  void createEmitter(
+      Namer namer, CodegenInputs codegen, JClosedWorld closedWorld) {
     measure(() {
       _nativeEmitter =
           new NativeEmitter(this, closedWorld, _backend.nativeCodegenEnqueuer);
@@ -89,7 +88,7 @@
           _compiler.dumpInfoTask,
           namer,
           closedWorld,
-          _backend.rtiEncoder,
+          codegen.rtiEncoder,
           _backend.sourceInformationStrategy,
           this,
           _generateSourceMap);
@@ -97,7 +96,7 @@
           _compiler.options,
           _compiler.reporter,
           _emitter,
-          _backend.rtiEncoder,
+          codegen.rtiEncoder,
           closedWorld.elementEnvironment);
       typeTestRegistry = new TypeTestRegistry(
           _compiler.options, closedWorld.elementEnvironment);
@@ -139,7 +138,7 @@
           closedWorld.sorter,
           typeTestRegistry.rtiNeededClasses,
           closedWorld.elementEnvironment.mainFunction);
-      int size = emitter.emitProgram(programBuilder, codegen, codegenWorld);
+      int size = emitter.emitProgram(programBuilder, codegenWorld);
       // TODO(floitsch): we shouldn't need the `neededClasses` anymore.
       neededClasses = programBuilder.collector.neededClasses;
       return size;
@@ -147,23 +146,14 @@
   }
 }
 
-abstract class Emitter {
-  Program get programForTesting;
-
-  /// Uses the [programBuilder] to generate a model of the program, emits
-  /// the program, and returns the size of the generated output.
-  int emitProgram(ProgramBuilder programBuilder, CodegenInputs codegen,
-      CodegenWorld codegenWorld);
-
-  /// Returns the JS function that must be invoked to get the value of the
-  /// lazily initialized static.
-  jsAst.Expression isolateLazyInitializerAccess(covariant FieldEntity element);
-
-  /// Returns the closure expression of a static function.
-  jsAst.Expression isolateStaticClosureAccess(covariant FunctionEntity element);
-
-  /// Returns the JS code for accessing the embedded [global].
-  jsAst.Expression generateEmbeddedGlobalAccess(String global);
+/// Interface for the subset of the [Emitter] that can be used during modular
+/// code generation.
+///
+/// Note that the emission phase is not itself modular but performed on
+/// the closed world computed by the codegen enqueuer.
+abstract class ModularEmitter {
+  /// Returns the JS prototype of the given class [e].
+  jsAst.Expression prototypeAccess(ClassEntity e, {bool hasBeenInstantiated});
 
   /// Returns the JS function representing the given function.
   ///
@@ -172,13 +162,41 @@
 
   jsAst.Expression staticFieldAccess(FieldEntity element);
 
+  /// Returns the JS function that must be invoked to get the value of the
+  /// lazily initialized static.
+  jsAst.Expression isolateLazyInitializerAccess(covariant FieldEntity element);
+
+  /// Returns the closure expression of a static function.
+  jsAst.Expression staticClosureAccess(covariant FunctionEntity element);
+
   /// Returns the JS constructor of the given element.
   ///
   /// The returned expression must only be used in a JS `new` expression.
   jsAst.Expression constructorAccess(ClassEntity e);
 
-  /// Returns the JS prototype of the given class [e].
-  jsAst.Expression prototypeAccess(ClassEntity e, {bool hasBeenInstantiated});
+  /// Returns the JS expression representing the type [e].
+  jsAst.Expression typeAccess(Entity e);
+
+  /// Returns the JS code for accessing the embedded [global].
+  jsAst.Expression generateEmbeddedGlobalAccess(String global);
+
+  /// Returns the JS code for accessing the given [constant].
+  jsAst.Expression constantReference(ConstantValue constant);
+
+  /// Returns the JS code for accessing the global property [global].
+  String generateEmbeddedGlobalAccessString(String global);
+}
+
+/// Interface for the emitter that is used during the emission phase on the
+/// closed world computed by the codegen enqueuer.
+///
+/// These methods are _not_ available during modular code generation.
+abstract class Emitter implements ModularEmitter {
+  Program get programForTesting;
+
+  /// Uses the [programBuilder] to generate a model of the program, emits
+  /// the program, and returns the size of the generated output.
+  int emitProgram(ProgramBuilder programBuilder, CodegenWorld codegenWorld);
 
   /// Returns the JS prototype of the given interceptor class [e].
   jsAst.Expression interceptorPrototypeAccess(ClassEntity e);
@@ -186,21 +204,12 @@
   /// Returns the JS constructor of the given interceptor class [e].
   jsAst.Expression interceptorClassAccess(ClassEntity e);
 
-  /// Returns the JS expression representing the type [e].
-  jsAst.Expression typeAccess(Entity e);
-
   /// Returns the JS expression representing a function that returns 'null'
   jsAst.Expression generateFunctionThatReturnsNull();
 
   int compareConstants(ConstantValue a, ConstantValue b);
   bool isConstantInlinedOrAlreadyEmitted(ConstantValue constant);
 
-  /// Returns the JS code for accessing the given [constant].
-  jsAst.Expression constantReference(ConstantValue constant);
-
-  /// Returns the JS template for the given [builtin].
-  jsAst.Template templateForBuiltin(JsBuiltin builtin);
-
   /// Returns the size of the code generated for a given output [unit].
   int generatedSize(OutputUnit unit);
 }
diff --git a/pkg/compiler/lib/src/js_emitter/constant_ordering.dart b/pkg/compiler/lib/src/js_emitter/constant_ordering.dart
index 9306361..fb1a792 100644
--- a/pkg/compiler/lib/src/js_emitter/constant_ordering.dart
+++ b/pkg/compiler/lib/src/js_emitter/constant_ordering.dart
@@ -8,7 +8,6 @@
 import '../elements/entities.dart'
     show ClassEntity, FieldEntity, MemberEntity, TypedefEntity;
 import '../elements/types.dart';
-import '../js_backend/js_backend.dart' show SyntheticConstantKind;
 import 'sorter.dart' show Sorter;
 
 /// A canonical but arbitrary ordering of constants. The ordering is 'stable'
@@ -169,32 +168,16 @@
   }
 
   @override
-  int visitSynthetic(SyntheticConstantValue a, SyntheticConstantValue b) {
-    // [SyntheticConstantValue]s have abstract fields that are set only by
-    // convention.  Lucky for us, they do not occur as top level constant, only
-    // as elements of a few constants.  If this becomes a source of instability,
-    // we will need to add a total ordering on JavaScript ASTs including
-    // deferred elements.
-    SyntheticConstantKind aKind = a.valueKind;
-    SyntheticConstantKind bKind = b.valueKind;
-    int r = aKind.index - bKind.index;
-    if (r != 0) return r;
-    switch (aKind) {
-      case SyntheticConstantKind.DUMMY_INTERCEPTOR:
-      case SyntheticConstantKind.EMPTY_VALUE:
-        // Never emitted.
-        return 0;
+  int visitAbstractValue(
+      AbstractValueConstantValue a, AbstractValueConstantValue b) {
+    // Never emitted.
+    return 0;
+  }
 
-      case SyntheticConstantKind.TYPEVARIABLE_REFERENCE:
-        // An opaque deferred JS AST reference to a type in reflection data.
-        return 0;
-      case SyntheticConstantKind.NAME:
-        // An opaque deferred JS AST reference to a name.
-        return 0;
-      default:
-        // Should not happen.
-        throw 'unexpected SyntheticConstantKind $aKind';
-    }
+  @override
+  int visitJsName(JsNameConstantValue a, JsNameConstantValue b) {
+    // An opaque deferred JS AST reference to a name.
+    return 0;
   }
 
   @override
@@ -229,10 +212,11 @@
   static const int CONSTRUCTED = 10;
   static const int TYPE = 11;
   static const int INTERCEPTOR = 12;
-  static const int SYNTHETIC = 13;
-  static const int DEFERRED_GLOBAL = 14;
-  static const int NONCONSTANT = 15;
-  static const int INSTANTIATION = 16;
+  static const int ABSTRACT_VALUE = 13;
+  static const int JS_NAME = 14;
+  static const int DEFERRED_GLOBAL = 15;
+  static const int NONCONSTANT = 16;
+  static const int INSTANTIATION = 17;
 
   static int kind(ConstantValue constant) =>
       constant.accept(const _KindVisitor(), null);
@@ -264,7 +248,9 @@
   @override
   int visitInterceptor(InterceptorConstantValue a, _) => INTERCEPTOR;
   @override
-  int visitSynthetic(SyntheticConstantValue a, _) => SYNTHETIC;
+  int visitAbstractValue(AbstractValueConstantValue a, _) => ABSTRACT_VALUE;
+  @override
+  int visitJsName(JsNameConstantValue a, _) => JS_NAME;
   @override
   int visitDeferredGlobal(DeferredGlobalConstantValue a, _) => DEFERRED_GLOBAL;
   @override
diff --git a/pkg/compiler/lib/src/js_emitter/instantiation_stub_generator.dart b/pkg/compiler/lib/src/js_emitter/instantiation_stub_generator.dart
index 5905955..7a13db6 100644
--- a/pkg/compiler/lib/src/js_emitter/instantiation_stub_generator.dart
+++ b/pkg/compiler/lib/src/js_emitter/instantiation_stub_generator.dart
@@ -106,7 +106,8 @@
   /// }
   /// ```
   ParameterStubMethod _generateSignatureStub(FieldEntity functionField) {
-    jsAst.Name operatorSignature = _namer.asName(_namer.operatorSignature);
+    jsAst.Name operatorSignature =
+        _namer.asName(_namer.fixedNames.operatorSignature);
 
     jsAst.Fun function = js('function() { return #(#(this.#), this.#); }', [
       _emitter.staticFunctionAccess(
diff --git a/pkg/compiler/lib/src/js_emitter/interceptor_stub_generator.dart b/pkg/compiler/lib/src/js_emitter/interceptor_stub_generator.dart
index eeecd6ff..495613f 100644
--- a/pkg/compiler/lib/src/js_emitter/interceptor_stub_generator.dart
+++ b/pkg/compiler/lib/src/js_emitter/interceptor_stub_generator.dart
@@ -31,7 +31,6 @@
   final Emitter _emitter;
   final NativeCodegenEnqueuer _nativeCodegenEnqueuer;
   final Namer _namer;
-  final OneShotInterceptorData _oneShotInterceptorData;
   final CustomElementsCodegenAnalysis _customElementsCodegenAnalysis;
   final CodegenWorld _codegenWorld;
   final JClosedWorld _closedWorld;
@@ -42,7 +41,6 @@
       this._emitter,
       this._nativeCodegenEnqueuer,
       this._namer,
-      this._oneShotInterceptorData,
       this._customElementsCodegenAnalysis,
       this._codegenWorld,
       this._closedWorld);
@@ -51,7 +49,10 @@
 
   InterceptorData get _interceptorData => _closedWorld.interceptorData;
 
-  jsAst.Expression generateGetInterceptorMethod(Set<ClassEntity> classes) {
+  jsAst.Expression generateGetInterceptorMethod(
+      SpecializedGetInterceptor interceptor) {
+    Set<ClassEntity> classes = interceptor.classes;
+
     jsAst.Expression interceptorFor(ClassEntity cls) {
       return _emitter.interceptorPrototypeAccess(cls);
     }
@@ -374,11 +375,9 @@
     return null;
   }
 
-  jsAst.Expression generateOneShotInterceptor(jsAst.Name name) {
-    Selector selector =
-        _oneShotInterceptorData.getOneShotInterceptorSelector(name);
-    Set<ClassEntity> classes =
-        _interceptorData.getInterceptedClassesOn(selector.name, _closedWorld);
+  jsAst.Expression generateOneShotInterceptor(OneShotInterceptor interceptor) {
+    Selector selector = interceptor.selector;
+    Set<ClassEntity> classes = interceptor.classes;
     jsAst.Name getInterceptorName = _namer.nameForGetInterceptor(classes);
 
     List<String> parameterNames = <String>[];
diff --git a/pkg/compiler/lib/src/js_emitter/metadata_collector.dart b/pkg/compiler/lib/src/js_emitter/metadata_collector.dart
index 57ff772..0fa30eb 100644
--- a/pkg/compiler/lib/src/js_emitter/metadata_collector.dart
+++ b/pkg/compiler/lib/src/js_emitter/metadata_collector.dart
@@ -37,7 +37,7 @@
   // will be applied to the [entry] to also mark potential [_MetadataEntry]
   // instances in the [entry] as seen.
   @override
-  markSeen(jsAst.TokenCounter visitor);
+  void markSeen(jsAst.TokenCounter visitor);
 }
 
 class _BoundMetadataEntry extends _MetadataEntry {
@@ -65,7 +65,7 @@
   bool get isUsed => _rc > 0;
 
   @override
-  markSeen(jsAst.BaseVisitor visitor) {
+  void markSeen(jsAst.BaseVisitor visitor) {
     _rc++;
     if (_rc == 1) entry.accept(visitor);
   }
diff --git a/pkg/compiler/lib/src/js_emitter/program_builder/collector.dart b/pkg/compiler/lib/src/js_emitter/program_builder/collector.dart
index b2c2743..7b49849f 100644
--- a/pkg/compiler/lib/src/js_emitter/program_builder/collector.dart
+++ b/pkg/compiler/lib/src/js_emitter/program_builder/collector.dart
@@ -85,10 +85,9 @@
     // Go over specialized interceptors and then constants to know which
     // interceptors are needed.
     Set<ClassEntity> needed = new Set<ClassEntity>();
-    for (js.Name name
-        in _oneShotInterceptorData.specializedGetInterceptorNames) {
-      needed.addAll(
-          _oneShotInterceptorData.getSpecializedGetInterceptorsFor(name));
+    for (SpecializedGetInterceptor interceptor
+        in _oneShotInterceptorData.specializedGetInterceptors) {
+      needed.addAll(interceptor.classes);
     }
 
     // Add interceptors referenced by constants.
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 cd297c8..10ebf1d 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
@@ -345,7 +345,6 @@
         _task.emitter,
         _nativeCodegenEnqueuer,
         _namer,
-        _oneShotInterceptorData,
         _customElementsCodegenAnalysis,
         _codegenWorld,
         _closedWorld);
@@ -958,7 +957,8 @@
       FunctionType type, OutputUnit outputUnit) {
     if (type.containsTypeVariables) {
       js.Expression thisAccess = js.js(r'this.$receiver');
-      return _rtiEncoder.getSignatureEncoding(_task.emitter, type, thisAccess);
+      return _rtiEncoder.getSignatureEncoding(
+          _namer, _task.emitter, type, thisAccess);
     } else {
       return _task.metadataCollector.reifyType(type, outputUnit);
     }
@@ -1001,11 +1001,10 @@
   // We must evaluate these classes eagerly so that the prototype is
   // accessible.
   void _markEagerInterceptorClasses() {
-    Iterable<js.Name> names =
-        _oneShotInterceptorData.specializedGetInterceptorNames;
-    for (js.Name name in names) {
-      for (ClassEntity element
-          in _oneShotInterceptorData.getSpecializedGetInterceptorsFor(name)) {
+    Iterable<SpecializedGetInterceptor> interceptors =
+        _oneShotInterceptorData.specializedGetInterceptors;
+    for (SpecializedGetInterceptor interceptor in interceptors) {
+      for (ClassEntity element in interceptor.classes) {
         Class cls = _classes[element];
         if (cls != null) cls.isEager = true;
       }
@@ -1019,7 +1018,6 @@
         _task.emitter,
         _nativeCodegenEnqueuer,
         _namer,
-        _oneShotInterceptorData,
         _customElementsCodegenAnalysis,
         _codegenWorld,
         _closedWorld);
@@ -1029,13 +1027,23 @@
     // TODO(floitsch): we shouldn't update the registry in the middle of
     // generating the interceptor methods.
     Holder holder = _registry.registerHolder(holderName);
-
-    Iterable<js.Name> names =
-        _oneShotInterceptorData.specializedGetInterceptorNames;
+    List<js.Name> names = [];
+    Map<js.Name, SpecializedGetInterceptor> interceptorMap = {};
+    for (SpecializedGetInterceptor interceptor
+        in _oneShotInterceptorData.specializedGetInterceptors) {
+      js.Name name = _namer.nameForGetInterceptor(interceptor.classes);
+      names.add(name);
+      assert(
+          !interceptorMap.containsKey(name),
+          "Duplicate specialized get interceptor for $name: Existing: "
+          "${interceptorMap[name]}, new ${interceptor}.");
+      interceptorMap[name] = interceptor;
+    }
+    names.sort();
     return names.map((js.Name name) {
-      Set<ClassEntity> classes =
-          _oneShotInterceptorData.getSpecializedGetInterceptorsFor(name);
-      js.Expression code = stubGenerator.generateGetInterceptorMethod(classes);
+      SpecializedGetInterceptor interceptor = interceptorMap[name];
+      js.Expression code =
+          stubGenerator.generateGetInterceptorMethod(interceptor);
       return new StaticStubMethod(name, holder, code);
     });
   }
@@ -1115,7 +1123,6 @@
         _task.emitter,
         _nativeCodegenEnqueuer,
         _namer,
-        _oneShotInterceptorData,
         _customElementsCodegenAnalysis,
         _codegenWorld,
         _closedWorld);
@@ -1125,10 +1132,24 @@
     // TODO(floitsch): we shouldn't update the registry in the middle of
     // generating the interceptor methods.
     Holder holder = _registry.registerHolder(holderName);
-
-    List<js.Name> names = _oneShotInterceptorData.oneShotInterceptorNames;
+    List<js.Name> names = [];
+    Map<js.Name, OneShotInterceptor> interceptorMap = {};
+    for (OneShotInterceptor interceptor
+        in _oneShotInterceptorData.oneShotInterceptors) {
+      js.Name name = _namer.nameForGetOneShotInterceptor(
+          interceptor.selector, interceptor.classes);
+      names.add(name);
+      assert(
+          !interceptorMap.containsKey(name),
+          "Duplicate specialized get interceptor for $name: Existing: "
+          "${interceptorMap[name]}, new ${interceptor}.");
+      interceptorMap[name] = interceptor;
+    }
+    names.sort();
     return names.map((js.Name name) {
-      js.Expression code = stubGenerator.generateOneShotInterceptor(name);
+      OneShotInterceptor interceptor = interceptorMap[name];
+      js.Expression code =
+          stubGenerator.generateOneShotInterceptor(interceptor);
       return new StaticStubMethod(name, holder, code);
     });
   }
diff --git a/pkg/compiler/lib/src/js_emitter/runtime_type_generator.dart b/pkg/compiler/lib/src/js_emitter/runtime_type_generator.dart
index 02cdf45..d82e130 100644
--- a/pkg/compiler/lib/src/js_emitter/runtime_type_generator.dart
+++ b/pkg/compiler/lib/src/js_emitter/runtime_type_generator.dart
@@ -16,6 +16,7 @@
     show
         ClassChecks,
         ClassFunctionType,
+        OnVariableCallback,
         RuntimeTypesChecks,
         RuntimeTypesEncoder,
         Substitution,
@@ -23,7 +24,7 @@
 import '../js_emitter/sorter.dart';
 import '../util/util.dart' show Setlet;
 
-import 'code_emitter_task.dart' show CodeEmitterTask;
+import 'code_emitter_task.dart' show CodeEmitterTask, Emitter;
 
 // Function signatures used in the generation of runtime type information.
 typedef void FunctionTypeSignatureEmitter(ClassFunctionType classFunctionType);
@@ -172,7 +173,7 @@
         }
         if (encoding != null) {
           jsAst.Name operatorSignature =
-              _namer.asName(_namer.operatorSignature);
+              _namer.asName(_namer.fixedNames.operatorSignature);
           result.addSignature(classElement, operatorSignature, encoding);
         }
       }
@@ -187,7 +188,7 @@
       Substitution substitution = check.substitution;
       if (substitution != null) {
         jsAst.Expression body =
-            _rtiEncoder.getSubstitutionCode(emitterTask.emitter, substitution);
+            _getSubstitutionCode(emitterTask.emitter, substitution);
         result.addSubstitution(
             checkedClass, _namer.substitutionName(checkedClass), body);
       }
@@ -201,14 +202,80 @@
       if (type != null) {
         jsAst.Expression thisAccess = new jsAst.This();
         jsAst.Expression encoding = _rtiEncoder.getSignatureEncoding(
-            emitterTask.emitter, type, thisAccess);
-        jsAst.Name operatorSignature = _namer.asName(_namer.operatorSignature);
+            _namer, emitterTask.emitter, type, thisAccess);
+        jsAst.Name operatorSignature =
+            _namer.asName(_namer.fixedNames.operatorSignature);
         result.addSignature(classElement, operatorSignature, encoding);
       }
     }
     return result;
   }
 
+  /// Compute a JavaScript expression that describes the necessary substitution
+  /// for type arguments in a subtype test.
+  ///
+  /// The result can be:
+  ///  1) `null`, if no substituted check is necessary, because the type
+  ///     variables are the same or there are no type variables in the class
+  ///     that is checked for.
+  ///  2) A list expression describing the type arguments to be used in the
+  ///     subtype check, if the type arguments to be used in the check do not
+  ///     depend on the type arguments of the object.
+  ///  3) A function mapping the type variables of the object to be checked to
+  ///     a list expression.
+  jsAst.Expression _getSubstitutionCode(
+      Emitter emitter, Substitution substitution) {
+    if (substitution.isTrivial) {
+      return new jsAst.LiteralNull();
+    }
+
+    if (substitution.isJsInterop) {
+      return js('function() { return # }',
+          _rtiEncoder.getJsInteropTypeArguments(substitution.length));
+    }
+
+    jsAst.Expression declaration(TypeVariableType variable) {
+      return new jsAst.Parameter(_getVariableName(variable.element.name));
+    }
+
+    jsAst.Expression use(TypeVariableType variable) {
+      return new jsAst.VariableUse(_getVariableName(variable.element.name));
+    }
+
+    if (substitution.arguments.every((DartType type) => type.isDynamic)) {
+      return emitter.generateFunctionThatReturnsNull();
+    } else {
+      jsAst.Expression value =
+          _getSubstitutionRepresentation(emitter, substitution.arguments, use);
+      if (substitution.isFunction) {
+        Iterable<jsAst.Expression> formals =
+            // TODO(johnniwinther): Pass [declaration] directly to `map` when
+            // `substitution.parameters` can no longer be a
+            // `List<ResolutionDartType>`.
+            substitution.parameters.map((type) => declaration(type));
+        return js('function(#) { return # }', [formals, value]);
+      } else {
+        return js('function() { return # }', value);
+      }
+    }
+  }
+
+  jsAst.Expression _getSubstitutionRepresentation(
+      Emitter emitter, List<DartType> types, OnVariableCallback onVariable) {
+    List<jsAst.Expression> elements = types
+        .map((DartType type) =>
+            _rtiEncoder.getTypeRepresentation(emitter, type, onVariable))
+        .toList(growable: false);
+    return new jsAst.ArrayInitializer(elements);
+  }
+
+  String _getVariableName(String name) {
+    // Kernel type variable names for anonymous mixin applications have names
+    // canonicalized to a non-identified, e.g. '#U0'.
+    name = name.replaceAll('#', '_');
+    return _namer.safeVariableName(name);
+  }
+
   void _generateIsTestsOn(
       ClassEntity cls,
       FunctionTypeSignatureEmitter generateFunctionTypeSignature,
diff --git a/pkg/compiler/lib/src/js_emitter/startup_emitter/emitter.dart b/pkg/compiler/lib/src/js_emitter/startup_emitter/emitter.dart
index f595f07..ba22b6e 100644
--- a/pkg/compiler/lib/src/js_emitter/startup_emitter/emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/startup_emitter/emitter.dart
@@ -4,33 +4,140 @@
 
 library dart2js.js_emitter.startup_emitter;
 
-import 'package:js_runtime/shared/embedded_names.dart'
-    show JsBuiltin, METADATA, TYPES;
-
 import '../../../compiler_new.dart';
 import '../../common.dart';
+import '../../common/codegen.dart';
 import '../../common/tasks.dart';
-import '../../constants/values.dart' show ConstantValue;
+import '../../constants/values.dart';
 import '../../deferred_load.dart' show OutputUnit;
 import '../../dump_info.dart';
 import '../../elements/entities.dart';
 import '../../io/source_information.dart';
 import '../../js/js.dart' as js;
-import '../../js_backend/js_backend.dart' show CodegenInputs, Namer;
+import '../../js_backend/constant_emitter.dart';
+import '../../js_backend/namer.dart';
 import '../../js_backend/runtime_types.dart';
 import '../../options.dart';
 import '../../universe/codegen_world_builder.dart' show CodegenWorld;
 import '../../world.dart' show JClosedWorld;
-import '../js_emitter.dart' show Emitter;
+import '../js_emitter.dart' show Emitter, ModularEmitter;
 import '../model.dart';
 import '../program_builder/program_builder.dart' show ProgramBuilder;
 import 'model_emitter.dart';
 
-class EmitterImpl implements Emitter {
+abstract class ModularEmitterBase implements ModularEmitter {
+  final ModularNamer _namer;
+
+  ModularEmitterBase(this._namer);
+
+  js.PropertyAccess globalPropertyAccessForClass(ClassEntity element) {
+    js.Name name = _namer.globalPropertyNameForClass(element);
+    js.PropertyAccess pa =
+        new js.PropertyAccess(_namer.readGlobalObjectForClass(element), name);
+    return pa;
+  }
+
+  js.PropertyAccess globalPropertyAccessForType(Entity element) {
+    js.Name name = _namer.globalPropertyNameForType(element);
+    js.PropertyAccess pa =
+        new js.PropertyAccess(_namer.readGlobalObjectForType(element), name);
+    return pa;
+  }
+
+  js.PropertyAccess globalPropertyAccessForMember(MemberEntity element) {
+    js.Name name = _namer.globalPropertyNameForMember(element);
+    js.PropertyAccess pa =
+        new js.PropertyAccess(_namer.readGlobalObjectForMember(element), name);
+    return pa;
+  }
+
+  @override
+  js.PropertyAccess constructorAccess(ClassEntity element) {
+    return globalPropertyAccessForClass(element);
+  }
+
+  @override
+  js.Expression isolateLazyInitializerAccess(FieldEntity element) {
+    return new js.PropertyAccess(_namer.readGlobalObjectForMember(element),
+        _namer.lazyInitializerName(element));
+  }
+
+  @override
+  js.PropertyAccess staticFunctionAccess(FunctionEntity element) {
+    return globalPropertyAccessForMember(element);
+  }
+
+  @override
+  js.PropertyAccess staticFieldAccess(FieldEntity element) {
+    return globalPropertyAccessForMember(element);
+  }
+
+  @override
+  js.PropertyAccess prototypeAccess(ClassEntity element,
+      {bool hasBeenInstantiated}) {
+    js.Expression constructor =
+        hasBeenInstantiated ? constructorAccess(element) : typeAccess(element);
+    return js.js('#.prototype', constructor);
+  }
+
+  @override
+  js.Expression typeAccess(Entity element) {
+    return globalPropertyAccessForType(element);
+  }
+
+  @override
+  js.Expression staticClosureAccess(FunctionEntity element) {
+    return new js.Call(
+        new js.PropertyAccess(_namer.readGlobalObjectForMember(element),
+            _namer.staticClosureName(element)),
+        const []);
+  }
+
+  @override
+  String generateEmbeddedGlobalAccessString(String global) {
+    // TODO(floitsch): don't use 'init' as global embedder storage.
+    return 'init.$global';
+  }
+}
+
+class ModularEmitterImpl extends ModularEmitterBase {
+  final CodegenRegistry _registry;
+  final ModularConstantEmitter _constantEmitter;
+
+  ModularEmitterImpl(
+      ModularNamer namer, this._registry, CompilerOptions options)
+      : _constantEmitter = new ModularConstantEmitter(options),
+        super(namer);
+
+  @override
+  js.Expression constantReference(ConstantValue constant) {
+    if (constant.isFunction) {
+      FunctionConstantValue function = constant;
+      return staticClosureAccess(function.element);
+    }
+    js.Expression expression = _constantEmitter.generate(constant);
+    if (expression != null) {
+      return expression;
+    }
+    expression =
+        new ModularExpression(ModularExpressionKind.constant, constant);
+    _registry.registerModularExpression(expression);
+    return expression;
+  }
+
+  @override
+  js.Expression generateEmbeddedGlobalAccess(String global) {
+    js.Expression expression = new ModularExpression(
+        ModularExpressionKind.embeddedGlobalAccess, global);
+    _registry.registerModularExpression(expression);
+    return expression;
+  }
+}
+
+class EmitterImpl extends ModularEmitterBase implements Emitter {
   final DiagnosticReporter _reporter;
   final JClosedWorld _closedWorld;
   final RuntimeTypesEncoder _rtiEncoder;
-  final Namer namer;
   ModelEmitter _emitter;
 
   @override
@@ -41,12 +148,13 @@
       this._reporter,
       CompilerOutput outputProvider,
       DumpInfoTask dumpInfoTask,
-      this.namer,
+      Namer namer,
       this._closedWorld,
       this._rtiEncoder,
       SourceInformationStrategy sourceInformationStrategy,
       CompilerTask task,
-      bool shouldGenerateSourceMap) {
+      bool shouldGenerateSourceMap)
+      : super(namer) {
     _emitter = new ModelEmitter(
         options,
         _reporter,
@@ -62,49 +170,15 @@
   }
 
   @override
-  int emitProgram(ProgramBuilder programBuilder, CodegenInputs codegen,
-      CodegenWorld codegenWorld) {
+  Namer get _namer => super._namer;
+
+  @override
+  int emitProgram(ProgramBuilder programBuilder, CodegenWorld codegenWorld) {
     Program program = programBuilder.buildProgram();
     if (retainDataForTesting) {
       programForTesting = program;
     }
-    return _emitter.emitProgram(program, codegen, codegenWorld);
-  }
-
-  js.PropertyAccess globalPropertyAccessForMember(MemberEntity element) {
-    js.Name name = namer.globalPropertyNameForMember(element);
-    js.PropertyAccess pa = new js.PropertyAccess(
-        new js.VariableUse(namer.globalObjectForMember(element)), name);
-    return pa;
-  }
-
-  js.PropertyAccess globalPropertyAccessForClass(ClassEntity element) {
-    js.Name name = namer.globalPropertyNameForClass(element);
-    js.PropertyAccess pa = new js.PropertyAccess(
-        new js.VariableUse(namer.globalObjectForClass(element)), name);
-    return pa;
-  }
-
-  js.PropertyAccess globalPropertyAccessForType(Entity element) {
-    js.Name name = namer.globalPropertyNameForType(element);
-    js.PropertyAccess pa = new js.PropertyAccess(
-        new js.VariableUse(namer.globalObjectForType(element)), name);
-    return pa;
-  }
-
-  @override
-  js.PropertyAccess staticFieldAccess(FieldEntity element) {
-    return globalPropertyAccessForMember(element);
-  }
-
-  @override
-  js.PropertyAccess staticFunctionAccess(FunctionEntity element) {
-    return globalPropertyAccessForMember(element);
-  }
-
-  @override
-  js.PropertyAccess constructorAccess(ClassEntity element) {
-    return globalPropertyAccessForClass(element);
+    return _emitter.emitProgram(program, codegenWorld);
   }
 
   @override
@@ -113,11 +187,6 @@
   }
 
   @override
-  js.Expression typeAccess(Entity element) {
-    return globalPropertyAccessForType(element);
-  }
-
-  @override
   bool isConstantInlinedOrAlreadyEmitted(ConstantValue constant) {
     return _emitter.isConstantInlinedOrAlreadyEmitted(constant);
   }
@@ -134,7 +203,7 @@
 
   @override
   js.Expression generateEmbeddedGlobalAccess(String global) {
-    return _emitter.generateEmbeddedGlobalAccess(global);
+    return js.js(generateEmbeddedGlobalAccessString(global));
   }
 
   @override
@@ -144,89 +213,11 @@
   }
 
   @override
-  js.Expression isolateLazyInitializerAccess(FieldEntity element) {
-    return js.js('#.#', [
-      namer.globalObjectForMember(element),
-      namer.lazyInitializerName(element)
-    ]);
-  }
-
-  @override
-  js.Expression isolateStaticClosureAccess(FunctionEntity element) {
-    return _emitter.generateStaticClosureAccess(element);
-  }
-
-  @override
-  js.PropertyAccess prototypeAccess(ClassEntity element,
-      {bool hasBeenInstantiated}) {
-    js.Expression constructor =
-        hasBeenInstantiated ? constructorAccess(element) : typeAccess(element);
-    return js.js('#.prototype', constructor);
-  }
-
-  @override
   js.Expression interceptorPrototypeAccess(ClassEntity e) {
     return js.js('#.prototype', interceptorClassAccess(e));
   }
 
   @override
-  js.Template templateForBuiltin(JsBuiltin builtin) {
-    switch (builtin) {
-      case JsBuiltin.dartObjectConstructor:
-        ClassEntity objectClass = _closedWorld.commonElements.objectClass;
-        return js.js.expressionTemplateYielding(typeAccess(objectClass));
-
-      case JsBuiltin.isCheckPropertyToJsConstructorName:
-        int isPrefixLength = namer.operatorIsPrefix.length;
-        return js.js.expressionTemplateFor('#.substring($isPrefixLength)');
-
-      case JsBuiltin.isFunctionType:
-        return _rtiEncoder.templateForIsFunctionType;
-
-      case JsBuiltin.isFutureOrType:
-        return _rtiEncoder.templateForIsFutureOrType;
-
-      case JsBuiltin.isVoidType:
-        return _rtiEncoder.templateForIsVoidType;
-
-      case JsBuiltin.isDynamicType:
-        return _rtiEncoder.templateForIsDynamicType;
-
-      case JsBuiltin.isJsInteropTypeArgument:
-        return _rtiEncoder.templateForIsJsInteropTypeArgument;
-
-      case JsBuiltin.rawRtiToJsConstructorName:
-        return js.js.expressionTemplateFor("#.name");
-
-      case JsBuiltin.rawRuntimeType:
-        return js.js.expressionTemplateFor("#.constructor");
-
-      case JsBuiltin.isSubtype:
-        // TODO(floitsch): move this closer to where is-check properties are
-        // built.
-        String isPrefix = namer.operatorIsPrefix;
-        return js.js.expressionTemplateFor("('$isPrefix' + #) in #.prototype");
-
-      case JsBuiltin.isGivenTypeRti:
-        return js.js.expressionTemplateFor('#.name === #');
-
-      case JsBuiltin.getMetadata:
-        String metadataAccess =
-            _emitter.generateEmbeddedGlobalAccessString(METADATA);
-        return js.js.expressionTemplateFor("$metadataAccess[#]");
-
-      case JsBuiltin.getType:
-        String typesAccess = _emitter.generateEmbeddedGlobalAccessString(TYPES);
-        return js.js.expressionTemplateFor("$typesAccess[#]");
-
-      default:
-        _reporter.internalError(
-            NO_LOCATION_SPANNABLE, "Unhandled Builtin: $builtin");
-        return null;
-    }
-  }
-
-  @override
   int generatedSize(OutputUnit unit) {
     if (_emitter.omittedFragments.any((f) => f.outputUnit == unit)) {
       return 0;
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 7781d54..0e58794 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
@@ -572,10 +572,10 @@
   final CompilerOptions _options;
   final DumpInfoTask _dumpInfoTask;
   final Namer _namer;
+  final Emitter _emitter;
   final ConstantEmitter _constantEmitter;
   final ModelEmitter _modelEmitter;
   final JClosedWorld _closedWorld;
-  final CodegenInputs _codegen;
   final CodegenWorld _codegenWorld;
 
   js.Name _call0Name, _call1Name, _call2Name;
@@ -590,14 +590,14 @@
       this._options,
       this._dumpInfoTask,
       this._namer,
+      this._emitter,
       this._constantEmitter,
       this._modelEmitter,
       this._closedWorld,
-      this._codegen,
       this._codegenWorld);
 
   js.Expression generateEmbeddedGlobalAccess(String global) =>
-      _modelEmitter.generateEmbeddedGlobalAccess(global);
+      _emitter.generateEmbeddedGlobalAccess(global);
 
   js.Expression generateConstantReference(ConstantValue value) =>
       _modelEmitter.generateConstantReference(value);
@@ -629,11 +629,11 @@
       // TODO(29455): 'hunkHelpers' displaces other names, so don't minify it.
       'hunkHelpers': js.VariableDeclaration('hunkHelpers', allowRename: false),
       'directAccessTestExpression': js.js(directAccessTestExpression),
-      'cyclicThrow': _codegen.emitter
+      'cyclicThrow': _emitter
           .staticFunctionAccess(_closedWorld.commonElements.cyclicThrowHelper),
-      'operatorIsPrefix': js.string(_namer.operatorIsPrefix),
+      'operatorIsPrefix': js.string(_namer.fixedNames.operatorIsPrefix),
       'tearOffCode': new js.Block(buildTearOffCode(
-          _options, _codegen.emitter, _namer, _closedWorld.commonElements)),
+          _options, _emitter, _namer, _closedWorld.commonElements)),
       'embeddedTypes': generateEmbeddedGlobalAccess(TYPES),
       'embeddedInterceptorTags':
           generateEmbeddedGlobalAccess(INTERCEPTORS_BY_TAG),
@@ -645,10 +645,10 @@
       'staticState': js.js('#', _namer.staticStateHolder),
       'constantHolderReference': buildConstantHolderReference(program),
       'holders': holderCode.statements,
-      'callName': js.string(_namer.callNameField),
+      'callName': js.string(_namer.fixedNames.callNameField),
       'stubName': js.string(_namer.stubNameField),
-      'argumentCount': js.string(_namer.requiredParameterField),
-      'defaultArgumentValues': js.string(_namer.defaultValuesField),
+      'argumentCount': js.string(_namer.fixedNames.requiredParameterField),
+      'defaultArgumentValues': js.string(_namer.fixedNames.defaultValuesField),
       'deferredGlobal': ModelEmitter.deferredInitializersGlobal,
       'hasSoftDeferredClasses': program.hasSoftDeferredClasses,
       'softId': js.string(softDeferredId),
@@ -817,8 +817,8 @@
     for (Library library in fragment.libraries) {
       for (StaticMethod method in library.statics) {
         assert(!method.holder.isStaticStateHolder);
-        var staticMethod = emitStaticMethod(method);
-        staticMethod.forEach((key, value) {
+        Map<js.Name, js.Expression> propertyMap = emitStaticMethod(method);
+        propertyMap.forEach((js.Name key, js.Expression value) {
           var property = new js.Property(js.quoteName(key), value);
           holderCode[method.holder].add(property);
           registerEntityAst(method.element, property, library: library.element);
@@ -826,7 +826,7 @@
       }
       for (Class cls in library.classes) {
         assert(!cls.holder.isStaticStateHolder);
-        var constructor = emitConstructor(cls);
+        js.Expression constructor = emitConstructor(cls);
         var property = new js.Property(js.quoteName(cls.name), constructor);
         registerEntityAst(cls.element, property, library: library.element);
         holderCode[cls.holder].add(property);
@@ -1072,14 +1072,15 @@
       // prototype for common values.
 
       // Closures taking exactly one argument are common.
+      properties.add(js.Property(js.string(_namer.fixedNames.callCatchAllName),
+          js.quoteName(call1Name)));
       properties.add(js.Property(
-          js.string(_namer.callCatchAllName), js.quoteName(call1Name)));
-      properties.add(
-          js.Property(js.string(_namer.requiredParameterField), js.number(1)));
+          js.string(_namer.fixedNames.requiredParameterField), js.number(1)));
 
       // Most closures have no optional arguments.
       properties.add(js.Property(
-          js.string(_namer.defaultValuesField), new js.LiteralNull()));
+          js.string(_namer.fixedNames.defaultValuesField),
+          new js.LiteralNull()));
     }
 
     return new js.ObjectInitializer(properties);
@@ -1189,12 +1190,12 @@
           js.Name applyName = method.applyIndex == 0
               ? method.name
               : method.parameterStubs[method.applyIndex - 1].name;
-          properties[js.string(_namer.callCatchAllName)] =
+          properties[js.string(_namer.fixedNames.callCatchAllName)] =
               js.quoteName(applyName);
         }
         // Common case of '1' is stored on the Closure class.
         if (method.requiredParameterCount != 1 || forceAdd) {
-          properties[js.string(_namer.requiredParameterField)] =
+          properties[js.string(_namer.fixedNames.requiredParameterField)] =
               js.number(method.requiredParameterCount);
         }
 
@@ -1203,7 +1204,8 @@
         // Default values property of `null` is stored on the common JS
         // superclass.
         if (defaultValues is! js.LiteralNull || forceAdd) {
-          properties[js.string(_namer.defaultValuesField)] = defaultValues;
+          properties[js.string(_namer.fixedNames.defaultValuesField)] =
+              defaultValues;
         }
       }
     }
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 f02e6a1..064bd19 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
@@ -44,7 +44,7 @@
 import '../../io/source_map_builder.dart' show SourceMapBuilder;
 import '../../js/js.dart' as js;
 import '../../js_backend/js_backend.dart'
-    show CodegenInputs, Namer, ConstantEmitter, StringBackedName;
+    show Namer, ConstantEmitter, StringBackedName;
 import '../../js_backend/js_interop_analysis.dart' as jsInteropAnalysis;
 import '../../js_backend/runtime_types.dart';
 import '../../options.dart';
@@ -65,6 +65,7 @@
   final DumpInfoTask _dumpInfoTask;
   final Namer _namer;
   final CompilerTask _task;
+  final Emitter _emitter;
   ConstantEmitter _constantEmitter;
   final bool _shouldGenerateSourceMap;
   final JClosedWorld _closedWorld;
@@ -93,7 +94,7 @@
       this._namer,
       this._closedWorld,
       this._task,
-      Emitter emitter,
+      this._emitter,
       this._sourceInformationStrategy,
       RuntimeTypesEncoder rtiEncoder,
       this._shouldGenerateSourceMap)
@@ -105,7 +106,7 @@
         _closedWorld.rtiNeed,
         rtiEncoder,
         _closedWorld.fieldAnalysis,
-        emitter,
+        _emitter,
         this.generateConstantReference,
         constantListGenerator);
   }
@@ -115,15 +116,6 @@
     return js.js('makeConstList(#)', [array]);
   }
 
-  js.Expression generateEmbeddedGlobalAccess(String global) {
-    return js.js(generateEmbeddedGlobalAccessString(global));
-  }
-
-  String generateEmbeddedGlobalAccessString(String global) {
-    // TODO(floitsch): don't use 'init' as global embedder storage.
-    return 'init.$global';
-  }
-
   bool isConstantInlinedOrAlreadyEmitted(ConstantValue constant) {
     if (constant.isFunction) return true; // Already emitted.
     if (constant.isPrimitive) return true; // Inlined.
@@ -154,17 +146,10 @@
     return _constantOrdering.compare(a, b);
   }
 
-  js.Expression generateStaticClosureAccess(FunctionEntity element) {
-    return js.js('#.#()', [
-      _namer.globalObjectForMember(element),
-      _namer.staticClosureName(element)
-    ]);
-  }
-
   js.Expression generateConstantReference(ConstantValue value) {
     if (value.isFunction) {
       FunctionConstantValue functionConstant = value;
-      return generateStaticClosureAccess(functionConstant.element);
+      return _emitter.staticClosureAccess(functionConstant.element);
     }
 
     // We are only interested in the "isInlined" part, but it does not hurt to
@@ -176,8 +161,7 @@
         [_namer.globalObjectForConstant(value), _namer.constantName(value)]);
   }
 
-  int emitProgram(
-      Program program, CodegenInputs codegen, CodegenWorld codegenWorld) {
+  int emitProgram(Program program, CodegenWorld codegenWorld) {
     MainFragment mainFragment = program.fragments.first;
     List<DeferredFragment> deferredFragments =
         new List<DeferredFragment>.from(program.deferredFragments);
@@ -186,10 +170,10 @@
         _options,
         _dumpInfoTask,
         _namer,
+        _emitter,
         _constantEmitter,
         this,
         _closedWorld,
-        codegen,
         codegenWorld);
 
     var deferredLoadingState = new DeferredLoadingState();
diff --git a/pkg/compiler/lib/src/js_model/element_map.dart b/pkg/compiler/lib/src/js_model/element_map.dart
index 1c7f8f8..2b2d412 100644
--- a/pkg/compiler/lib/src/js_model/element_map.dart
+++ b/pkg/compiler/lib/src/js_model/element_map.dart
@@ -15,9 +15,6 @@
 import '../ir/closure.dart';
 import '../ir/static_type_provider.dart';
 import '../ir/util.dart';
-import '../js/js.dart' as js;
-import '../js_backend/namer.dart';
-import '../js_emitter/code_emitter_task.dart';
 import '../js_model/closure.dart' show JRecordField;
 import '../js_model/elements.dart' show JGeneratorBody;
 import '../native/behavior.dart';
@@ -104,9 +101,6 @@
   NativeBehavior getNativeBehaviorForJsEmbeddedGlobalCall(
       ir.StaticInvocation node);
 
-  /// Returns the [js.Name] for the `JsGetName` [constant] value.
-  js.Name getNameForJsGetName(ConstantValue constant, Namer namer);
-
   /// Computes the [ConstantValue] for the constant [expression].
   // TODO(johnniwinther): Move to [KernelToElementMapForBuilding]. This is only
   // used in impact builder for symbol constants.
@@ -140,9 +134,6 @@
   /// Returns the [LibraryEntity] corresponding to the library [node].
   LibraryEntity getLibrary(ir.Library node);
 
-  /// Returns the [js.Template] for the `JsBuiltin` [constant] value.
-  js.Template getJsBuiltinTemplate(ConstantValue constant, Emitter emitter);
-
   /// Returns a [Spannable] for a message pointing to the IR [node] in the
   /// context of [member].
   Spannable getSpannable(MemberEntity member, ir.Node node);
diff --git a/pkg/compiler/lib/src/js_model/element_map_impl.dart b/pkg/compiler/lib/src/js_model/element_map_impl.dart
index 30418af..5356e84 100644
--- a/pkg/compiler/lib/src/js_model/element_map_impl.dart
+++ b/pkg/compiler/lib/src/js_model/element_map_impl.dart
@@ -4,7 +4,6 @@
 
 import 'package:front_end/src/api_unstable/dart2js.dart' show Link, LinkBuilder;
 
-import 'package:js_runtime/shared/embedded_names.dart';
 import 'package:kernel/ast.dart' as ir;
 import 'package:kernel/class_hierarchy.dart' as ir;
 import 'package:kernel/core_types.dart' as ir;
@@ -36,11 +35,8 @@
 import '../ir/static_type_cache.dart';
 import '../ir/static_type_provider.dart';
 import '../ir/util.dart';
-import '../js/js.dart' as js;
 import '../js_backend/annotations.dart';
-import '../js_backend/namer.dart';
 import '../js_backend/native_data.dart';
-import '../js_emitter/code_emitter_task.dart';
 import '../kernel/element_map_impl.dart';
 import '../kernel/env.dart';
 import '../kernel/kelements.dart';
@@ -1419,29 +1415,6 @@
   }
 
   @override
-  js.Name getNameForJsGetName(ConstantValue constant, Namer namer) {
-    int index = extractEnumIndexFromConstantValue(
-        constant, commonElements.jsGetNameEnum);
-    if (index == null) return null;
-    return namer.getNameForJsGetName(
-        CURRENT_ELEMENT_SPANNABLE, JsGetName.values[index]);
-  }
-
-  int extractEnumIndexFromConstantValue(
-      ConstantValue constant, ClassEntity classElement) {
-    if (constant is ConstructedConstantValue) {
-      if (constant.type.element == classElement) {
-        assert(constant.fields.length == 1 || constant.fields.length == 2);
-        ConstantValue indexConstant = constant.fields.values.first;
-        if (indexConstant is IntConstantValue) {
-          return indexConstant.intValue.toInt();
-        }
-      }
-    }
-    return null;
-  }
-
-  @override
   ConstantValue getConstantValue(ir.Expression node,
       {bool requireConstant: true, bool implicitNull: false}) {
     if (node is ir.ConstantExpression) {
@@ -2109,14 +2082,6 @@
     }
     return generatorBody;
   }
-
-  @override
-  js.Template getJsBuiltinTemplate(ConstantValue constant, Emitter emitter) {
-    int index = extractEnumIndexFromConstantValue(
-        constant, commonElements.jsBuiltinEnum);
-    if (index == null) return null;
-    return emitter.templateForBuiltin(JsBuiltin.values[index]);
-  }
 }
 
 class JsElementEnvironment extends ElementEnvironment
@@ -2619,3 +2584,35 @@
     return typeVariable;
   }
 }
+
+/// [EntityLookup] implementation for an fully built [JsKernelToElementMap].
+class ClosedEntityLookup implements EntityLookup {
+  final JsKernelToElementMap _elementMap;
+
+  ClosedEntityLookup(this._elementMap);
+
+  @override
+  IndexedTypeVariable getTypeVariableByIndex(int index) {
+    return _elementMap.typeVariables.getEntity(index);
+  }
+
+  @override
+  IndexedMember getMemberByIndex(int index) {
+    return _elementMap.members.getEntity(index);
+  }
+
+  @override
+  IndexedTypedef getTypedefByIndex(int index) {
+    return _elementMap.typedefs.getEntity(index);
+  }
+
+  @override
+  IndexedClass getClassByIndex(int index) {
+    return _elementMap.classes.getEntity(index);
+  }
+
+  @override
+  IndexedLibrary getLibraryByIndex(int index) {
+    return _elementMap.libraries.getEntity(index);
+  }
+}
diff --git a/pkg/compiler/lib/src/js_model/js_strategy.dart b/pkg/compiler/lib/src/js_model/js_strategy.dart
index ecda819..ffe37e3 100644
--- a/pkg/compiler/lib/src/js_model/js_strategy.dart
+++ b/pkg/compiler/lib/src/js_model/js_strategy.dart
@@ -8,10 +8,11 @@
 
 import '../backend_strategy.dart';
 import '../common.dart';
-import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem;
+import '../common/codegen.dart' show CodegenRegistry;
 import '../common/tasks.dart';
+import '../common/work.dart';
 import '../compiler.dart';
-import '../deferred_load.dart';
+import '../deferred_load.dart' hide WorkItem;
 import '../dump_info.dart';
 import '../elements/entities.dart';
 import '../enqueue.dart';
@@ -24,17 +25,17 @@
 import '../js/js_source_mapping.dart';
 import '../js_backend/backend.dart';
 import '../js_backend/inferred_data.dart';
-import '../js_backend/namer.dart';
 import '../js_backend/native_data.dart';
-import '../js_emitter/code_emitter_task.dart';
+import '../js_backend/namer.dart' show ModularNamer;
+import '../js_emitter/code_emitter_task.dart' show ModularEmitter;
 import '../kernel/kernel_strategy.dart';
 import '../native/behavior.dart';
 import '../options.dart';
+import '../serialization/serialization.dart';
 import '../ssa/builder_kernel.dart';
 import '../ssa/nodes.dart';
 import '../ssa/ssa.dart';
 import '../ssa/types.dart';
-import '../tracer.dart';
 import '../universe/codegen_world_builder.dart';
 import '../universe/selector.dart';
 import '../universe/world_builder.dart';
@@ -97,8 +98,8 @@
   }
 
   @override
-  SsaBuilder createSsaBuilder(CompilerTask task, CodegenInputs codegen,
-      SourceInformationStrategy sourceInformationStrategy) {
+  SsaBuilder createSsaBuilder(
+      CompilerTask task, SourceInformationStrategy sourceInformationStrategy) {
     return new KernelSsaBuilder(
         task,
         _compiler.options,
@@ -106,19 +107,21 @@
         _compiler.dumpInfoTask,
         // ignore:deprecated_member_use_from_same_package
         elementMap,
-        codegen.namer,
-        codegen.emitter,
-        codegen.tracer,
         sourceInformationStrategy);
   }
 
   @override
-  WorkItemBuilder createCodegenWorkItemBuilder(
-      JClosedWorld closedWorld,
-      GlobalTypeInferenceResults globalInferenceResults,
-      CodegenInputs codegen) {
+  WorkItemBuilder createCodegenWorkItemBuilder(JClosedWorld closedWorld) {
+    assert(_elementMap != null,
+        "JsBackendStrategy.elementMap has not been created yet.");
     return new KernelCodegenWorkItemBuilder(
-        _compiler.backend, closedWorld, globalInferenceResults, codegen);
+        _compiler.backend,
+        closedWorld,
+        new ClosedEntityLookup(_elementMap),
+        // TODO(johnniwinther): Avoid the need for a [ComponentLookup]. This
+        // is caused by some type masks holding a kernel node for using in
+        // tracing.
+        new ComponentLookup(_elementMap.programEnv.mainComponent));
   }
 
   @override
@@ -145,39 +148,35 @@
 class KernelCodegenWorkItemBuilder implements WorkItemBuilder {
   final JavaScriptBackend _backend;
   final JClosedWorld _closedWorld;
-  final GlobalTypeInferenceResults _globalInferenceResults;
-  final CodegenInputs _codegen;
+  final EntityLookup _entityLookup;
+  final ComponentLookup _componentLookup;
 
   KernelCodegenWorkItemBuilder(this._backend, this._closedWorld,
-      this._globalInferenceResults, this._codegen);
+      this._entityLookup, this._componentLookup);
 
   @override
-  CodegenWorkItem createWorkItem(MemberEntity entity) {
+  WorkItem createWorkItem(MemberEntity entity) {
     if (entity.isAbstract) return null;
     return new KernelCodegenWorkItem(
-        _backend, _closedWorld, _globalInferenceResults, _codegen, entity);
+        _backend, _closedWorld, _entityLookup, _componentLookup, entity);
   }
 }
 
-class KernelCodegenWorkItem extends CodegenWorkItem {
+class KernelCodegenWorkItem extends WorkItem {
   final JavaScriptBackend _backend;
   final JClosedWorld _closedWorld;
+  final EntityLookup _entityLookup;
+  final ComponentLookup _componentLookup;
   @override
   final MemberEntity element;
-  @override
-  final CodegenRegistry registry;
-  final GlobalTypeInferenceResults _globalInferenceResults;
-  final CodegenInputs _codegen;
 
-  KernelCodegenWorkItem(this._backend, this._closedWorld,
-      this._globalInferenceResults, this._codegen, this.element)
-      : registry =
-            new CodegenRegistry(_closedWorld.elementEnvironment, element);
+  KernelCodegenWorkItem(this._backend, this._closedWorld, this._entityLookup,
+      this._componentLookup, this.element);
 
   @override
   WorldImpact run() {
     return _backend.generateCode(
-        this, _closedWorld, _globalInferenceResults, _codegen);
+        this, _closedWorld, _entityLookup, _componentLookup);
   }
 }
 
@@ -188,44 +187,40 @@
   final DiagnosticReporter _reporter;
   final DumpInfoTask _dumpInfoTask;
   final JsToElementMap _elementMap;
-  final Namer _namer;
-  final Emitter _emitter;
-  final Tracer _tracer;
   final SourceInformationStrategy _sourceInformationStrategy;
 
   // TODO(johnniwinther,sra): Inlining decisions should not be based on the
   // order in which ssa graphs are built.
   FunctionInlineCache _inlineCache;
 
-  KernelSsaBuilder(
-      this._task,
-      this._options,
-      this._reporter,
-      this._dumpInfoTask,
-      this._elementMap,
-      this._namer,
-      this._emitter,
-      this._tracer,
-      this._sourceInformationStrategy);
+  KernelSsaBuilder(this._task, this._options, this._reporter,
+      this._dumpInfoTask, this._elementMap, this._sourceInformationStrategy);
 
   @override
-  HGraph build(CodegenWorkItem work, JClosedWorld closedWorld,
-      GlobalTypeInferenceResults results) {
+  HGraph build(
+      MemberEntity member,
+      JClosedWorld closedWorld,
+      GlobalTypeInferenceResults results,
+      CodegenInputs codegen,
+      CodegenRegistry registry,
+      ModularNamer namer,
+      ModularEmitter emitter) {
     _inlineCache ??= new FunctionInlineCache(closedWorld.annotationsData);
     return _task.measure(() {
       KernelSsaGraphBuilder builder = new KernelSsaGraphBuilder(
           _options,
           _reporter,
-          work.element,
-          _elementMap.getMemberThisType(work.element),
+          member,
+          _elementMap.getMemberThisType(member),
           _dumpInfoTask,
           _elementMap,
           results,
           closedWorld,
-          work.registry,
-          _namer,
-          _emitter,
-          _tracer,
+          registry,
+          namer,
+          emitter,
+          codegen.tracer,
+          codegen.rtiEncoder,
           _sourceInformationStrategy,
           _inlineCache);
       return builder.build();
diff --git a/pkg/compiler/lib/src/js_model/js_world_builder.dart b/pkg/compiler/lib/src/js_model/js_world_builder.dart
index 1a9544f..b3a59d2 100644
--- a/pkg/compiler/lib/src/js_model/js_world_builder.dart
+++ b/pkg/compiler/lib/src/js_model/js_world_builder.dart
@@ -846,7 +846,10 @@
   @override
   ConstantValue visitString(StringConstantValue constant, _) => constant;
   @override
-  ConstantValue visitSynthetic(SyntheticConstantValue constant, _) => constant;
+  ConstantValue visitAbstractValue(AbstractValueConstantValue constant, _) =>
+      constant;
+  @override
+  ConstantValue visitJsName(JsNameConstantValue constant, _) => constant;
   @override
   ConstantValue visitNonConstant(NonConstantValue constant, _) => constant;
 
diff --git a/pkg/compiler/lib/src/kernel/kernel_impact.dart b/pkg/compiler/lib/src/kernel/kernel_impact.dart
index 6041116..5415e98 100644
--- a/pkg/compiler/lib/src/kernel/kernel_impact.dart
+++ b/pkg/compiler/lib/src/kernel/kernel_impact.dart
@@ -466,7 +466,7 @@
     Selector selector = new Selector.callClosure(
         0, const <String>[], thisType.typeArguments.length);
     impactBuilder.registerDynamicUse(
-        new ConstrainedDynamicUse(selector, null, thisType.typeArguments));
+        new DynamicUse(selector, null, thisType.typeArguments));
   }
 
   @override
@@ -564,8 +564,8 @@
     // TODO(johnniwinther): Yet, alas, we need the dynamic use for now. Remove
     // this when kernel adds an `isFunctionCall` flag to
     // [ir.MethodInvocation].
-    impactBuilder.registerDynamicUse(new ConstrainedDynamicUse(
-        callStructure.callSelector, null, dartTypeArguments));
+    impactBuilder.registerDynamicUse(
+        new DynamicUse(callStructure.callSelector, null, dartTypeArguments));
   }
 
   @override
@@ -579,7 +579,7 @@
     Selector selector = elementMap.getInvocationSelector(
         name, positionalArguments, namedArguments, typeArguments.length);
     List<DartType> dartTypeArguments = _getTypeArguments(typeArguments);
-    impactBuilder.registerDynamicUse(new ConstrainedDynamicUse(selector,
+    impactBuilder.registerDynamicUse(new DynamicUse(selector,
         _computeReceiverConstraint(receiverType, relation), dartTypeArguments));
   }
 
@@ -594,7 +594,7 @@
         namedArguments,
         typeArguments.length);
     List<DartType> dartTypeArguments = _getTypeArguments(typeArguments);
-    impactBuilder.registerDynamicUse(new ConstrainedDynamicUse(
+    impactBuilder.registerDynamicUse(new DynamicUse(
         callStructure.callSelector,
         _computeReceiverConstraint(receiverType, ClassRelation.subtype),
         dartTypeArguments));
@@ -609,7 +609,7 @@
       List<String> namedArguments,
       List<ir.DartType> typeArguments) {
     List<DartType> dartTypeArguments = _getTypeArguments(typeArguments);
-    impactBuilder.registerDynamicUse(new ConstrainedDynamicUse(
+    impactBuilder.registerDynamicUse(new DynamicUse(
         elementMap.getInvocationSelector(target.name, positionalArguments,
             namedArguments, typeArguments.length),
         _computeReceiverConstraint(receiverType, relation),
@@ -619,7 +619,7 @@
   @override
   void registerDynamicGet(
       ir.DartType receiverType, ClassRelation relation, ir.Name name) {
-    impactBuilder.registerDynamicUse(new ConstrainedDynamicUse(
+    impactBuilder.registerDynamicUse(new DynamicUse(
         new Selector.getter(elementMap.getName(name)),
         _computeReceiverConstraint(receiverType, relation),
         const <DartType>[]));
@@ -628,7 +628,7 @@
   @override
   void registerInstanceGet(
       ir.DartType receiverType, ClassRelation relation, ir.Member target) {
-    impactBuilder.registerDynamicUse(new ConstrainedDynamicUse(
+    impactBuilder.registerDynamicUse(new DynamicUse(
         new Selector.getter(elementMap.getName(target.name)),
         _computeReceiverConstraint(receiverType, relation),
         const <DartType>[]));
@@ -637,7 +637,7 @@
   @override
   void registerDynamicSet(
       ir.DartType receiverType, ClassRelation relation, ir.Name name) {
-    impactBuilder.registerDynamicUse(new ConstrainedDynamicUse(
+    impactBuilder.registerDynamicUse(new DynamicUse(
         new Selector.setter(elementMap.getName(name)),
         _computeReceiverConstraint(receiverType, relation),
         const <DartType>[]));
@@ -646,7 +646,7 @@
   @override
   void registerInstanceSet(
       ir.DartType receiverType, ClassRelation relation, ir.Member target) {
-    impactBuilder.registerDynamicUse(new ConstrainedDynamicUse(
+    impactBuilder.registerDynamicUse(new DynamicUse(
         new Selector.setter(elementMap.getName(target.name)),
         _computeReceiverConstraint(receiverType, relation),
         const <DartType>[]));
@@ -744,12 +744,12 @@
     Object receiverConstraint =
         _computeReceiverConstraint(iteratorType, iteratorClassRelation);
     impactBuilder.registerFeature(Feature.SYNC_FOR_IN);
-    impactBuilder.registerDynamicUse(new ConstrainedDynamicUse(
-        Selectors.iterator, receiverConstraint, const []));
-    impactBuilder.registerDynamicUse(new ConstrainedDynamicUse(
-        Selectors.current, receiverConstraint, const []));
-    impactBuilder.registerDynamicUse(new ConstrainedDynamicUse(
-        Selectors.moveNext, receiverConstraint, const []));
+    impactBuilder.registerDynamicUse(
+        new DynamicUse(Selectors.iterator, receiverConstraint, const []));
+    impactBuilder.registerDynamicUse(
+        new DynamicUse(Selectors.current, receiverConstraint, const []));
+    impactBuilder.registerDynamicUse(
+        new DynamicUse(Selectors.moveNext, receiverConstraint, const []));
   }
 
   @override
@@ -758,12 +758,12 @@
     Object receiverConstraint =
         _computeReceiverConstraint(iteratorType, iteratorClassRelation);
     impactBuilder.registerFeature(Feature.ASYNC_FOR_IN);
-    impactBuilder.registerDynamicUse(new ConstrainedDynamicUse(
-        Selectors.cancel, receiverConstraint, const []));
-    impactBuilder.registerDynamicUse(new ConstrainedDynamicUse(
-        Selectors.current, receiverConstraint, const []));
-    impactBuilder.registerDynamicUse(new ConstrainedDynamicUse(
-        Selectors.moveNext, receiverConstraint, const []));
+    impactBuilder.registerDynamicUse(
+        new DynamicUse(Selectors.cancel, receiverConstraint, const []));
+    impactBuilder.registerDynamicUse(
+        new DynamicUse(Selectors.current, receiverConstraint, const []));
+    impactBuilder.registerDynamicUse(
+        new DynamicUse(Selectors.moveNext, receiverConstraint, const []));
   }
 
   @override
diff --git a/pkg/compiler/lib/src/serialization/abstract_sink.dart b/pkg/compiler/lib/src/serialization/abstract_sink.dart
index dfe4e9b..ac9d487 100644
--- a/pkg/compiler/lib/src/serialization/abstract_sink.dart
+++ b/pkg/compiler/lib/src/serialization/abstract_sink.dart
@@ -34,6 +34,8 @@
 
   Map<Type, IndexedSink> _generalCaches = {};
 
+  CodegenWriter _codegenWriter;
+
   AbstractDataSink({this.useDataKinds: false}) {
     _dartTypeWriter = new DartTypeWriter(this);
     _dartTypeNodeWriter = new DartTypeNodeWriter(this);
@@ -439,12 +441,23 @@
         break;
       case ConstantValueKind.NON_CONSTANT:
         break;
-      case ConstantValueKind.DEFERRED_GLOBAL:
       case ConstantValueKind.INTERCEPTOR:
-      case ConstantValueKind.SYNTHETIC:
-        // These are only created in the SSA graph builder.
-        throw new UnsupportedError(
-            "Unsupported constant value kind ${value.kind}.");
+        InterceptorConstantValue constant = value;
+        writeClass(constant.cls);
+        break;
+      case ConstantValueKind.DEFERRED_GLOBAL:
+        DeferredGlobalConstantValue constant = value;
+        writeConstant(constant.referenced);
+        writeOutputUnitReference(constant.unit);
+        break;
+      case ConstantValueKind.ABSTRACT_VALUE:
+        AbstractValueConstantValue constant = value;
+        writeAbstractValue(constant.abstractValue);
+        break;
+      case ConstantValueKind.JS_NAME:
+        JsNameConstantValue constant = value;
+        writeJsNode(constant.name);
+        break;
     }
   }
 
@@ -474,6 +487,36 @@
     _writeBool(value.isDeferred);
   }
 
+  @override
+  void registerCodegenWriter(CodegenWriter writer) {
+    assert(writer != null);
+    assert(_codegenWriter == null);
+    _codegenWriter = writer;
+  }
+
+  @override
+  void writeOutputUnitReference(OutputUnit value) {
+    assert(
+        _codegenWriter != null,
+        "Can not serialize an OutputUnit reference "
+        "without a registered codegen writer.");
+    _codegenWriter.writeOutputUnitReference(this, value);
+  }
+
+  @override
+  void writeAbstractValue(AbstractValue value) {
+    assert(_codegenWriter != null,
+        "Can not serialize an AbstractValue without a registered codegen writer.");
+    _codegenWriter.writeAbstractValue(this, value);
+  }
+
+  @override
+  void writeJsNode(js.Node value) {
+    assert(_codegenWriter != null,
+        "Can not serialize a JS ndoe without a registered codegen writer.");
+    _codegenWriter.writeJsNode(this, value);
+  }
+
   /// Actual serialization of a section begin tag, implemented by subclasses.
   void _begin(String tag);
 
diff --git a/pkg/compiler/lib/src/serialization/abstract_source.dart b/pkg/compiler/lib/src/serialization/abstract_source.dart
index f4160ce..87cb765 100644
--- a/pkg/compiler/lib/src/serialization/abstract_source.dart
+++ b/pkg/compiler/lib/src/serialization/abstract_source.dart
@@ -12,6 +12,7 @@
   ComponentLookup _componentLookup;
   EntityLookup _entityLookup;
   LocalLookup _localLookup;
+  CodegenReader _codegenReader;
 
   IndexedSource<String> _stringIndex;
   IndexedSource<Uri> _uriIndex;
@@ -71,6 +72,13 @@
   }
 
   @override
+  void registerCodegenReader(CodegenReader reader) {
+    assert(reader != null);
+    assert(_codegenReader == null);
+    _codegenReader = reader;
+  }
+
+  @override
   E readCached<E>(E f()) {
     IndexedSource source = _generalCaches[E] ??= new IndexedSource<E>(this);
     return source.read(f);
@@ -495,11 +503,19 @@
         return new InstantiationConstantValue(typeArguments, function);
       case ConstantValueKind.NON_CONSTANT:
         return new NonConstantValue();
-      case ConstantValueKind.DEFERRED_GLOBAL:
       case ConstantValueKind.INTERCEPTOR:
-      case ConstantValueKind.SYNTHETIC:
-        // These are only created in the SSA graph builder.
-        throw new UnsupportedError("Unsupported constant value kind ${kind}.");
+        ClassEntity cls = readClass();
+        return new InterceptorConstantValue(cls);
+      case ConstantValueKind.DEFERRED_GLOBAL:
+        ConstantValue constant = readConstant();
+        OutputUnit unit = readOutputUnitReference();
+        return new DeferredGlobalConstantValue(constant, unit);
+      case ConstantValueKind.ABSTRACT_VALUE:
+        AbstractValue abstractValue = readAbstractValue();
+        return new AbstractValueConstantValue(abstractValue);
+      case ConstantValueKind.JS_NAME:
+        js.LiteralString name = readJsNode();
+        return new JsNameConstantValue(name);
     }
     throw new UnsupportedError("Unexpexted constant value kind ${kind}.");
   }
@@ -626,6 +642,31 @@
     return new ImportEntity(isDeferred, name, uri, enclosingLibraryUri);
   }
 
+  @override
+  OutputUnit readOutputUnitReference() {
+    assert(
+        _codegenReader != null,
+        "Can not deserialize an OutputUnit reference "
+        "without a registered codegen reader.");
+    return _codegenReader.readOutputUnitReference(this);
+  }
+
+  @override
+  AbstractValue readAbstractValue() {
+    assert(
+        _codegenReader != null,
+        "Can not deserialize an AbstractValue "
+        "without a registered codegen reader.");
+    return _codegenReader.readAbstractValue(this);
+  }
+
+  @override
+  js.Node readJsNode() {
+    assert(_codegenReader != null,
+        "Can not deserialize a JS node without a registered codegen reader.");
+    return _codegenReader.readJsNode(this);
+  }
+
   /// Actual deserialization of a section begin tag, implemented by subclasses.
   void _begin(String tag);
 
diff --git a/pkg/compiler/lib/src/serialization/mixins.dart b/pkg/compiler/lib/src/serialization/mixins.dart
index 695d112..2de3e8a 100644
--- a/pkg/compiler/lib/src/serialization/mixins.dart
+++ b/pkg/compiler/lib/src/serialization/mixins.dart
@@ -314,6 +314,15 @@
   }
 
   @override
+  ImportEntity readImportOrNull() {
+    bool hasClass = readBool();
+    if (hasClass) {
+      return readImport();
+    }
+    return null;
+  }
+
+  @override
   List<ImportEntity> readImports({bool emptyAsNull: false}) {
     int count = readInt();
     if (count == 0 && emptyAsNull) return null;
@@ -366,6 +375,15 @@
   ir.LibraryDependency readLibraryDependencyNodeOrNull() {
     return readValueOrNull(readLibraryDependencyNode);
   }
+
+  @override
+  js.Node readJsNodeOrNull() {
+    bool hasValue = readBool();
+    if (hasValue) {
+      return readJsNode();
+    }
+    return null;
+  }
 }
 
 /// Mixin that implements all convenience methods of [DataSink].
@@ -693,6 +711,14 @@
   }
 
   @override
+  void writeImportOrNull(ImportEntity value) {
+    writeBool(value != null);
+    if (value != null) {
+      writeImport(value);
+    }
+  }
+
+  @override
   void writeImports(Iterable<ImportEntity> values, {bool allowNull: false}) {
     if (values == null) {
       assert(allowNull);
@@ -751,4 +777,12 @@
   void writeLibraryDependencyNodeOrNull(ir.LibraryDependency value) {
     writeValueOrNull(value, writeLibraryDependencyNode);
   }
+
+  @override
+  void writeJsNodeOrNull(js.Node value) {
+    writeBool(value != null);
+    if (value != null) {
+      writeJsNode(value);
+    }
+  }
 }
diff --git a/pkg/compiler/lib/src/serialization/serialization.dart b/pkg/compiler/lib/src/serialization/serialization.dart
index 8623f87..d4f574c 100644
--- a/pkg/compiler/lib/src/serialization/serialization.dart
+++ b/pkg/compiler/lib/src/serialization/serialization.dart
@@ -11,12 +11,15 @@
 import '../closure.dart';
 import '../constants/constant_system.dart' as constant_system;
 import '../constants/values.dart';
+import '../deferred_load.dart';
 import '../diagnostics/source_span.dart';
 import '../elements/entities.dart';
 import '../elements/indexed.dart';
 import '../elements/types.dart';
+import '../inferrer/abstract_value_domain.dart';
 import '../ir/constants.dart';
 import '../ir/static_type_base.dart';
+import '../js/js.dart' as js;
 import '../js_model/closure.dart';
 import '../js_model/locals.dart';
 
@@ -357,6 +360,9 @@
   /// Writes the import [value] to this data sink.
   void writeImport(ImportEntity value);
 
+  /// Writes the potentially `null` import [value] to this data sink.
+  void writeImportOrNull(ImportEntity value);
+
   /// Writes import [values] to this data sink. If [allowNull] is `true`,
   /// [values] is allowed to be `null`.
   ///
@@ -372,6 +378,30 @@
   /// [DataSource.readImportMap].
   void writeImportMap<V>(Map<ImportEntity, V> map, void f(V value),
       {bool allowNull: false});
+
+  /// Writes an abstract [value] to this data sink.
+  ///
+  /// This feature is only available a [CodegenWriter] has been registered.
+  void writeAbstractValue(AbstractValue value);
+
+  /// Writes a reference to the output unit [value] to this data sink.
+  ///
+  /// This feature is only available a [CodegenWriter] has been registered.
+  void writeOutputUnitReference(OutputUnit value);
+
+  /// Writes a js node [value] to this data sink.
+  ///
+  /// This feature is only available a [CodegenWriter] has been registered.
+  void writeJsNode(js.Node value);
+
+  /// Writes a potentially `null` js node [value] to this data sink.
+  ///
+  /// This feature is only available a [CodegenWriter] has been registered.
+  void writeJsNodeOrNull(js.Node value);
+
+  /// Register a [CodegenWriter] with this data sink to support serialization
+  /// of codegen only data.
+  void registerCodegenWriter(CodegenWriter writer);
 }
 
 /// Interface for deserialization.
@@ -400,6 +430,10 @@
   /// deserialization of references to locals.
   void registerLocalLookup(LocalLookup localLookup);
 
+  /// Registers a [CodegenReader] with this data source to support
+  /// deserialization of codegen only data.
+  void registerCodegenReader(CodegenReader read);
+
   /// Reads a reference to an [E] value from this data source. If the value has
   /// not yet been deserialized, [f] is called to deserialize the value itself.
   E readCached<E>(E f());
@@ -680,6 +714,9 @@
   /// Reads a import from this data source.
   ImportEntity readImport();
 
+  /// Reads a potentially `null` import from this data source.
+  ImportEntity readImportOrNull();
+
   /// Reads a list of imports from this data source. If [emptyAsNull] is
   /// `true`, `null` is returned instead of an empty list.
   ///
@@ -694,6 +731,26 @@
   /// This is a convenience method to be used together with
   /// [DataSink.writeImportMap].
   Map<ImportEntity, V> readImportMap<V>(V f(), {bool emptyAsNull: false});
+
+  /// Reads an [AbstractValue] from this data source.
+  ///
+  /// This feature is only available a [CodegenReader] has been registered.
+  AbstractValue readAbstractValue();
+
+  /// Reads a reference to an [OutputUnit] from this data source.
+  ///
+  /// This feature is only available a [CodegenReader] has been registered.
+  OutputUnit readOutputUnitReference();
+
+  /// Reads a [js.Node] value from this data source.
+  ///
+  /// This feature is only available a [CodegenReader] has been registered.
+  js.Node readJsNode();
+
+  /// Reads a potentially `null` [js.Node] value from this data source.
+  ///
+  /// This feature is only available a [CodegenReader] has been registered.
+  js.Node readJsNodeOrNull();
 }
 
 /// Interface used for looking up entities by index during deserialization.
@@ -718,3 +775,17 @@
 abstract class LocalLookup {
   Local getLocalByIndex(MemberEntity memberContext, int index);
 }
+
+/// Interface used for reading codegen only data during deserialization.
+abstract class CodegenReader {
+  AbstractValue readAbstractValue(DataSource source);
+  OutputUnit readOutputUnitReference(DataSource source);
+  js.Node readJsNode(DataSource source);
+}
+
+/// Interface used for writing codegen only data during serialization.
+abstract class CodegenWriter {
+  void writeAbstractValue(DataSink sink, AbstractValue value);
+  void writeOutputUnitReference(DataSink sink, OutputUnit value);
+  void writeJsNode(DataSink sink, js.Node node);
+}
diff --git a/pkg/compiler/lib/src/ssa/builder_kernel.dart b/pkg/compiler/lib/src/ssa/builder_kernel.dart
index 2f3ace7a..67cc980 100644
--- a/pkg/compiler/lib/src/ssa/builder_kernel.dart
+++ b/pkg/compiler/lib/src/ssa/builder_kernel.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:js_runtime/shared/embedded_names.dart';
 import 'package:kernel/ast.dart' as ir;
 
 import '../closure.dart';
@@ -10,12 +11,7 @@
 import '../common/names.dart';
 import '../common_elements.dart';
 import '../constants/constant_system.dart' as constant_system;
-import '../constants/values.dart'
-    show
-        ConstantValue,
-        InterceptorConstantValue,
-        StringConstantValue,
-        TypeConstantValue;
+import '../constants/values.dart';
 import '../dump_info.dart';
 import '../elements/entities.dart';
 import '../elements/jumps.dart';
@@ -33,10 +29,10 @@
     show FieldAnalysisData, JFieldAnalysis;
 import '../js_backend/interceptor_data.dart';
 import '../js_backend/inferred_data.dart';
-import '../js_backend/namer.dart';
+import '../js_backend/namer.dart' show ModularNamer;
 import '../js_backend/native_data.dart';
 import '../js_backend/runtime_types.dart';
-import '../js_emitter/code_emitter_task.dart';
+import '../js_emitter/code_emitter_task.dart' show ModularEmitter;
 import '../js_model/locals.dart' show JumpVisitor;
 import '../js_model/elements.dart' show JGeneratorBody;
 import '../js_model/element_map.dart';
@@ -113,14 +109,15 @@
 
   final CompilerOptions options;
   final DiagnosticReporter reporter;
-  final Emitter _emitter;
-  final Namer _namer;
+  final ModularEmitter _emitter;
+  final ModularNamer _namer;
   final MemberEntity targetElement;
   final MemberEntity _initialTargetElement;
   final JClosedWorld closedWorld;
   final CodegenRegistry registry;
   final ClosureData _closureDataLookup;
   final Tracer _tracer;
+  final RuntimeTypesEncoder _rtiEncoder;
 
   /// A stack of [InterfaceType]s that have been seen during inlining of
   /// factory constructors.  These types are preserved in [HInvokeStatic]s and
@@ -168,6 +165,7 @@
       this._namer,
       this._emitter,
       this._tracer,
+      this._rtiEncoder,
       this._sourceInformationStrategy,
       this._inlineCache)
       : this.targetElement = _effectiveTargetElementFor(_initialTargetElement),
@@ -452,7 +450,7 @@
                 closedWorld.fieldAnalysis.getFieldData(targetElement);
 
             if (fieldData.initialValue != null) {
-              registry.worldImpact.registerConstantUse(
+              registry.registerConstantUse(
                   new ConstantUse.init(fieldData.initialValue));
               if (targetElement.isStatic || targetElement.isTopLevel) {
                 /// No code is created for this field: All references inline the
@@ -462,7 +460,7 @@
             } else if (fieldData.isLazy) {
               // The generated initializer needs be wrapped in the cyclic-error
               // helper.
-              registry.worldImpact.registerStaticUse(new StaticUse.staticInvoke(
+              registry.registerStaticUse(new StaticUse.staticInvoke(
                   closedWorld.commonElements.cyclicThrowHelper,
                   CallStructure.ONE_ARG));
             }
@@ -4339,8 +4337,7 @@
     HInstruction instruction = pop();
 
     if (instruction is HConstant) {
-      js.Name name =
-          _elementMap.getNameForJsGetName(instruction.constant, _namer);
+      js.Name name = _getNameForJsGetName(instruction.constant, _namer);
       stack.add(graph.addConstantStringFromName(name, closedWorld));
       return;
     }
@@ -4353,6 +4350,29 @@
     stack.add(graph.addConstantNull(closedWorld));
   }
 
+  int _extractEnumIndexFromConstantValue(
+      ConstantValue constant, ClassEntity classElement) {
+    if (constant is ConstructedConstantValue) {
+      if (constant.type.element == classElement) {
+        assert(constant.fields.length == 1 || constant.fields.length == 2);
+        ConstantValue indexConstant = constant.fields.values.first;
+        if (indexConstant is IntConstantValue) {
+          return indexConstant.intValue.toInt();
+        }
+      }
+    }
+    return null;
+  }
+
+  /// Returns the [js.Name] for the `JsGetName` [constant] value.
+  js.Name _getNameForJsGetName(ConstantValue constant, ModularNamer namer) {
+    int index = _extractEnumIndexFromConstantValue(
+        constant, _commonElements.jsGetNameEnum);
+    if (index == null) return null;
+    return namer.getNameForJsGetName(
+        CURRENT_ELEMENT_SPANNABLE, JsGetName.values[index]);
+  }
+
   void _handleForeignJsEmbeddedGlobal(ir.StaticInvocation invocation) {
     if (_unexpectedForeignArguments(invocation,
         minPositional: 2, maxPositional: 2)) {
@@ -4393,8 +4413,7 @@
 
     js.Template template;
     if (instruction is HConstant) {
-      template =
-          _elementMap.getJsBuiltinTemplate(instruction.constant, _emitter);
+      template = _getJsBuiltinTemplate(instruction.constant, _emitter);
     }
     if (template == null) {
       reporter.reportErrorMessage(
@@ -4425,6 +4444,73 @@
         nativeBehavior: nativeBehavior));
   }
 
+  /// Returns the [js.Template] for the `JsBuiltin` [constant] value.
+  js.Template _getJsBuiltinTemplate(
+      ConstantValue constant, ModularEmitter emitter) {
+    int index = _extractEnumIndexFromConstantValue(
+        constant, _commonElements.jsBuiltinEnum);
+    if (index == null) return null;
+    return _templateForBuiltin(JsBuiltin.values[index]);
+  }
+
+  /// Returns the JS template for the given [builtin].
+  js.Template _templateForBuiltin(JsBuiltin builtin) {
+    switch (builtin) {
+      case JsBuiltin.dartObjectConstructor:
+        ClassEntity objectClass = closedWorld.commonElements.objectClass;
+        return js.js
+            .expressionTemplateYielding(_emitter.typeAccess(objectClass));
+
+      case JsBuiltin.isCheckPropertyToJsConstructorName:
+        int isPrefixLength = _namer.fixedNames.operatorIsPrefix.length;
+        return js.js.expressionTemplateFor('#.substring($isPrefixLength)');
+
+      case JsBuiltin.isFunctionType:
+        return _rtiEncoder.templateForIsFunctionType;
+
+      case JsBuiltin.isFutureOrType:
+        return _rtiEncoder.templateForIsFutureOrType;
+
+      case JsBuiltin.isVoidType:
+        return _rtiEncoder.templateForIsVoidType;
+
+      case JsBuiltin.isDynamicType:
+        return _rtiEncoder.templateForIsDynamicType;
+
+      case JsBuiltin.isJsInteropTypeArgument:
+        return _rtiEncoder.templateForIsJsInteropTypeArgument;
+
+      case JsBuiltin.rawRtiToJsConstructorName:
+        return js.js.expressionTemplateFor("#.name");
+
+      case JsBuiltin.rawRuntimeType:
+        return js.js.expressionTemplateFor("#.constructor");
+
+      case JsBuiltin.isSubtype:
+        // TODO(floitsch): move this closer to where is-check properties are
+        // built.
+        String isPrefix = _namer.fixedNames.operatorIsPrefix;
+        return js.js.expressionTemplateFor("('$isPrefix' + #) in #.prototype");
+
+      case JsBuiltin.isGivenTypeRti:
+        return js.js.expressionTemplateFor('#.name === #');
+
+      case JsBuiltin.getMetadata:
+        String metadataAccess =
+            _emitter.generateEmbeddedGlobalAccessString(METADATA);
+        return js.js.expressionTemplateFor("$metadataAccess[#]");
+
+      case JsBuiltin.getType:
+        String typesAccess = _emitter.generateEmbeddedGlobalAccessString(TYPES);
+        return js.js.expressionTemplateFor("$typesAccess[#]");
+
+      default:
+        reporter.internalError(
+            NO_LOCATION_SPANNABLE, "Unhandled Builtin: $builtin");
+        return null;
+    }
+  }
+
   void _handleForeignJsGetFlag(ir.StaticInvocation invocation) {
     if (_unexpectedForeignArguments(invocation,
         minPositional: 1, maxPositional: 1)) {
@@ -4861,16 +4947,16 @@
     var arguments = <HInstruction>[];
     node.expression.accept(this);
     arguments.add(pop());
-    // TODO(johnniwinther): Use the static type of the expression.
+    StaticType expressionType = _getStaticType(node.expression);
     bool typeArgumentsNeeded = _rtiNeed.instantiationNeedsTypeArguments(
-        null, node.typeArguments.length);
+        expressionType.type, node.typeArguments.length);
     List<DartType> typeArguments = node.typeArguments
         .map((type) => typeArgumentsNeeded
             ? _elementMap.getDartType(type)
             : _commonElements.dynamicType)
         .toList();
     registry.registerGenericInstantiation(
-        new GenericInstantiation(null, typeArguments));
+        new GenericInstantiation(expressionType.type, typeArguments));
     // TODO(johnniwinther): Can we avoid creating the instantiation object?
     for (DartType type in typeArguments) {
       HInstruction instruction =
diff --git a/pkg/compiler/lib/src/ssa/codegen.dart b/pkg/compiler/lib/src/ssa/codegen.dart
index 6bfaa83..47d0de0 100644
--- a/pkg/compiler/lib/src/ssa/codegen.dart
+++ b/pkg/compiler/lib/src/ssa/codegen.dart
@@ -9,7 +9,7 @@
 
 import '../common.dart';
 import '../common/names.dart';
-import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem;
+import '../common/codegen.dart' show CodegenRegistry;
 import '../common/tasks.dart' show Measurer, CompilerTask;
 import '../constants/constant_system.dart' as constant_system;
 import '../constants/values.dart';
@@ -21,20 +21,19 @@
 import '../io/source_information.dart';
 import '../js/js.dart' as js;
 import '../js_backend/interceptor_data.dart';
-import '../js_backend/backend.dart';
+import '../js_backend/backend.dart' show CodegenInputs, SuperMemberData;
 import '../js_backend/checked_mode_helpers.dart';
 import '../js_backend/native_data.dart';
-import '../js_backend/namer.dart';
+import '../js_backend/namer.dart' show ModularNamer;
 import '../js_backend/runtime_types.dart';
-import '../js_emitter/code_emitter_task.dart';
+import '../js_emitter/code_emitter_task.dart' show ModularEmitter;
 import '../js_model/elements.dart' show JGeneratorBody;
 import '../native/behavior.dart';
 import '../options.dart';
 import '../tracer.dart';
 import '../universe/call_structure.dart' show CallStructure;
 import '../universe/selector.dart' show Selector;
-import '../universe/use.dart'
-    show ConstantUse, ConstrainedDynamicUse, StaticUse, TypeUse;
+import '../universe/use.dart' show ConstantUse, DynamicUse, StaticUse, TypeUse;
 import '../world.dart' show JClosedWorld;
 import 'codegen_helpers.dart';
 import 'nodes.dart';
@@ -68,74 +67,93 @@
     if (needsAsyncRewrite) {
       return finish(element.asyncMarker.isAsync
           ? (element.asyncMarker.isYielding
-              ? const js.AsyncModifier.asyncStar()
-              : const js.AsyncModifier.async())
+              ? js.AsyncModifier.asyncStar
+              : js.AsyncModifier.async)
           : (element.asyncMarker.isYielding
-              ? const js.AsyncModifier.syncStar()
-              : const js.AsyncModifier.sync()));
+              ? js.AsyncModifier.syncStar
+              : js.AsyncModifier.sync));
     } else {
-      return finish(const js.AsyncModifier.sync());
+      return finish(js.AsyncModifier.sync);
     }
   }
 
-  js.Expression generateCode(CodegenWorkItem work, HGraph graph,
-      CodegenInputs codegen, JClosedWorld closedWorld) {
-    if (work.element.isField) {
-      return generateLazyInitializer(work, graph, codegen, closedWorld);
+  js.Expression generateCode(
+      MemberEntity member,
+      HGraph graph,
+      CodegenInputs codegen,
+      JClosedWorld closedWorld,
+      CodegenRegistry registry,
+      ModularNamer namer,
+      ModularEmitter emitter) {
+    if (member.isField) {
+      return generateLazyInitializer(
+          member, graph, codegen, closedWorld, registry, namer, emitter);
     } else {
-      return generateMethod(work, graph, codegen, closedWorld);
+      return generateMethod(
+          member, graph, codegen, closedWorld, registry, namer, emitter);
     }
   }
 
-  js.Expression generateLazyInitializer(CodegenWorkItem work, HGraph graph,
-      CodegenInputs codegen, JClosedWorld closedWorld) {
+  js.Expression generateLazyInitializer(
+      FieldEntity field,
+      HGraph graph,
+      CodegenInputs codegen,
+      JClosedWorld closedWorld,
+      CodegenRegistry registry,
+      ModularNamer namer,
+      ModularEmitter emitter) {
     return measure(() {
       codegen.tracer.traceGraph("codegen", graph);
       SourceInformation sourceInformation = sourceInformationStrategy
-          .createBuilderForContext(work.element)
-          .buildDeclaration(work.element);
+          .createBuilderForContext(field)
+          .buildDeclaration(field);
       SsaCodeGenerator codeGenerator = new SsaCodeGenerator(
           this,
           _options,
-          codegen.emitter,
+          emitter,
           codegen.checkedModeHelpers,
           codegen.oneShotInterceptorData,
           codegen.rtiSubstitutions,
           codegen.rtiEncoder,
-          codegen.namer,
+          namer,
           codegen.superMemberData,
           codegen.tracer,
           closedWorld,
-          work);
+          registry);
       codeGenerator.visitGraph(graph);
       return new js.Fun(codeGenerator.parameters, codeGenerator.body)
           .withSourceInformation(sourceInformation);
     });
   }
 
-  js.Expression generateMethod(CodegenWorkItem work, HGraph graph,
-      CodegenInputs codegen, JClosedWorld closedWorld) {
+  js.Expression generateMethod(
+      FunctionEntity method,
+      HGraph graph,
+      CodegenInputs codegen,
+      JClosedWorld closedWorld,
+      CodegenRegistry registry,
+      ModularNamer namer,
+      ModularEmitter emitter) {
     return measure(() {
-      FunctionEntity element = work.element;
-      if (element.asyncMarker != AsyncMarker.SYNC) {
-        work.registry.registerAsyncMarker(element.asyncMarker);
+      if (method.asyncMarker != AsyncMarker.SYNC) {
+        registry.registerAsyncMarker(method.asyncMarker);
       }
       SsaCodeGenerator codeGenerator = new SsaCodeGenerator(
           this,
           _options,
-          codegen.emitter,
+          emitter,
           codegen.checkedModeHelpers,
           codegen.oneShotInterceptorData,
           codegen.rtiSubstitutions,
           codegen.rtiEncoder,
-          codegen.namer,
+          namer,
           codegen.superMemberData,
           codegen.tracer,
           closedWorld,
-          work);
+          registry);
       codeGenerator.visitGraph(graph);
       codegen.tracer.traceGraph("codegen", graph);
-      return buildJavaScriptFunction(graph.needsAsyncRewrite, work.element,
+      return buildJavaScriptFunction(graph.needsAsyncRewrite, method,
           codeGenerator.parameters, codeGenerator.body);
     });
   }
@@ -162,16 +180,16 @@
 
   final CompilerTask _codegenTask;
   final CompilerOptions _options;
-  final Emitter _emitter;
+  final ModularEmitter _emitter;
   final CheckedModeHelpers _checkedModeHelpers;
   final OneShotInterceptorData _oneShotInterceptorData;
   final RuntimeTypesSubstitutions _rtiSubstitutions;
   final RuntimeTypesEncoder _rtiEncoder;
-  final Namer _namer;
+  final ModularNamer _namer;
   final SuperMemberData _superMemberData;
   final Tracer _tracer;
   final JClosedWorld _closedWorld;
-  final CodegenWorkItem _work;
+  final CodegenRegistry _registry;
 
   final Set<HInstruction> generateAtUseSite;
   final Set<HInstruction> controlFlowOperators;
@@ -227,7 +245,7 @@
       this._superMemberData,
       this._tracer,
       this._closedWorld,
-      this._work,
+      this._registry,
       {SourceInformation sourceInformation})
       : declaredLocals = new Set<String>(),
         collectedVariableDeclarations = new Set<String>(),
@@ -241,8 +259,6 @@
         continueAction = new Set<LabelDefinition>(),
         implicitContinueAction = new Set<JumpTarget>();
 
-  CodegenRegistry get _registry => _work.registry;
-
   JCommonElements get _commonElements => _closedWorld.commonElements;
 
   NativeData get _nativeData => _closedWorld.nativeData;
@@ -623,14 +639,15 @@
           op == '^' ||
           op == '&' ||
           op == '|') {
-        if (binary.left is js.VariableUse &&
-            (binary.left as js.VariableUse).name == variableName) {
+        js.Expression left = binary.left;
+        if (left is js.VariableUse && left.name == variableName) {
           // We know now, that we can shorten x = x + y into x += y.
           // Also check for the shortcut where y equals 1: x++ and x--.
+          js.Expression right = binary.right;
           if ((op == '+' || op == '-') &&
-              binary.right is js.LiteralNumber &&
-              (binary.right as js.LiteralNumber).value == "1") {
-            return new js.Prefix(op == '+' ? '++' : '--', binary.left);
+              right is js.LiteralNumber &&
+              right.value == "1") {
+            return new js.Prefix(op == '+' ? '++' : '--', left);
           }
           return new js.Assignment.compound(binary.left, op, binary.right);
         }
@@ -1811,8 +1828,8 @@
       assert(node.inputs.length == 1);
       _registry.registerSpecializedGetInterceptor(node.interceptedClasses);
       js.Name name = _namer.nameForGetInterceptor(node.interceptedClasses);
-      var isolate = new js.VariableUse(
-          _namer.globalObjectForLibrary(_commonElements.interceptorsLibrary));
+      js.Expression isolate = _namer
+          .readGlobalObjectForLibrary(_commonElements.interceptorsLibrary);
       use(node.receiver);
       List<js.Expression> arguments = <js.Expression>[pop()];
       push(js
@@ -1903,8 +1920,8 @@
   @override
   void visitOneShotInterceptor(HOneShotInterceptor node) {
     List<js.Expression> arguments = visitArguments(node.inputs);
-    var isolate = new js.VariableUse(
-        _namer.globalObjectForLibrary(_commonElements.interceptorsLibrary));
+    js.Expression isolate =
+        _namer.readGlobalObjectForLibrary(_commonElements.interceptorsLibrary);
     Selector selector = node.selector;
     js.Name methodName = _oneShotInterceptorData.registerOneShotInterceptor(
         selector, _namer, _closedWorld);
@@ -1964,8 +1981,8 @@
       // may know something about the types of closures that need
       // the specific closure call method.
       Selector call = new Selector.callClosureFrom(selector);
-      _registry.registerDynamicUse(
-          new ConstrainedDynamicUse(call, null, node.typeArguments));
+      _registry
+          .registerDynamicUse(new DynamicUse(call, null, node.typeArguments));
     }
     if (target != null) {
       // This is a dynamic invocation which we have found to have a single
@@ -1982,7 +1999,7 @@
       AbstractValue mask =
           getOptimizedSelectorFor(node, selector, node.receiverType);
       _registry.registerDynamicUse(
-          new ConstrainedDynamicUse(selector, mask, node.typeArguments));
+          new DynamicUse(selector, mask, node.typeArguments));
     }
   }
 
@@ -1998,7 +2015,7 @@
       AbstractValue mask =
           getOptimizedSelectorFor(node, selector, node.receiverType);
       _registry.registerDynamicUse(
-          new ConstrainedDynamicUse(selector, mask, node.typeArguments));
+          new DynamicUse(selector, mask, node.typeArguments));
     }
   }
 
@@ -2016,7 +2033,7 @@
       AbstractValue mask =
           getOptimizedSelectorFor(node, selector, node.receiverType);
       _registry.registerDynamicUse(
-          new ConstrainedDynamicUse(selector, mask, node.typeArguments));
+          new DynamicUse(selector, mask, node.typeArguments));
     }
   }
 
@@ -2051,8 +2068,8 @@
     // TODO(kasperl): If we have a typed selector for the call, we
     // may know something about the types of closures that need
     // the specific closure call method.
-    _registry.registerDynamicUse(
-        new ConstrainedDynamicUse(call, null, node.typeArguments));
+    _registry
+        .registerDynamicUse(new DynamicUse(call, null, node.typeArguments));
   }
 
   @override
@@ -2641,7 +2658,7 @@
     assert(element.isFunction || element.isField);
     if (element.isFunction) {
       push(_emitter
-          .isolateStaticClosureAccess(element)
+          .staticClosureAccess(element)
           .withSourceInformation(node.sourceInformation));
       _registry.registerStaticUse(new StaticUse.staticTearOff(element));
     } else {
diff --git a/pkg/compiler/lib/src/ssa/codegen_helpers.dart b/pkg/compiler/lib/src/ssa/codegen_helpers.dart
index c1ee6cb..bc388f2 100644
--- a/pkg/compiler/lib/src/ssa/codegen_helpers.dart
+++ b/pkg/compiler/lib/src/ssa/codegen_helpers.dart
@@ -5,7 +5,7 @@
 import '../constants/values.dart';
 import '../elements/entities.dart';
 import '../inferrer/abstract_value_domain.dart';
-import '../js_backend/js_backend.dart';
+import '../js_backend/js_backend.dart' show SuperMemberData;
 import '../js_backend/interceptor_data.dart';
 import '../options.dart';
 import '../universe/selector.dart' show Selector;
@@ -190,9 +190,8 @@
       if (_interceptorData.isInterceptedSelector(selector) &&
           !_interceptorData.isInterceptedMixinSelector(
               selector, mask, _closedWorld)) {
-        ConstantValue constant = new SyntheticConstantValue(
-            SyntheticConstantKind.DUMMY_INTERCEPTOR,
-            receiverArgument.instructionType);
+        ConstantValue constant =
+            new AbstractValueConstantValue(receiverArgument.instructionType);
         HConstant dummy = graph.addConstant(constant, _closedWorld);
         receiverArgument.usedBy.remove(node);
         node.inputs[1] = dummy;
diff --git a/pkg/compiler/lib/src/ssa/nodes.dart b/pkg/compiler/lib/src/ssa/nodes.dart
index 9e87a54..a893874 100644
--- a/pkg/compiler/lib/src/ssa/nodes.dart
+++ b/pkg/compiler/lib/src/ssa/nodes.dart
@@ -15,7 +15,6 @@
 import '../inferrer/abstract_value_domain.dart';
 import '../io/source_information.dart';
 import '../js/js.dart' as js;
-import '../js_backend/js_backend.dart';
 import '../native/behavior.dart';
 import '../universe/selector.dart' show Selector;
 import '../universe/side_effects.dart' show SideEffects;
@@ -313,9 +312,7 @@
 
   HConstant addConstantStringFromName(js.Name name, JClosedWorld closedWorld) {
     return addConstant(
-        new SyntheticConstantValue(
-            SyntheticConstantKind.NAME, js.quoteName(name)),
-        closedWorld);
+        new JsNameConstantValue(js.quoteName(name)), closedWorld);
   }
 
   HConstant addConstantBool(bool value, JClosedWorld closedWorld) {
@@ -330,7 +327,7 @@
     // A constant with an empty type used as the HInstruction of an expression
     // in an unreachable context.
     return addConstant(
-        new SyntheticConstantValue(SyntheticConstantKind.EMPTY_VALUE,
+        new AbstractValueConstantValue(
             closedWorld.abstractValueDomain.emptyType),
         closedWorld);
   }
diff --git a/pkg/compiler/lib/src/ssa/optimize.dart b/pkg/compiler/lib/src/ssa/optimize.dart
index 88f9b6c..91a06794f 100644
--- a/pkg/compiler/lib/src/ssa/optimize.dart
+++ b/pkg/compiler/lib/src/ssa/optimize.dart
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import '../common.dart';
-import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem;
+import '../common/codegen.dart' show CodegenRegistry;
 import '../common/names.dart' show Selectors;
 import '../common/tasks.dart' show Measurer, CompilerTask;
 import '../constants/constant_system.dart' as constant_system;
@@ -15,7 +15,7 @@
 import '../inferrer/types.dart';
 import '../js_backend/field_analysis.dart'
     show FieldAnalysisData, JFieldAnalysis;
-import '../js_backend/backend.dart';
+import '../js_backend/backend.dart' show CodegenInputs;
 import '../js_backend/native_data.dart' show NativeData;
 import '../js_backend/runtime_types.dart';
 import '../native/behavior.dart';
@@ -51,11 +51,12 @@
   String get name => 'SSA optimizer';
 
   void optimize(
-      CodegenWorkItem work,
+      MemberEntity member,
       HGraph graph,
       CodegenInputs codegen,
       JClosedWorld closedWorld,
-      GlobalTypeInferenceResults globalInferenceResults) {
+      GlobalTypeInferenceResults globalInferenceResults,
+      CodegenRegistry registry) {
     void runPhase(OptimizationPhase phase) {
       measureSubtask(phase.name, () => phase.visitGraph(graph));
       codegen.tracer.traceGraph(phase.name, graph);
@@ -63,7 +64,6 @@
     }
 
     bool trustPrimitives = _options.trustPrimitives;
-    CodegenRegistry registry = work.registry;
     Set<HInstruction> boundsChecked = new Set<HInstruction>();
     SsaCodeMotion codeMotion;
     SsaLoadElimination loadElimination;
@@ -71,7 +71,7 @@
     OptimizationTestLog log;
     if (retainDataForTesting) {
       loggersForTesting ??= {};
-      loggersForTesting[work.element] = log = new OptimizationTestLog();
+      loggersForTesting[member] = log = new OptimizationTestLog();
     }
 
     measure(() {
@@ -125,8 +125,7 @@
       // Simplifying interceptors is not strictly just an optimization, it is
       // required for implementation correctness because the code generator
       // assumes it is always performed.
-      runPhase(new SsaSimplifyInterceptors(
-          closedWorld, work.element.enclosingClass));
+      runPhase(new SsaSimplifyInterceptors(closedWorld, member.enclosingClass));
 
       SsaDeadCodeEliminator dce = new SsaDeadCodeEliminator(closedWorld, this);
       runPhase(dce);
@@ -142,7 +141,7 @@
           new SsaInstructionSimplifier(globalInferenceResults, _options,
               codegen.rtiSubstitutions, closedWorld, registry, log),
           new SsaCheckInserter(trustPrimitives, closedWorld, boundsChecked),
-          new SsaSimplifyInterceptors(closedWorld, work.element.enclosingClass),
+          new SsaSimplifyInterceptors(closedWorld, member.enclosingClass),
           new SsaDeadCodeEliminator(closedWorld, this),
         ];
       } else {
@@ -1956,8 +1955,8 @@
   HInstruction get zapInstruction {
     if (zapInstructionCache == null) {
       // A constant with no type does not pollute types at phi nodes.
-      ConstantValue constant = new SyntheticConstantValue(
-          SyntheticConstantKind.EMPTY_VALUE, _abstractValueDomain.emptyType);
+      ConstantValue constant =
+          new AbstractValueConstantValue(_abstractValueDomain.emptyType);
       zapInstructionCache = analyzer.graph.addConstant(constant, closedWorld);
     }
     return zapInstructionCache;
diff --git a/pkg/compiler/lib/src/ssa/ssa.dart b/pkg/compiler/lib/src/ssa/ssa.dart
index c6e963e..12f1db9 100644
--- a/pkg/compiler/lib/src/ssa/ssa.dart
+++ b/pkg/compiler/lib/src/ssa/ssa.dart
@@ -7,7 +7,7 @@
 import '../backend_strategy.dart';
 import '../common.dart';
 import '../common_elements.dart' show CommonElements, JElementEnvironment;
-import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem;
+import '../common/codegen.dart' show CodegenResult, CodegenRegistry;
 import '../common/tasks.dart' show CompilerTask, Measurer;
 import '../elements/entities.dart';
 import '../elements/types.dart';
@@ -16,6 +16,9 @@
 import '../js/js.dart' as js;
 import '../js/rewrite_async.dart';
 import '../js_backend/backend.dart' show CodegenInputs, FunctionCompiler;
+import '../js_backend/namer.dart' show ModularNamer, ModularNamerImpl;
+import '../js_emitter/code_emitter_task.dart' show ModularEmitter;
+import '../js_emitter/startup_emitter/emitter.dart' show ModularEmitterImpl;
 import '../js_model/elements.dart';
 import '../options.dart';
 import '../universe/call_structure.dart' show CallStructure;
@@ -27,59 +30,82 @@
 import 'optimize.dart';
 
 class SsaFunctionCompiler implements FunctionCompiler {
+  final CompilerOptions _options;
   final DiagnosticReporter _reporter;
   final SsaCodeGeneratorTask generator;
   final SsaBuilderTask _builder;
   final SsaOptimizerTask optimizer;
   final SourceInformationStrategy sourceInformationStrategy;
+  GlobalTypeInferenceResults _globalInferenceResults;
+  CodegenInputs _codegen;
 
   SsaFunctionCompiler(
-      CompilerOptions options,
+      this._options,
       this._reporter,
       BackendStrategy backendStrategy,
       Measurer measurer,
       this.sourceInformationStrategy)
       : generator = new SsaCodeGeneratorTask(
-            measurer, options, sourceInformationStrategy),
+            measurer, _options, sourceInformationStrategy),
         _builder = new SsaBuilderTask(
             measurer, backendStrategy, sourceInformationStrategy),
-        optimizer = new SsaOptimizerTask(measurer, options);
+        optimizer = new SsaOptimizerTask(measurer, _options);
 
   @override
-  void onCodegenStart(CodegenInputs codegen) {
-    _builder.onCodegenStart(codegen);
+  void initialize(GlobalTypeInferenceResults globalInferenceResults,
+      CodegenInputs codegen) {
+    _globalInferenceResults = globalInferenceResults;
+    _codegen = codegen;
+    _builder.onCodegenStart();
   }
 
-  /// Generates JavaScript code for `work.element`.
+  /// Generates JavaScript code for [member].
   /// Using the ssa builder, optimizer and code generator.
   @override
-  js.Fun compile(
-      CodegenWorkItem work,
-      CodegenInputs codegen,
-      JClosedWorld closedWorld,
-      GlobalTypeInferenceResults globalInferenceResults) {
-    HGraph graph = _builder.build(work, closedWorld, globalInferenceResults);
-    if (graph == null) return null;
-    optimizer.optimize(
-        work, graph, codegen, closedWorld, globalInferenceResults);
-    MemberEntity element = work.element;
-    js.Expression result =
-        generator.generateCode(work, graph, codegen, closedWorld);
+  CodegenResult compile(MemberEntity member) {
+    JClosedWorld closedWorld = _globalInferenceResults.closedWorld;
+    CodegenRegistry registry =
+        new CodegenRegistry(closedWorld.elementEnvironment, member);
+    ModularNamer namer = new ModularNamerImpl(registry,
+        closedWorld.commonElements, _codegen.rtiTags, _codegen.fixedNames);
+    ModularEmitter emitter = new ModularEmitterImpl(namer, registry, _options);
+    if (member.isConstructor &&
+        member.enclosingClass == closedWorld.commonElements.jsNullClass) {
+      // Work around a problem compiling JSNull's constructor.
+      return registry.close(null);
+    }
+
+    HGraph graph = _builder.build(member, closedWorld, _globalInferenceResults,
+        _codegen, registry, namer, emitter);
+    if (graph == null) {
+      return registry.close(null);
+    }
+    optimizer.optimize(member, graph, _codegen, closedWorld,
+        _globalInferenceResults, registry);
+    js.Expression result = generator.generateCode(
+        member, graph, _codegen, closedWorld, registry, namer, emitter);
     if (graph.needsAsyncRewrite) {
       SourceInformationBuilder sourceInformationBuilder =
-          sourceInformationStrategy.createBuilderForContext(element);
+          sourceInformationStrategy.createBuilderForContext(member);
       result = _rewriteAsync(
-          codegen,
+          _codegen,
           closedWorld.commonElements,
           closedWorld.elementEnvironment,
-          work.registry,
-          element,
+          registry,
+          namer,
+          emitter,
+          member,
           result,
           graph.asyncElementType,
           sourceInformationBuilder.buildAsyncBody(),
           sourceInformationBuilder.buildAsyncExit());
     }
-    return result;
+    if (result.sourceInformation == null) {
+      result = result.withSourceInformation(
+          sourceInformationStrategy.buildSourceMappedMarker());
+    }
+
+    return registry.close(result);
   }
 
   js.Expression _rewriteAsync(
@@ -87,6 +113,8 @@
       CommonElements commonElements,
       JElementEnvironment elementEnvironment,
       CodegenRegistry registry,
+      ModularNamer namer,
+      ModularEmitter emitter,
       FunctionEntity element,
       js.Expression code,
       DartType asyncTypeParameter,
@@ -95,7 +123,7 @@
     if (element.asyncMarker == AsyncMarker.SYNC) return code;
 
     AsyncRewriterBase rewriter = null;
-    js.Name name = codegen.namer.methodPropertyName(
+    js.Name name = namer.methodPropertyName(
         element is JGeneratorBody ? element.function : element);
 
     switch (element.asyncMarker) {
@@ -105,6 +133,8 @@
             commonElements,
             elementEnvironment,
             registry,
+            namer,
+            emitter,
             element,
             code,
             asyncTypeParameter,
@@ -112,18 +142,18 @@
         break;
       case AsyncMarker.SYNC_STAR:
         rewriter = new SyncStarRewriter(_reporter, element,
-            endOfIteration: codegen.emitter
-                .staticFunctionAccess(commonElements.endOfIteration),
-            iterableFactory: codegen.emitter
+            endOfIteration:
+                emitter.staticFunctionAccess(commonElements.endOfIteration),
+            iterableFactory: emitter
                 .staticFunctionAccess(commonElements.syncStarIterableFactory),
             iterableFactoryTypeArguments:
-                _fetchItemType(codegen, asyncTypeParameter),
+                _fetchItemType(codegen, emitter, asyncTypeParameter),
             yieldStarExpression:
-                codegen.emitter.staticFunctionAccess(commonElements.yieldStar),
-            uncaughtErrorExpression: codegen.emitter
+                emitter.staticFunctionAccess(commonElements.yieldStar),
+            uncaughtErrorExpression: emitter
                 .staticFunctionAccess(commonElements.syncStarUncaughtError),
-            safeVariableName: codegen.namer.safeVariablePrefixForAsyncRewrite,
-            bodyName: codegen.namer.deriveAsyncBodyName(name));
+            safeVariableName: namer.safeVariablePrefixForAsyncRewrite,
+            bodyName: namer.deriveAsyncBodyName(name));
         registry.registerStaticUse(new StaticUse.staticInvoke(
             commonElements.syncStarIterableFactory,
             const CallStructure.unnamed(1, 1), [
@@ -132,22 +162,21 @@
         break;
       case AsyncMarker.ASYNC_STAR:
         rewriter = new AsyncStarRewriter(_reporter, element,
-            asyncStarHelper: codegen.emitter
-                .staticFunctionAccess(commonElements.asyncStarHelper),
-            streamOfController: codegen.emitter
-                .staticFunctionAccess(commonElements.streamOfController),
-            wrapBody:
-                codegen.emitter.staticFunctionAccess(commonElements.wrapBody),
-            newController: codegen.emitter.staticFunctionAccess(
+            asyncStarHelper:
+                emitter.staticFunctionAccess(commonElements.asyncStarHelper),
+            streamOfController:
+                emitter.staticFunctionAccess(commonElements.streamOfController),
+            wrapBody: emitter.staticFunctionAccess(commonElements.wrapBody),
+            newController: emitter.staticFunctionAccess(
                 commonElements.asyncStarStreamControllerFactory),
             newControllerTypeArguments:
-                _fetchItemType(codegen, asyncTypeParameter),
-            safeVariableName: codegen.namer.safeVariablePrefixForAsyncRewrite,
-            yieldExpression: codegen.emitter
-                .staticFunctionAccess(commonElements.yieldSingle),
+                _fetchItemType(codegen, emitter, asyncTypeParameter),
+            safeVariableName: namer.safeVariablePrefixForAsyncRewrite,
+            yieldExpression:
+                emitter.staticFunctionAccess(commonElements.yieldSingle),
             yieldStarExpression:
-                codegen.emitter.staticFunctionAccess(commonElements.yieldStar),
-            bodyName: codegen.namer.deriveAsyncBodyName(name));
+                emitter.staticFunctionAccess(commonElements.yieldStar),
+            bodyName: namer.deriveAsyncBodyName(name));
         registry.registerStaticUse(new StaticUse.staticInvoke(
             commonElements.asyncStarStreamControllerFactory,
             const CallStructure.unnamed(1, 1), [
@@ -163,10 +192,10 @@
   /// added as a function parameter to the rewritten code.
   // TODO(sra): We could also return an empty list if the generator takes no
   // type (e.g. due to rtiNeed optimization).
-  List<js.Expression> _fetchItemType(CodegenInputs codegen, DartType type) {
+  List<js.Expression> _fetchItemType(
+      CodegenInputs codegen, ModularEmitter emitter, DartType type) {
     if (type == null) return null;
-    var ast =
-        codegen.rtiEncoder.getTypeRepresentation(codegen.emitter, type, null);
+    var ast = codegen.rtiEncoder.getTypeRepresentation(emitter, type, null);
     return <js.Expression>[ast];
   }
 
@@ -175,6 +204,8 @@
       CommonElements commonElements,
       JElementEnvironment elementEnvironment,
       CodegenRegistry registry,
+      ModularNamer namer,
+      ModularEmitter emitter,
       FunctionEntity element,
       js.Expression code,
       DartType elementType,
@@ -183,22 +214,21 @@
     FunctionEntity completerFactory = commonElements.asyncAwaitCompleterFactory;
 
     List<js.Expression> itemTypeExpression =
-        _fetchItemType(codegen, elementType);
+        _fetchItemType(codegen, emitter, elementType);
 
     AsyncRewriter rewriter = new AsyncRewriter(_reporter, element,
-        asyncStart: codegen.emitter.staticFunctionAccess(startFunction),
-        asyncAwait: codegen.emitter
-            .staticFunctionAccess(commonElements.asyncHelperAwait),
-        asyncReturn: codegen.emitter
-            .staticFunctionAccess(commonElements.asyncHelperReturn),
-        asyncRethrow: codegen.emitter
-            .staticFunctionAccess(commonElements.asyncHelperRethrow),
-        wrapBody: codegen.emitter.staticFunctionAccess(commonElements.wrapBody),
-        completerFactory:
-            codegen.emitter.staticFunctionAccess(completerFactory),
+        asyncStart: emitter.staticFunctionAccess(startFunction),
+        asyncAwait:
+            emitter.staticFunctionAccess(commonElements.asyncHelperAwait),
+        asyncReturn:
+            emitter.staticFunctionAccess(commonElements.asyncHelperReturn),
+        asyncRethrow:
+            emitter.staticFunctionAccess(commonElements.asyncHelperRethrow),
+        wrapBody: emitter.staticFunctionAccess(commonElements.wrapBody),
+        completerFactory: emitter.staticFunctionAccess(completerFactory),
         completerFactoryTypeArguments: itemTypeExpression,
-        safeVariableName: codegen.namer.safeVariablePrefixForAsyncRewrite,
-        bodyName: codegen.namer.deriveAsyncBodyName(name));
+        safeVariableName: namer.safeVariablePrefixForAsyncRewrite,
+        bodyName: namer.deriveAsyncBodyName(name));
 
     registry.registerStaticUse(new StaticUse.staticInvoke(
         completerFactory,
@@ -215,10 +245,16 @@
 }
 
 abstract class SsaBuilder {
-  /// Creates the [HGraph] for [work] or returns `null` if no code is needed
-  /// for [work].
-  HGraph build(CodegenWorkItem work, JClosedWorld closedWorld,
-      GlobalTypeInferenceResults globalInferenceResults);
+  /// Creates the [HGraph] for [member] or returns `null` if no code is needed
+  /// for [member].
+  HGraph build(
+      MemberEntity member,
+      JClosedWorld closedWorld,
+      GlobalTypeInferenceResults globalInferenceResults,
+      CodegenInputs codegen,
+      CodegenRegistry registry,
+      ModularNamer namer,
+      ModularEmitter emitter);
 }
 
 class SsaBuilderTask extends CompilerTask {
@@ -233,15 +269,22 @@
   @override
   String get name => 'SSA builder';
 
-  void onCodegenStart(CodegenInputs codegen) {
-    _builder = _backendStrategy.createSsaBuilder(
-        this, codegen, _sourceInformationFactory);
+  void onCodegenStart() {
+    _builder =
+        _backendStrategy.createSsaBuilder(this, _sourceInformationFactory);
   }
 
-  /// Creates the [HGraph] for [work] or returns `null` if no code is needed
-  /// for [work].
-  HGraph build(CodegenWorkItem work, JClosedWorld closedWorld,
-      GlobalTypeInferenceResults globalInferenceResults) {
-    return _builder.build(work, closedWorld, globalInferenceResults);
+  /// Creates the [HGraph] for [member] or returns `null` if no code is needed
+  /// for [member].
+  HGraph build(
+      MemberEntity member,
+      JClosedWorld closedWorld,
+      GlobalTypeInferenceResults globalInferenceResults,
+      CodegenInputs codegen,
+      CodegenRegistry registry,
+      ModularNamer namer,
+      ModularEmitter emitter) {
+    return _builder.build(member, closedWorld, globalInferenceResults, codegen,
+        registry, namer, emitter);
   }
 }
diff --git a/pkg/compiler/lib/src/ssa/ssa_tracer.dart b/pkg/compiler/lib/src/ssa/ssa_tracer.dart
index b4fe2d7..9a5b4ca 100644
--- a/pkg/compiler/lib/src/ssa/ssa_tracer.dart
+++ b/pkg/compiler/lib/src/ssa/ssa_tracer.dart
@@ -7,7 +7,7 @@
 import '../../compiler_new.dart' show OutputSink;
 import '../diagnostics/invariant.dart' show DEBUG_MODE;
 import '../inferrer/abstract_value_domain.dart';
-import '../js_backend/namer.dart' show Namer;
+import '../js_backend/namer.dart' show suffixForGetInterceptor;
 import '../tracer.dart';
 import '../world.dart' show JClosedWorld;
 import 'nodes.dart';
@@ -17,11 +17,10 @@
 /// to enable it.
 class HTracer extends HGraphVisitor with TracerUtil {
   final JClosedWorld closedWorld;
-  final Namer namer;
   @override
   final OutputSink output;
 
-  HTracer(this.output, this.closedWorld, this.namer);
+  HTracer(this.output, this.closedWorld);
 
   void traceGraph(String name, HGraph graph) {
     DEBUG_MODE = true;
@@ -76,7 +75,7 @@
   @override
   void visitBasicBlock(HBasicBlock block) {
     HInstructionStringifier stringifier =
-        new HInstructionStringifier(block, closedWorld, namer);
+        new HInstructionStringifier(block, closedWorld);
     assert(block.id != null);
     tag("block", () {
       printProperty("name", "B${block.id}");
@@ -114,10 +113,9 @@
 
 class HInstructionStringifier implements HVisitor<String> {
   final JClosedWorld closedWorld;
-  final Namer namer;
   final HBasicBlock currentBlock;
 
-  HInstructionStringifier(this.currentBlock, this.closedWorld, this.namer);
+  HInstructionStringifier(this.currentBlock, this.closedWorld);
 
   AbstractValueDomain get _abstractValueDomain =>
       closedWorld.abstractValueDomain;
@@ -356,8 +354,9 @@
   String visitInterceptor(HInterceptor node) {
     String value = temporaryId(node.inputs[0]);
     if (node.interceptedClasses != null) {
-      String cls = namer.suffixForGetInterceptor(node.interceptedClasses);
-      return "Interceptor ($cls): $value";
+      String cls = suffixForGetInterceptor(closedWorld.commonElements,
+          closedWorld.nativeData, node.interceptedClasses);
+      return "Interceptor (${cls}): $value";
     }
     return "Interceptor: $value";
   }
diff --git a/pkg/compiler/lib/src/ssa/switch_continue_analysis.dart b/pkg/compiler/lib/src/ssa/switch_continue_analysis.dart
index bebc7e6..1733898 100644
--- a/pkg/compiler/lib/src/ssa/switch_continue_analysis.dart
+++ b/pkg/compiler/lib/src/ssa/switch_continue_analysis.dart
@@ -1,3 +1,7 @@
+// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
 import 'package:kernel/ast.dart' as ir;
 
 /// Helper class that traverses a kernel AST subtree to see if it has any
diff --git a/pkg/compiler/lib/src/ssa/variable_allocator.dart b/pkg/compiler/lib/src/ssa/variable_allocator.dart
index a9f6e39..33f1006 100644
--- a/pkg/compiler/lib/src/ssa/variable_allocator.dart
+++ b/pkg/compiler/lib/src/ssa/variable_allocator.dart
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import '../common.dart';
-import '../js_backend/js_backend.dart';
+import '../js_backend/namer.dart' show ModularNamer;
 import 'codegen.dart' show CodegenPhase;
 import 'nodes.dart';
 
@@ -450,7 +450,7 @@
 /// Allocates variable names for instructions, making sure they don't collide.
 class VariableNamer {
   final VariableNames names;
-  final Namer _namer;
+  final ModularNamer _namer;
   final Set<String> usedNames;
   final List<String> freeTemporaryNames;
   int temporaryIndex = 0;
@@ -570,7 +570,7 @@
 /// instruction, and allocates a name to the instruction. For each phi,
 /// it adds a copy to the CopyHandler of the corresponding predecessor.
 class SsaVariableAllocator extends HBaseVisitor with CodegenPhase {
-  final Namer _namer;
+  final ModularNamer _namer;
   final Map<HBasicBlock, LiveEnvironment> liveInstructions;
   final Map<HInstruction, LiveInterval> liveIntervals;
   final Set<HInstruction> generateAtUseSite;
diff --git a/pkg/compiler/lib/src/tracer.dart b/pkg/compiler/lib/src/tracer.dart
index 2c687bf..c67cafc 100644
--- a/pkg/compiler/lib/src/tracer.dart
+++ b/pkg/compiler/lib/src/tracer.dart
@@ -5,7 +5,6 @@
 library tracer;
 
 import '../compiler_new.dart' as api;
-import 'js_backend/namer.dart' show Namer;
 import 'ssa/nodes.dart' as ssa show HGraph;
 import 'ssa/ssa_tracer.dart' show HTracer;
 import 'util/util.dart' show Indentation;
@@ -24,13 +23,12 @@
 /// readable by IR Hydra.
 class Tracer extends TracerUtil {
   final JClosedWorld closedWorld;
-  final Namer namer;
   bool traceActive = false;
   @override
   final api.OutputSink output;
   final RegExp traceFilter;
 
-  Tracer(this.closedWorld, this.namer, api.CompilerOutput compilerOutput)
+  Tracer(this.closedWorld, api.CompilerOutput compilerOutput)
       : traceFilter = TRACE_FILTER_PATTERN == null
             ? null
             : new RegExp(TRACE_FILTER_PATTERN),
@@ -55,7 +53,7 @@
   void traceGraph(String name, var irObject) {
     if (!traceActive) return;
     if (irObject is ssa.HGraph) {
-      new HTracer(output, closedWorld, namer).traceGraph(name, irObject);
+      new HTracer(output, closedWorld).traceGraph(name, irObject);
     }
   }
 
diff --git a/pkg/compiler/lib/src/universe/call_structure.dart b/pkg/compiler/lib/src/universe/call_structure.dart
index 8c148c8..5410034 100644
--- a/pkg/compiler/lib/src/universe/call_structure.dart
+++ b/pkg/compiler/lib/src/universe/call_structure.dart
@@ -67,6 +67,15 @@
     sink.end(tag);
   }
 
+  /// Returns `true` if this call structure is normalized, that is, its named
+  /// arguments are sorted.
+  bool get isNormalized => true;
+
+  /// Returns the normalized version of this call structure.
+  ///
+  /// A [CallStructure] is normalized if its named arguments are sorted.
+  CallStructure toNormalized() => this;
+
   CallStructure withTypeArgumentCount(int typeArgumentCount) =>
       new CallStructure(argumentCount, namedArguments, typeArgumentCount);
 
@@ -185,17 +194,21 @@
   }
 }
 
-///
+/// Call structure with named arguments.
 class NamedCallStructure extends CallStructure {
   @override
   final List<String> namedArguments;
-  final List<String> _orderedNamedArguments = <String>[];
+  final List<String> _orderedNamedArguments;
 
   NamedCallStructure(
-      int argumentCount, this.namedArguments, int typeArgumentCount)
-      : super.unnamed(argumentCount, typeArgumentCount) {
-    assert(namedArguments.isNotEmpty);
-  }
+      int argumentCount, List<String> namedArguments, int typeArgumentCount)
+      : this.internal(
+            argumentCount, namedArguments, typeArgumentCount, <String>[]);
+
+  NamedCallStructure.internal(int argumentCount, this.namedArguments,
+      int typeArgumentCount, this._orderedNamedArguments)
+      : assert(namedArguments.isNotEmpty),
+        super.unnamed(argumentCount, typeArgumentCount);
 
   @override
   bool get isNamed => true;
@@ -210,6 +223,16 @@
   int get positionalArgumentCount => argumentCount - namedArgumentCount;
 
   @override
+  bool get isNormalized => namedArguments == _orderedNamedArguments;
+
+  @override
+  CallStructure toNormalized() => new NamedCallStructure.internal(
+      argumentCount,
+      getOrderedNamedArguments(),
+      typeArgumentCount,
+      getOrderedNamedArguments());
+
+  @override
   List<String> getOrderedNamedArguments() {
     if (!_orderedNamedArguments.isEmpty) return _orderedNamedArguments;
 
diff --git a/pkg/compiler/lib/src/universe/codegen_world_builder.dart b/pkg/compiler/lib/src/universe/codegen_world_builder.dart
index b719421..9b26699 100644
--- a/pkg/compiler/lib/src/universe/codegen_world_builder.dart
+++ b/pkg/compiler/lib/src/universe/codegen_world_builder.dart
@@ -36,7 +36,7 @@
 
 // The immutable result of the [CodegenWorldBuilder].
 abstract class CodegenWorld extends BuiltWorld {
-  /// Calls [f] for each
+  /// Calls [f] for each generic call method on a live closure class.
   void forEachGenericClosureCallMethod(void Function(FunctionEntity) f);
 
   bool hasInvokedGetter(MemberEntity member);
diff --git a/pkg/compiler/lib/src/universe/feature.dart b/pkg/compiler/lib/src/universe/feature.dart
index f6386be..92ded95 100644
--- a/pkg/compiler/lib/src/universe/feature.dart
+++ b/pkg/compiler/lib/src/universe/feature.dart
@@ -10,6 +10,7 @@
 
 import '../elements/types.dart';
 import '../ir/runtime_type_analysis.dart';
+import '../serialization/serialization.dart';
 import '../util/util.dart';
 
 /// A language feature that may be seen in the program.
@@ -236,6 +237,8 @@
 /// A generic instantiation of an expression of type [functionType] with the
 /// given [typeArguments].
 class GenericInstantiation {
+  static const String tag = 'generic-instantiation';
+
   /// The static type of the instantiated expression.
   final DartType functionType;
 
@@ -244,6 +247,21 @@
 
   GenericInstantiation(this.functionType, this.typeArguments);
 
+  factory GenericInstantiation.readFromDataSource(DataSource source) {
+    source.begin(tag);
+    DartType functionType = source.readDartType();
+    List<DartType> typeArguments = source.readDartTypes();
+    source.end(tag);
+    return new GenericInstantiation(functionType, typeArguments);
+  }
+
+  void writeToDataSink(DataSink sink) {
+    sink.begin(tag);
+    sink.writeDartType(functionType);
+    sink.writeDartTypes(typeArguments);
+    sink.end(tag);
+  }
+
   /// Short textual representation use for testing.
   String get shortText => '<${typeArguments.join(',')}>';
 
diff --git a/pkg/compiler/lib/src/universe/selector.dart b/pkg/compiler/lib/src/universe/selector.dart
index 2f70e16..20f8391 100644
--- a/pkg/compiler/lib/src/universe/selector.dart
+++ b/pkg/compiler/lib/src/universe/selector.dart
@@ -315,6 +315,15 @@
     return 'Selector($kind, $name, ${callStructure.structureToString()})';
   }
 
+  /// Returns the normalized version of this selector.
+  ///
+  /// A selector is normalized if its call structure is normalized.
+  // TODO(johnniwinther): Use normalized selectors as much as possible,
+  // especially where selectors are used in sets or as keys in maps.
+  Selector toNormalized() => callStructure.isNormalized
+      ? this
+      : new Selector(kind, memberName, callStructure.toNormalized());
+
   Selector toCallSelector() => new Selector.callClosureFrom(this);
 
   /// Returns the non-generic [Selector] corresponding to this selector.
diff --git a/pkg/compiler/lib/src/universe/use.dart b/pkg/compiler/lib/src/universe/use.dart
index 453f812..d062fc5 100644
--- a/pkg/compiler/lib/src/universe/use.dart
+++ b/pkg/compiler/lib/src/universe/use.dart
@@ -20,6 +20,8 @@
 import '../constants/values.dart';
 import '../elements/types.dart';
 import '../elements/entities.dart';
+import '../inferrer/abstract_value_domain.dart';
+import '../serialization/serialization.dart';
 import '../js_model/closure.dart';
 import '../util/util.dart' show equalElements, Hashing;
 import 'call_structure.dart' show CallStructure;
@@ -36,9 +38,49 @@
 /// property and [receiverConstraint] defines the known constraint for the
 /// object on which the property is accessed.
 class DynamicUse {
-  final Selector selector;
+  static const String tag = 'dynamic-use';
 
-  DynamicUse(this.selector);
+  final Selector selector;
+  final Object receiverConstraint;
+  final List<DartType> _typeArguments;
+
+  DynamicUse(this.selector, this.receiverConstraint, this._typeArguments) {
+    assert(
+        selector.callStructure.typeArgumentCount ==
+            (_typeArguments?.length ?? 0),
+        "Type argument count mismatch. Selector has "
+        "${selector.callStructure.typeArgumentCount} but "
+        "${_typeArguments?.length ?? 0} were passed.");
+  }
+
+  factory DynamicUse.readFromDataSource(DataSource source) {
+    source.begin(tag);
+    Selector selector = Selector.readFromDataSource(source);
+    bool hasConstraint = source.readBool();
+    Object receiverConstraint;
+    if (hasConstraint) {
+      receiverConstraint = source.readAbstractValue();
+    }
+    List<DartType> typeArguments = source.readDartTypes(emptyAsNull: true);
+    source.end(tag);
+    return new DynamicUse(selector, receiverConstraint, typeArguments);
+  }
+
+  void writeToDataSink(DataSink sink) {
+    sink.begin(tag);
+    selector.writeToDataSink(sink);
+    sink.writeBool(receiverConstraint != null);
+    if (receiverConstraint != null) {
+      if (receiverConstraint is AbstractValue) {
+        sink.writeAbstractValue(receiverConstraint);
+      } else {
+        throw new UnsupportedError(
+            "Unsupported receiver constraint: ${receiverConstraint}");
+      }
+    }
+    sink.writeDartTypes(_typeArguments, allowNull: true);
+    sink.end(tag);
+  }
 
   /// Short textual representation use for testing.
   String get shortText {
@@ -71,8 +113,6 @@
     return sb.toString();
   }
 
-  Object get receiverConstraint => null;
-
   DynamicUseKind get kind {
     if (selector.isGetter) {
       return DynamicUseKind.GET;
@@ -83,7 +123,7 @@
     }
   }
 
-  List<DartType> get typeArguments => const <DartType>[];
+  List<DartType> get typeArguments => _typeArguments ?? const <DartType>[];
 
   @override
   int get hashCode => Hashing.listHash(
@@ -99,48 +139,7 @@
   }
 
   @override
-  String toString() => '$selector,$receiverConstraint';
-}
-
-class GenericDynamicUse extends DynamicUse {
-  final List<DartType> _typeArguments;
-
-  GenericDynamicUse(Selector selector, [this._typeArguments])
-      : super(selector) {
-    assert(
-        selector.callStructure.typeArgumentCount ==
-            (_typeArguments?.length ?? 0),
-        "Type argument count mismatch. Selector has "
-        "${selector.callStructure.typeArgumentCount} but "
-        "${typeArguments?.length ?? 0} were passed.");
-  }
-
-  @override
-  List<DartType> get typeArguments => _typeArguments ?? const <DartType>[];
-}
-
-/// A dynamic use with a receiver constraint.
-///
-/// This is used in the codegen phase where receivers are constrained to a
-/// type mask or similar.
-class ConstrainedDynamicUse extends DynamicUse {
-  @override
-  final Object receiverConstraint;
-  final List<DartType> _typeArguments;
-
-  ConstrainedDynamicUse(
-      Selector selector, this.receiverConstraint, this._typeArguments)
-      : super(selector) {
-    assert(
-        selector.callStructure.typeArgumentCount ==
-            (_typeArguments?.length ?? 0),
-        "Type argument count mismatch. Selector has "
-        "${selector.callStructure.typeArgumentCount} but "
-        "${_typeArguments?.length ?? 0} were passed.");
-  }
-
-  @override
-  List<DartType> get typeArguments => _typeArguments ?? const <DartType>[];
+  String toString() => '$selector,$receiverConstraint,$typeArguments';
 }
 
 enum StaticUseKind {
@@ -170,6 +169,8 @@
 // TODO(johnniwinther): Create backend-specific implementations with better
 // invariants.
 class StaticUse {
+  static const String tag = 'static-use';
+
   final Entity element;
   final StaticUseKind kind;
   @override
@@ -178,24 +179,69 @@
   final CallStructure callStructure;
   final ImportEntity deferredImport;
   final ConstantValue constant;
+  final List<DartType> typeArguments;
 
   StaticUse.internal(Entity element, this.kind,
       {this.type,
       this.callStructure,
       this.deferredImport,
-      typeArgumentsHash: 0,
+      this.typeArguments,
       this.constant})
       : this.element = element,
         this.hashCode = Hashing.listHash([
           element,
           kind,
           type,
-          typeArgumentsHash,
+          Hashing.listHash(typeArguments),
           callStructure,
           deferredImport,
           constant
         ]);
 
+  bool _checkGenericInvariants() {
+    assert(
+        (callStructure?.typeArgumentCount ?? 0) == (typeArguments?.length ?? 0),
+        failedAt(
+            element,
+            "Type argument count mismatch. Call structure has "
+            "${callStructure?.typeArgumentCount ?? 0} but "
+            "${typeArguments?.length ?? 0} were passed in $this."));
+    return true;
+  }
+
+  factory StaticUse.readFromDataSource(DataSource source) {
+    source.begin(tag);
+    MemberEntity element = source.readMember();
+    StaticUseKind kind = source.readEnum(StaticUseKind.values);
+    InterfaceType type = source.readDartType(allowNull: true);
+    CallStructure callStructure =
+        source.readValueOrNull(() => CallStructure.readFromDataSource(source));
+    ImportEntity deferredImport = source.readImportOrNull();
+    ConstantValue constant = source.readConstantOrNull();
+    List<DartType> typeArguments = source.readDartTypes(emptyAsNull: true);
+    source.end(tag);
+    return new StaticUse.internal(element, kind,
+        type: type,
+        callStructure: callStructure,
+        deferredImport: deferredImport,
+        constant: constant,
+        typeArguments: typeArguments);
+  }
+
+  void writeToDataSink(DataSink sink) {
+    sink.begin(tag);
+    assert(element is MemberEntity, "Unsupported entity: $element");
+    sink.writeMember(element);
+    sink.writeEnum(kind);
+    sink.writeDartType(type, allowNull: true);
+    sink.writeValueOrNull(
+        callStructure, (CallStructure c) => c.writeToDataSink(sink));
+    sink.writeImportOrNull(deferredImport);
+    sink.writeConstantOrNull(constant);
+    sink.writeDartTypes(typeArguments, allowNull: true);
+    sink.end(tag);
+  }
+
   /// Short textual representation use for testing.
   String get shortText {
     StringBuffer sb = new StringBuffer();
@@ -252,8 +298,6 @@
     return sb.toString();
   }
 
-  List<DartType> get typeArguments => null;
-
   /// Invocation of a static or top-level [element] with the given
   /// [callStructure].
   factory StaticUse.staticInvoke(
@@ -272,8 +316,13 @@
         failedAt(element,
             "Not CallStructure for static invocation of element $element."));
 
-    return new GenericStaticUse(element, StaticUseKind.STATIC_INVOKE,
-        callStructure, typeArguments, deferredImport);
+    StaticUse staticUse = new StaticUse.internal(
+        element, StaticUseKind.STATIC_INVOKE,
+        callStructure: callStructure,
+        typeArguments: typeArguments,
+        deferredImport: deferredImport);
+    assert(staticUse._checkGenericInvariants());
+    return staticUse;
   }
 
   /// Closurization of a static or top-level function [element].
@@ -351,8 +400,11 @@
         callStructure != null,
         failedAt(element,
             "Not CallStructure for super invocation of element $element."));
-    return new GenericStaticUse(
-        element, StaticUseKind.SUPER_INVOKE, callStructure, typeArguments);
+    StaticUse staticUse = new StaticUse.internal(
+        element, StaticUseKind.SUPER_INVOKE,
+        callStructure: callStructure, typeArguments: typeArguments);
+    assert(staticUse._checkGenericInvariants());
+    return staticUse;
   }
 
   /// Read access of a super field or getter [element].
@@ -449,8 +501,11 @@
             "Direct invoke element $element must be an instance member."));
     assert(element.isFunction,
         failedAt(element, "Direct invoke element $element must be a method."));
-    return new GenericStaticUse(
-        element, StaticUseKind.DIRECT_INVOKE, callStructure, typeArguments);
+    StaticUse staticUse = new StaticUse.internal(
+        element, StaticUseKind.DIRECT_INVOKE,
+        callStructure: callStructure, typeArguments: typeArguments);
+    assert(staticUse._checkGenericInvariants());
+    return staticUse;
   }
 
   /// Direct read access of a field or getter [element].
@@ -584,8 +639,11 @@
   /// [callStructure] and [typeArguments].
   factory StaticUse.closureCall(Local element, CallStructure callStructure,
       List<DartType> typeArguments) {
-    return new GenericStaticUse(
-        element, StaticUseKind.CLOSURE_CALL, callStructure, typeArguments);
+    StaticUse staticUse = new StaticUse.internal(
+        element, StaticUseKind.CLOSURE_CALL,
+        callStructure: callStructure, typeArguments: typeArguments);
+    assert(staticUse._checkGenericInvariants());
+    return staticUse;
   }
 
   /// Read of a call [method] on a closureClass.
@@ -610,7 +668,8 @@
   /// Inlining of [element].
   factory StaticUse.methodInlining(
       FunctionEntity element, List<DartType> typeArguments) {
-    return new GenericStaticUse.methodInlining(element, typeArguments);
+    return new StaticUse.internal(element, StaticUseKind.INLINING,
+        typeArguments: typeArguments);
   }
 
   @override
@@ -631,31 +690,6 @@
       'StaticUse($element,$kind,$type,$typeArguments,$callStructure)';
 }
 
-class GenericStaticUse extends StaticUse {
-  @override
-  final List<DartType> typeArguments;
-
-  GenericStaticUse(Entity entity, StaticUseKind kind,
-      CallStructure callStructure, this.typeArguments,
-      [ImportEntity deferredImport])
-      : super.internal(entity, kind,
-            callStructure: callStructure,
-            deferredImport: deferredImport,
-            typeArgumentsHash: Hashing.listHash(typeArguments)) {
-    assert(
-        (callStructure?.typeArgumentCount ?? 0) == (typeArguments?.length ?? 0),
-        failedAt(
-            element,
-            "Type argument count mismatch. Call structure has "
-            "${callStructure?.typeArgumentCount ?? 0} but "
-            "${typeArguments?.length ?? 0} were passed in $this."));
-  }
-
-  GenericStaticUse.methodInlining(FunctionEntity entity, this.typeArguments)
-      : super.internal(entity, StaticUseKind.INLINING,
-            typeArgumentsHash: Hashing.listHash(typeArguments));
-}
-
 enum TypeUseKind {
   IS_CHECK,
   AS_CAST,
@@ -672,6 +706,8 @@
 
 /// Use of a [DartType].
 class TypeUse {
+  static const String tag = 'type-use';
+
   final DartType type;
   final TypeUseKind kind;
   @override
@@ -683,6 +719,23 @@
         this.kind = kind,
         this.hashCode = Hashing.objectsHash(type, kind, deferredImport);
 
+  factory TypeUse.readFromDataSource(DataSource source) {
+    source.begin(tag);
+    DartType type = source.readDartType();
+    TypeUseKind kind = source.readEnum(TypeUseKind.values);
+    ImportEntity deferredImport = source.readImportOrNull();
+    source.end(tag);
+    return new TypeUse.internal(type, kind, deferredImport);
+  }
+
+  void writeToDataSink(DataSink sink) {
+    sink.begin(tag);
+    sink.writeDartType(type);
+    sink.writeEnum(kind);
+    sink.writeImportOrNull(deferredImport);
+    sink.end(tag);
+  }
+
   /// Short textual representation use for testing.
   String get shortText {
     StringBuffer sb = new StringBuffer();
@@ -818,10 +871,25 @@
 
 /// Use of a [ConstantValue].
 class ConstantUse {
+  static const String tag = 'constant-use';
+
   final ConstantValue value;
 
   ConstantUse._(this.value);
 
+  factory ConstantUse.readFromDataSource(DataSource source) {
+    source.begin(tag);
+    ConstantValue value = source.readConstant();
+    source.end(tag);
+    return new ConstantUse._(value);
+  }
+
+  void writeToDataSink(DataSink sink) {
+    sink.begin(tag);
+    sink.writeConstant(value);
+    sink.end(tag);
+  }
+
   /// Short textual representation use for testing.
   String get shortText {
     return value.toDartText();
diff --git a/pkg/compiler/lib/src/universe/world_impact.dart b/pkg/compiler/lib/src/universe/world_impact.dart
index cc9a92c..f3c8e21 100644
--- a/pkg/compiler/lib/src/universe/world_impact.dart
+++ b/pkg/compiler/lib/src/universe/world_impact.dart
@@ -82,6 +82,11 @@
   Set<TypeUse> _typeUses;
   Set<ConstantUse> _constantUses;
 
+  WorldImpactBuilderImpl();
+
+  WorldImpactBuilderImpl.internal(
+      this._dynamicUses, this._staticUses, this._typeUses, this._constantUses);
+
   @override
   bool get isEmpty =>
       _dynamicUses == null &&
diff --git a/pkg/dartfix/analysis_options.yaml b/pkg/dartfix/analysis_options.yaml
index e36185e..309f5ca 100644
--- a/pkg/dartfix/analysis_options.yaml
+++ b/pkg/dartfix/analysis_options.yaml
@@ -1,6 +1,7 @@
+include: package:pedantic/analysis_options.yaml
+
 linter:
   rules:
-    - empty_constructor_bodies
+    - directives_ordering
     - empty_statements
     - unnecessary_brace_in_string_interps
-    - valid_regexps
diff --git a/pkg/dartfix/bin/fix.dart b/pkg/dartfix/bin/dartfix.dart
similarity index 91%
rename from pkg/dartfix/bin/fix.dart
rename to pkg/dartfix/bin/dartfix.dart
index 0e2a489..7df5fc4 100644
--- a/pkg/dartfix/bin/fix.dart
+++ b/pkg/dartfix/bin/dartfix.dart
@@ -6,7 +6,7 @@
 import 'package:dartfix/src/driver.dart';
 
 /// The entry point for dartfix.
-main(List<String> args) async {
+void main(List<String> args) async {
   Driver starter = new Driver();
 
   // Wait for the starter to complete.
diff --git a/pkg/dartfix/lib/listener/recording_listener.dart b/pkg/dartfix/lib/listener/recording_listener.dart
index 7ac4a12..db0dcf1 100644
--- a/pkg/dartfix/lib/listener/recording_listener.dart
+++ b/pkg/dartfix/lib/listener/recording_listener.dart
@@ -2,8 +2,8 @@
 // for details. All 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_client/server.dart';
 import 'package:analysis_server_client/listener/server_listener.dart';
+import 'package:analysis_server_client/server.dart';
 import 'package:dartfix/listener/bad_message_listener.dart';
 import 'package:dartfix/listener/timed_listener.dart';
 
diff --git a/pkg/dartfix/lib/src/driver.dart b/pkg/dartfix/lib/src/driver.dart
index 42bec0e..549f41d 100644
--- a/pkg/dartfix/lib/src/driver.dart
+++ b/pkg/dartfix/lib/src/driver.dart
@@ -31,8 +31,11 @@
 
   Ansi get ansi => logger.ansi;
 
-  Future start(List<String> args,
-      {Context testContext, Logger testLogger}) async {
+  Future start(
+    List<String> args, {
+    Context testContext,
+    Logger testLogger,
+  }) async {
     final Options options = Options.parse(args);
 
     force = options.force;
@@ -43,23 +46,44 @@
     server = new Server(listener: new _Listener(logger));
     handler = new _Handler(this);
 
+    // Start showing progress before we start the analysis server.
+    Progress progress;
+    if (options.listFixes) {
+      progress = logger.progress('${ansi.emphasized('Listing fixes')}');
+    } else {
+      progress = logger.progress('${ansi.emphasized('Calculating fixes')}');
+    }
+
     if (!await startServer(options)) {
       context.exit(15);
     }
-    try {
-      if (checkSupported(options)) {
-        if (options.listFixes) {
-          await showListOfFixes();
-        } else {
-          final progress = await setupAnalysis(options);
-          result = await requestFixes(options, progress);
+
+    if (!checkSupported(options)) {
+      await server.stop();
+      context.exit(1);
+    }
+
+    if (options.listFixes) {
+      try {
+        await showListOfFixes(progress: progress);
+      } finally {
+        await server.stop();
+      }
+    } else {
+      Future serverStopped;
+
+      try {
+        await setupFixesAnalysis(options);
+        result = await requestFixes(options, progress: progress);
+        serverStopped = server.stop();
+        await applyFixes();
+        await serverStopped;
+      } finally {
+        // If we didn't already try to stop the server, then stop it now.
+        if (serverStopped == null) {
+          await server.stop();
         }
       }
-    } finally {
-      await server.stop();
-    }
-    if (result != null) {
-      applyFixes();
     }
   }
 
@@ -80,7 +104,7 @@
       serverPath: serverPath,
     );
     server.listenToOutput(notificationProcessor: handler.handleEvent);
-    return handler.serverConnected(timeLimit: const Duration(seconds: 15));
+    return handler.serverConnected(timeLimit: const Duration(seconds: 30));
   }
 
   /// Check if the specified options is supported by the version of analysis
@@ -116,8 +140,10 @@
 Please upgrade to a newer version of the Dart SDK to use this option.''');
   }
 
-  Future<Progress> setupAnalysis(Options options) async {
-    final progress = logger.progress('${ansi.emphasized('Calculating fixes')}');
+  Future<Progress> setupFixesAnalysis(
+    Options options, {
+    Progress progress,
+  }) async {
     logger.trace('');
     logger.trace('Setup analysis');
     await server.send(SERVER_REQUEST_SET_SUBSCRIPTIONS,
@@ -132,7 +158,9 @@
   }
 
   Future<EditDartfixResult> requestFixes(
-      Options options, Progress progress) async {
+    Options options, {
+    Progress progress,
+  }) async {
     logger.trace('Requesting fixes');
     Future isAnalysisComplete = handler.analysisComplete();
 
@@ -232,14 +260,10 @@
     return filePath;
   }
 
-  showListOfFixes() async {
-    final progress =
-        logger.progress('${ansi.emphasized('Getting list of fixes')}');
-    logger.trace('');
+  Future<EditGetDartfixInfoResult> showListOfFixes({Progress progress}) async {
     Map<String, dynamic> json = await server.send(
         EDIT_REQUEST_GET_DARTFIX_INFO, new EditGetDartfixInfoParams().toJson());
-
-    progress.finish(showTiming: true);
+    progress?.finish(showTiming: true);
     ResponseDecoder decoder = new ResponseDecoder(null);
     final result = EditGetDartfixInfoResult.fromJson(decoder, 'result', json);
 
@@ -259,6 +283,7 @@
         }
       }
     }
+
     return result;
   }
 
diff --git a/pkg/dartfix/lib/src/options.dart b/pkg/dartfix/lib/src/options.dart
index a9af28e..3b6d651 100644
--- a/pkg/dartfix/lib/src/options.dart
+++ b/pkg/dartfix/lib/src/options.dart
@@ -4,9 +4,9 @@
 
 import 'dart:io';
 
-import 'package:dartfix/src/context.dart';
 import 'package:args/args.dart';
 import 'package:cli_util/cli_logging.dart';
+import 'package:dartfix/src/context.dart';
 import 'package:path/path.dart' as path;
 
 /// Command line options for `dartfix`.
@@ -55,10 +55,7 @@
           help: 'Overwrite files even if there are errors.',
           defaultsTo: false,
           negatable: false)
-      ..addSeparator('Miscelaneous:')
-      ..addFlag(_colorOption,
-          help: 'Use ansi colors when printing messages.',
-          defaultsTo: Ansi.terminalSupportsAnsi)
+      ..addSeparator('Miscellaneous:')
       ..addFlag(_helpOption,
           abbr: 'h',
           help: 'Display this help message.',
@@ -68,7 +65,10 @@
           abbr: 'v',
           defaultsTo: false,
           help: 'Verbose output.',
-          negatable: false);
+          negatable: false)
+      ..addFlag(_colorOption,
+          help: 'Use ansi colors when printing messages.',
+          defaultsTo: Ansi.terminalSupportsAnsi);
 
     context ??= new Context();
 
@@ -78,6 +78,7 @@
     } on FormatException catch (e) {
       logger ??= new Logger.standard(ansi: new Ansi(Ansi.terminalSupportsAnsi));
       logger.stderr(e.message);
+      logger.stderr('\n');
       _showUsage(parser, logger);
       context.exit(15);
     }
@@ -103,8 +104,8 @@
       context.exit(1);
     }
 
+    // For '--list', we short circuit the logic to validate the sdk and project.
     if (options.listFixes) {
-      _showUsage(parser, logger, showListHint: false);
       return options;
     }
 
@@ -112,19 +113,17 @@
     String sdkPath = options.sdkPath;
     if (sdkPath == null) {
       logger.stderr('No Dart SDK found.');
-      _showUsage(parser, logger);
       context.exit(15);
     }
+
     if (!context.exists(sdkPath)) {
       logger.stderr('Invalid Dart SDK path: $sdkPath');
-      _showUsage(parser, logger);
       context.exit(15);
     }
 
     // Check for files and/or directories to analyze.
     if (options.targets == null || options.targets.isEmpty) {
       logger.stderr('Expected at least one file or directory to analyze.');
-      _showUsage(parser, logger);
       context.exit(15);
     }
 
@@ -138,7 +137,6 @@
         } else {
           logger.stderr('Expected directory, but found: $target');
         }
-        _showUsage(parser, logger);
         context.exit(15);
       }
     }
@@ -189,14 +187,14 @@
     logger.stderr(parser.usage);
     logger.stderr('''
 
-If neither --$includeOption nor --$requiredOption is specified, then all fixes
-will be applied. Any fixes specified using --$excludeOption will not be applied
-regardless of whether they are required or specifed using --$includeOption.''');
+If neither --$includeOption nor --$requiredOption is specified, then all fixes will be
+applied. Any fixes specified using --$excludeOption will not be applied regardless
+of whether they are required or specifed using --$includeOption.''');
     if (showListHint) {
       logger.stderr('''
 
-Use --list to display the fixes that can be specified
-using either --$includeOption or --$excludeOption.''');
+Use --list to display the fixes that can be specified using either
+--$includeOption or --$excludeOption.''');
     }
   }
 }
diff --git a/pkg/dartfix/pubspec.yaml b/pkg/dartfix/pubspec.yaml
index 88c9dfc..8f6b34b 100644
--- a/pkg/dartfix/pubspec.yaml
+++ b/pkg/dartfix/pubspec.yaml
@@ -2,13 +2,16 @@
 version: 0.1.5-dev
 author: Dart Team <misc@dartlang.org>
 description:
-  A tool for migrating Dart source to newer versions of the Dart SDK,
+  A tool for migrating Dart source to newer versions of the Dart SDK
   and fixing common issues.
 homepage: https://github.com/dart-lang/sdk/tree/master/pkg/dartfix
-executables:
-  dartfix: fix
 environment:
-  sdk: '>=2.1.0 <3.0.0'
+  sdk: '>=2.2.0 <3.0.0'
+
+# Add the bin/dartfix.dart script to the scripts pub installs.
+executables:
+  dartfix:
+
 dependencies:
   # pin to an exact version of analysis_server_client because the edit.dartfix protocol
   # is experimental and will continue to evolve
@@ -17,6 +20,8 @@
   cli_util: ^0.1.3
   path: ^1.6.0
   pub_semver: ^1.4.2
+
 dev_dependencies:
   analyzer: ^0.33.0
+  pedantic: ^1.5.0
   test: ^1.3.0
diff --git a/pkg/dartfix/test/src/options_test.dart b/pkg/dartfix/test/src/options_test.dart
index 971517a..c463ed6 100644
--- a/pkg/dartfix/test/src/options_test.dart
+++ b/pkg/dartfix/test/src/options_test.dart
@@ -108,7 +108,7 @@
   });
 
   test('list fixes', () {
-    parse(['--list'], errorOut: 'Display this help message', listFixes: true);
+    parse(['--list'], normalOut: '', listFixes: true);
   });
 
   test('overwrite', () {
diff --git a/pkg/dev_compiler/analysis_options.yaml b/pkg/dev_compiler/analysis_options.yaml
index 55db4c5..43cfad3 100644
--- a/pkg/dev_compiler/analysis_options.yaml
+++ b/pkg/dev_compiler/analysis_options.yaml
@@ -1,4 +1,6 @@
 analyzer:
+  errors:
+    todo: ignore
   exclude:
     - doc/api/**
     - gen/**
@@ -7,3 +9,25 @@
     - test/samples/**
     - test/transformer/hello_app/**
     - tool/input_sdk/**
+
+linter:
+  rules:
+    - annotate_overrides
+    - avoid_empty_else
+    - avoid_init_to_null
+    - avoid_return_types_on_setters
+    - avoid_shadowing_type_parameters
+    - avoid_types_as_parameter_names
+    - curly_braces_in_flow_control_structures
+    - empty_constructor_bodies
+    - library_names
+    - null_closures
+    - prefer_contains
+    - prefer_equal_for_default_values
+    - prefer_is_empty
+    - prefer_is_not_empty
+    - recursive_getters
+    - type_init_formals
+    - unnecessary_null_in_if_null_operators
+    - use_rethrow_when_possible
+    - valid_regexps
diff --git a/pkg/dev_compiler/bin/dartdevc.dart b/pkg/dev_compiler/bin/dartdevc.dart
index fbe7114..db2f7b8 100755
--- a/pkg/dev_compiler/bin/dartdevc.dart
+++ b/pkg/dev_compiler/bin/dartdevc.dart
@@ -47,6 +47,7 @@
   CompilerResult lastResult;
 
   /// Performs each individual work request.
+  @override
   Future<WorkResponse> performRequest(WorkRequest request) async {
     var args = _startupArgs.merge(request.arguments);
     var output = StringBuffer();
diff --git a/pkg/dev_compiler/lib/src/analyzer/ast_builder.dart b/pkg/dev_compiler/lib/src/analyzer/ast_builder.dart
index 1b5039a..120b590 100644
--- a/pkg/dev_compiler/lib/src/analyzer/ast_builder.dart
+++ b/pkg/dev_compiler/lib/src/analyzer/ast_builder.dart
@@ -16,15 +16,15 @@
   KeywordToken get constKeyword => KeywordToken(Keyword.CONST, 0);
 
   TypeName typeName(Identifier id, List<TypeAnnotation> args) {
-    TypeArgumentList argList = null;
-    if (args != null && args.length > 0) argList = typeArgumentList(args);
+    TypeArgumentList argList;
+    if (args != null && args.isNotEmpty) argList = typeArgumentList(args);
     return astFactory.typeName(id, argList);
   }
 
   FunctionTypeAlias functionTypeAlias(TypeName ret, SimpleIdentifier name,
       List<TypeParameter> tParams, List<FormalParameter> params) {
     TypeParameterList tps =
-        (tParams.length == 0) ? null : typeParameterList(tParams);
+        (tParams.isEmpty) ? null : typeParameterList(tParams);
     FormalParameterList fps = formalParameterList(params);
     Token semi = Token(TokenType.SEMICOLON, 0);
     Token td = KeywordToken(Keyword.TYPEDEF, 0);
@@ -313,7 +313,7 @@
     return astFactory.prefixedIdentifier(pre, period, id);
   }
 
-  TypeParameter typeParameter(SimpleIdentifier name, [TypeName bound = null]) {
+  TypeParameter typeParameter(SimpleIdentifier name, [TypeName bound]) {
     Token keyword = (bound == null) ? null : KeywordToken(Keyword.EXTENDS, 0);
     return astFactory.typeParameter(null, null, name, keyword, bound);
   }
@@ -388,8 +388,8 @@
     bool hasOptional = params.any((p) => p.isPositional);
     bool hasNamed = params.any((p) => p.isNamed);
     assert(!(hasOptional && hasNamed));
-    Token ld = null;
-    Token rd = null;
+    Token ld;
+    Token rd;
     if (hasOptional) {
       ld = BeginToken(TokenType.OPEN_SQUARE_BRACKET, 0);
       rd = Token(TokenType.CLOSE_SQUARE_BRACKET, 0);
diff --git a/pkg/dev_compiler/lib/src/analyzer/code_generator.dart b/pkg/dev_compiler/lib/src/analyzer/code_generator.dart
index 2c72273..f97e1c2 100644
--- a/pkg/dev_compiler/lib/src/analyzer/code_generator.dart
+++ b/pkg/dev_compiler/lib/src/analyzer/code_generator.dart
@@ -83,6 +83,7 @@
   /// Errors that were produced during compilation, if any.
   final ErrorCollector errors;
 
+  @override
   JSTypeRep jsTypeRep;
 
   /// The list of dart:_runtime SDK functions; these are assumed by other code
@@ -112,6 +113,7 @@
   /// The  type provider from the current Analysis [context].
   final TypeProvider types;
 
+  @override
   final LibraryElement coreLibrary;
   final LibraryElement dartJSLibrary;
 
@@ -183,6 +185,7 @@
 
   /// Information about virtual fields for all libraries in the current build
   /// unit.
+  @override
   final virtualFields = VirtualFieldModel();
 
   final _usedCovariantPrivateMembers = HashSet<ExecutableElement>();
@@ -234,6 +237,7 @@
     jsTypeRep = JSTypeRep(rules, driver);
   }
 
+  @override
   LibraryElement get currentLibrary => _currentElement.library;
 
   @override
@@ -3444,7 +3448,7 @@
       return _emitSetSimpleIdentifier(left, right);
     }
 
-    Expression target = null;
+    Expression target;
     SimpleIdentifier id;
     if (left is PropertyAccess) {
       if (left.operator.lexeme == '?.') {
@@ -4772,7 +4776,9 @@
 
   AstNode _parentOperation(AstNode node) {
     node = node.parent;
-    while (node is ParenthesizedExpression) node = node.parent;
+    while (node is ParenthesizedExpression) {
+      node = node.parent;
+    }
     return node;
   }
 
@@ -6218,6 +6224,7 @@
 
   /// Return true if this is one of the methods/properties on all Dart Objects
   /// (toString, hashCode, noSuchMethod, runtimeType, ==).
+  @override
   bool isObjectMember(String name) {
     // We could look these up on Object, but we have hard coded runtime helpers
     // so it's not really providing any benefit.
@@ -6253,7 +6260,7 @@
     }
     var type = functionType.returnType;
 
-    InterfaceType expectedType = null;
+    InterfaceType expectedType;
     if (element.isAsynchronous) {
       if (element.isGenerator) {
         // Stream<T> -> T
@@ -6438,9 +6445,9 @@
 
   JS.For _emitFor(ForParts forParts, JS.Statement body) {
     JS.Expression init;
-    if (forParts is ForPartsWithExpression)
+    if (forParts is ForPartsWithExpression) {
       init = _visitExpression(forParts.initialization);
-    else if (forParts is ForPartsWithDeclarations) {
+    } else if (forParts is ForPartsWithDeclarations) {
       init = visitVariableDeclarationList(forParts.variables);
     } else {
       throw new StateError('Unrecognized for loop parts');
@@ -6687,8 +6694,10 @@
         : enclosingElement;
   }
 
+  @override
   int get hashCode => identityHashCode(this);
 
+  @override
   bool operator ==(Object other) => identical(this, other);
 }
 
diff --git a/pkg/dev_compiler/lib/src/analyzer/command.dart b/pkg/dev_compiler/lib/src/analyzer/command.dart
index 2d32c8d..d8e2363 100644
--- a/pkg/dev_compiler/lib/src/analyzer/command.dart
+++ b/pkg/dev_compiler/lib/src/analyzer/command.dart
@@ -140,12 +140,12 @@
   if (outPaths.isEmpty) {
     throw UsageException(
         'Please specify the output file location. For example:\n'
-        '    -o PATH/TO/OUTPUT_FILE.js',
+            '    -o PATH/TO/OUTPUT_FILE.js',
         '');
   } else if (outPaths.length != moduleFormats.length) {
     throw UsageException(
         'Number of output files (${outPaths.length}) must match '
-        'number of module formats (${moduleFormats.length}).',
+            'number of module formats (${moduleFormats.length}).',
         '');
   }
 
@@ -208,11 +208,13 @@
 
 /// Thrown when the input source code has errors.
 class CompileErrorException implements Exception {
+  @override
   toString() => '\nPlease fix all errors before compiling (warnings are okay).';
 }
 
 /// Thrown when force compilation failed (probably due to static errors).
 class ForceCompileErrorException extends CompileErrorException {
+  @override
   toString() =>
       '\nForce-compilation not successful. Please check static errors.';
 }
diff --git a/pkg/dev_compiler/lib/src/analyzer/driver.dart b/pkg/dev_compiler/lib/src/analyzer/driver.dart
index c1e1efc..8d55999 100644
--- a/pkg/dev_compiler/lib/src/analyzer/driver.dart
+++ b/pkg/dev_compiler/lib/src/analyzer/driver.dart
@@ -14,6 +14,7 @@
 import 'package:analyzer/src/dart/analysis/file_state.dart';
 import 'package:analyzer/src/dart/analysis/library_analyzer.dart';
 import 'package:analyzer/src/dart/analysis/performance_logger.dart';
+import 'package:analyzer/src/dart/analysis/session.dart';
 import 'package:analyzer/src/dart/analysis/restricted_analysis_context.dart';
 import 'package:analyzer/src/dart/element/inheritance_manager2.dart';
 import 'package:analyzer/src/generated/engine.dart';
@@ -241,8 +242,9 @@
     var bundle = PackageBundle.fromBuffer(summaryBytes);
 
     /// Create an analysis context to contain the state for this build unit.
-    var context = RestrictedAnalysisContext(
-        analysisOptions, declaredVariables, sourceFactory);
+    var synchronousSession =
+        SynchronousSession(analysisOptions, declaredVariables);
+    var context = RestrictedAnalysisContext(synchronousSession, sourceFactory);
     var resynthesizer = StoreBasedSummaryResynthesizer(
       context,
       null,
diff --git a/pkg/dev_compiler/lib/src/analyzer/error_helpers.dart b/pkg/dev_compiler/lib/src/analyzer/error_helpers.dart
index 1528546..db93257 100644
--- a/pkg/dev_compiler/lib/src/analyzer/error_helpers.dart
+++ b/pkg/dev_compiler/lib/src/analyzer/error_helpers.dart
@@ -34,7 +34,9 @@
   }
 
   void addAll(LineInfo lineInfo, Iterable<AnalysisError> errors) {
-    for (var e in errors) add(lineInfo, e);
+    for (var e in errors) {
+      add(lineInfo, e);
+    }
   }
 
   ErrorSeverity _errorSeverity(AnalysisError error) {
@@ -123,4 +125,4 @@
     ErrorType.COMPILE_TIME_ERROR,
     'INVALID_JS_INTEGER',
     "The integer literal '{0}' can't be represented exactly in JavaScript. "
-    "The nearest value that can be represented exactly is '{1}'.");
+        "The nearest value that can be represented exactly is '{1}'.");
diff --git a/pkg/dev_compiler/lib/src/analyzer/nullable_type_inference.dart b/pkg/dev_compiler/lib/src/analyzer/nullable_type_inference.dart
index ef723c2..885172f 100644
--- a/pkg/dev_compiler/lib/src/analyzer/nullable_type_inference.dart
+++ b/pkg/dev_compiler/lib/src/analyzer/nullable_type_inference.dart
@@ -136,8 +136,8 @@
     // leads to O(depth) cost for calling this function. We could store the
     // resulting value if that becomes an issue, so we maintain the invariant
     // that each node is visited once.
-    Element element = null;
-    String name = null;
+    Element element;
+    String name;
     if (expr is PropertyAccess &&
         expr.operator?.type != TokenType.QUESTION_PERIOD) {
       element = expr.propertyName.staticElement;
@@ -196,7 +196,7 @@
       // they will throw noSuchMethod.
       // The only properties/methods on `null` are those on Object itself.
       for (var section in expr.cascadeSections) {
-        Element e = null;
+        Element e;
         if (section is PropertyAccess) {
           e = section.propertyName.staticElement;
         } else if (section is MethodInvocation) {
diff --git a/pkg/dev_compiler/lib/src/analyzer/property_model.dart b/pkg/dev_compiler/lib/src/analyzer/property_model.dart
index b7dc784..d63abc3 100644
--- a/pkg/dev_compiler/lib/src/analyzer/property_model.dart
+++ b/pkg/dev_compiler/lib/src/analyzer/property_model.dart
@@ -77,8 +77,9 @@
       // add it to our work set if this is the first time we've visited it.
       for (var superclass in getImmediateSuperclasses(extensibleClass)) {
         if (!superclass.isPublic && superclass.library == library) {
-          if (_extensiblePrivateClasses.add(superclass))
+          if (_extensiblePrivateClasses.add(superclass)) {
             classesToVisit.add(superclass);
+          }
         }
       }
     }
@@ -282,8 +283,12 @@
     void visit(InterfaceType type, bool isAbstract) {
       if (type == null) return;
       visit(type.superclass, isAbstract);
-      for (var m in type.mixins) visit(m, isAbstract);
-      for (var i in type.interfaces) visit(i, true);
+      for (var m in type.mixins) {
+        visit(m, isAbstract);
+      }
+      for (var i in type.interfaces) {
+        visit(i, true);
+      }
 
       for (var m in [type.methods, type.accessors].expand((m) => m)) {
         if (m.isStatic) continue;
diff --git a/pkg/dev_compiler/lib/src/analyzer/type_utilities.dart b/pkg/dev_compiler/lib/src/analyzer/type_utilities.dart
index 91978e7..dc52e86 100644
--- a/pkg/dev_compiler/lib/src/analyzer/type_utilities.dart
+++ b/pkg/dev_compiler/lib/src/analyzer/type_utilities.dart
@@ -134,6 +134,7 @@
 
   _GeneratorTable(this._runtimeModule);
 
+  @override
   JS.Statement _dischargeType(DartType t) {
     var name = _names.remove(t);
     if (name != null) {
diff --git a/pkg/dev_compiler/lib/src/compiler/js_metalet.dart b/pkg/dev_compiler/lib/src/compiler/js_metalet.dart
index e911dca..a88c582 100644
--- a/pkg/dev_compiler/lib/src/compiler/js_metalet.dart
+++ b/pkg/dev_compiler/lib/src/compiler/js_metalet.dart
@@ -54,6 +54,7 @@
   /// Returns an expression that ignores the result. This is a cross between
   /// [toExpression] and [toStatement]. Used for C-style for-loop updaters,
   /// which is an expression syntactically, but functions more like a statement.
+  @override
   Expression toVoidExpression() {
     var block = toStatement();
     var s = block.statements;
@@ -65,6 +66,7 @@
     return _toInvokedFunction(block);
   }
 
+  @override
   Expression toAssignExpression(Expression left, [String op]) {
     if (left is Identifier) {
       return _simplifyAssignment(left, op: op) ?? _toAssign(left, op);
@@ -82,6 +84,7 @@
     return MetaLet(variables, exprs);
   }
 
+  @override
   Statement toVariableDeclaration(VariableBinding name) {
     if (name is Identifier) {
       var simple = _simplifyAssignment(name, isDeclaration: true);
@@ -118,6 +121,7 @@
     return _expression = _toInvokedFunction(block);
   }
 
+  @override
   Block toStatement() {
     // Skip return value if not used.
     var statements = body.map((e) => e.toStatement()).toList();
@@ -125,6 +129,7 @@
     return _finishStatement(statements);
   }
 
+  @override
   Block toReturn() {
     var statements = body
         .map((e) => e == body.last ? e.toReturn() : e.toStatement())
@@ -132,6 +137,7 @@
     return _finishStatement(statements);
   }
 
+  @override
   Block toYieldStatement({bool star = false}) {
     var statements = body
         .map((e) =>
@@ -140,6 +146,7 @@
     return _finishStatement(statements);
   }
 
+  @override
   T accept<T>(NodeVisitor<T> visitor) {
     // TODO(jmesserly): we special case vistors from js_ast.Template, because it
     // doesn't know about MetaLet. Should we integrate directly?
@@ -153,6 +160,7 @@
     }
   }
 
+  @override
   void visitChildren(NodeVisitor visitor) {
     // TODO(jmesserly): we special case vistors from js_ast.Template, because it
     // doesn't know about MetaLet. Should we integrate directly?
@@ -166,6 +174,7 @@
   }
 
   /// This generates as either a comma expression or a call.
+  @override
   int get precedenceLevel => toExpression().precedenceLevel;
 
   /// Patch to pretend [Template] supports visitMetaLet.
@@ -199,7 +208,9 @@
     var node = Block(statements);
     node.accept(counter);
     // Also count the init expressions.
-    for (var init in variables.values) init.accept(counter);
+    for (var init in variables.values) {
+      init.accept(counter);
+    }
 
     var initializers = <VariableInitialization>[];
     var substitutions = <MetaLetVariable, Expression>{};
diff --git a/pkg/dev_compiler/lib/src/compiler/js_names.dart b/pkg/dev_compiler/lib/src/compiler/js_names.dart
index c4c1c11..a5afca2 100644
--- a/pkg/dev_compiler/lib/src/compiler/js_names.dart
+++ b/pkg/dev_compiler/lib/src/compiler/js_names.dart
@@ -29,7 +29,9 @@
   //
   // However we may need to fix this if we want hover to work well for things
   // like library prefixes and field-initializing formals.
+  @override
   get sourceInformation => null;
+  @override
   set sourceInformation(Object obj) {}
 
   TemporaryId(String name) : super(name);
@@ -60,10 +62,13 @@
     }
   }
 
+  @override
   int get precedenceLevel => _expr.precedenceLevel;
 
+  @override
   T accept<T>(NodeVisitor<T> visitor) => _expr.accept(visitor);
 
+  @override
   void visitChildren(NodeVisitor visitor) => _expr.visitChildren(visitor);
 }
 
@@ -83,16 +88,19 @@
 
   TemporaryNamer(Node node) : scope = _RenameVisitor.build(node).rootScope;
 
+  @override
   String getName(Identifier node) {
     var rename = scope.renames[identifierKey(node)];
     if (rename != null) return rename;
     return node.name;
   }
 
+  @override
   void enterScope(Node node) {
     scope = scope.childScopes[node];
   }
 
+  @override
   void leaveScope() {
     scope = scope.parent;
   }
@@ -138,6 +146,7 @@
     _finishNames();
   }
 
+  @override
   declare(Identifier node) {
     var id = identifierKey(node);
     var notAlreadyDeclared = scope.declared.add(id);
@@ -147,6 +156,7 @@
     _markUsed(node, id, scope);
   }
 
+  @override
   visitIdentifier(Identifier node) {
     var id = identifierKey(node);
 
@@ -166,7 +176,7 @@
   _markUsed(Identifier node, Object id, _FunctionScope declScope) {
     // If it needs rename, we can't add it to the used name set yet, instead we
     // will record all scopes it is visible in.
-    Set<_FunctionScope> usedIn = null;
+    Set<_FunctionScope> usedIn;
     var rename = declScope != globalScope && needsRename(node);
     if (rename) {
       usedIn = pendingRenames.putIfAbsent(id, () => HashSet());
@@ -180,11 +190,13 @@
     }
   }
 
+  @override
   visitFunctionExpression(FunctionExpression node) {
     // Visit nested functions after all identifiers are declared.
     scope.childScopes[node] = _FunctionScope(scope);
   }
 
+  @override
   visitClassExpression(ClassExpression node) {
     scope.childScopes[node] = _FunctionScope(scope);
   }
diff --git a/pkg/dev_compiler/lib/src/compiler/js_typerep.dart b/pkg/dev_compiler/lib/src/compiler/js_typerep.dart
index a7bd241..f5e355b 100644
--- a/pkg/dev_compiler/lib/src/compiler/js_typerep.dart
+++ b/pkg/dev_compiler/lib/src/compiler/js_typerep.dart
@@ -31,9 +31,13 @@
 /// Inhabited by booleans (including JSBool), null, and undefined
 class JSBoolean extends JSType {
   const JSBoolean();
+  @override
   bool get isPrimitive => true;
+  @override
   bool get isPrimitiveInJS => true;
+  @override
   bool get isFalsey => true;
+  @override
   String get primitiveTypeOf => 'boolean';
 }
 
@@ -45,42 +49,59 @@
 /// It's defined in our "dart:_interceptors".
 class JSNumber extends JSType {
   const JSNumber();
+  @override
   bool get isPrimitive => true;
+  @override
   bool get isPrimitiveInJS => true;
+  @override
   bool get isFalsey => true;
+  @override
   String get primitiveTypeOf => 'number';
 }
 
 /// Inhabited by null and undefined
 class JSNull extends JSType {
   const JSNull();
+  @override
   bool get isPrimitive => false;
+  @override
   bool get isPrimitiveInJS => false;
+  @override
   bool get isFalsey => true;
 }
 
 /// Inhabited by objects, null, and undefined
 class JSObject extends JSType {
   const JSObject();
+  @override
   bool get isPrimitive => false;
+  @override
   bool get isPrimitiveInJS => false;
+  @override
   bool get isFalsey => false;
 }
 
 /// Inhabited by strings (including JSString), null, and undefined
 class JSString extends JSType {
   const JSString();
+  @override
   bool get isPrimitive => true;
+  @override
   bool get isPrimitiveInJS => false;
+  @override
   bool get isFalsey => true;
+  @override
   String get primitiveTypeOf => 'string';
 }
 
 /// Inhabitance not statically known
 class JSUnknown extends JSType {
   const JSUnknown();
+  @override
   bool get isPrimitive => false;
+  @override
   bool get isPrimitiveInJS => false;
+  @override
   bool get isFalsey => true;
 }
 
diff --git a/pkg/dev_compiler/lib/src/compiler/module_builder.dart b/pkg/dev_compiler/lib/src/compiler/module_builder.dart
index f3db4fa..a6ebc20 100644
--- a/pkg/dev_compiler/lib/src/compiler/module_builder.dart
+++ b/pkg/dev_compiler/lib/src/compiler/module_builder.dart
@@ -58,7 +58,7 @@
         default:
           throw UsageException(
               'Format $format cannot be combined with '
-              'single-out-file. Only amd and legacy modes are supported.',
+                  'single-out-file. Only amd and legacy modes are supported.',
               '');
       }
     }
@@ -345,10 +345,10 @@
 
 /// Escape [name] to make it into a valid identifier.
 String toJSIdentifier(String name) {
-  if (name.length == 0) return r'$';
+  if (name.isEmpty) return r'$';
 
   // Escape any invalid characters
-  StringBuffer buffer = null;
+  StringBuffer buffer;
   for (int i = 0; i < name.length; i++) {
     var ch = name[i];
     var needsEscape = ch == r'$' || _invalidCharInIdentifier.hasMatch(ch);
diff --git a/pkg/dev_compiler/lib/src/compiler/shared_compiler.dart b/pkg/dev_compiler/lib/src/compiler/shared_compiler.dart
index d9270a2..05cc667 100644
--- a/pkg/dev_compiler/lib/src/compiler/shared_compiler.dart
+++ b/pkg/dev_compiler/lib/src/compiler/shared_compiler.dart
@@ -585,10 +585,12 @@
 
   static final instance = _IdentifierFinder();
 
+  @override
   visitIdentifier(node) {
     if (node.name == nameToFind) found = true;
   }
 
+  @override
   visitNode(node) {
     if (!found) super.visitNode(node);
   }
diff --git a/pkg/dev_compiler/lib/src/js_ast/builder.dart b/pkg/dev_compiler/lib/src/js_ast/builder.dart
index fc44cb9..2d0dd51 100644
--- a/pkg/dev_compiler/lib/src/js_ast/builder.dart
+++ b/pkg/dev_compiler/lib/src/js_ast/builder.dart
@@ -432,11 +432,12 @@
 }
 
 class MiniJsParserError {
-  MiniJsParserError(this.parser, this.message) {}
+  MiniJsParserError(this.parser, this.message);
 
   final MiniJsParser parser;
   final String message;
 
+  @override
   String toString() {
     int pos = parser.lastPosition;
 
@@ -491,7 +492,7 @@
   }
 
   int lastCategory = NONE;
-  String lastToken = null;
+  String lastToken;
   int lastPosition = 0;
   int position = 0;
   bool skippedNewline = false; // skipped newline in last getToken?
@@ -1550,12 +1551,12 @@
     //     for (let variable of Expression) Statement
     //
     Statement finishFor(Expression init) {
-      Expression condition = null;
+      Expression condition;
       if (!acceptCategory(SEMICOLON)) {
         condition = parseExpression();
         expectCategory(SEMICOLON);
       }
-      Expression update = null;
+      Expression update;
       if (!acceptCategory(RPAREN)) {
         update = parseExpression();
         expectCategory(RPAREN);
@@ -1613,9 +1614,9 @@
   Statement parseTry() {
     expectCategory(LBRACE);
     Block body = parseBlock();
-    Catch catchPart = null;
+    Catch catchPart;
     if (acceptString('catch')) catchPart = parseCatch();
-    Block finallyPart = null;
+    Block finallyPart;
     if (acceptString('finally')) {
       expectCategory(LBRACE);
       finallyPart = parseBlock();
@@ -1626,7 +1627,7 @@
   }
 
   SwitchCase parseSwitchClause() {
-    Expression expression = null;
+    Expression expression;
     if (acceptString('case')) {
       expression = parseExpression();
       expectCategory(COLON);
@@ -1689,7 +1690,7 @@
 
   ClassExpression parseClass() {
     Identifier name = parseIdentifier();
-    Expression heritage = null;
+    Expression heritage;
     if (acceptString('extends')) {
       heritage = parseConditional();
     }
@@ -1718,7 +1719,7 @@
 
     bool isGetter = lastToken == 'get';
     bool isSetter = lastToken == 'set';
-    Expression name = null;
+    Expression name;
     if (isGetter || isSetter) {
       var token = lastToken;
       getToken();
diff --git a/pkg/dev_compiler/lib/src/js_ast/nodes.dart b/pkg/dev_compiler/lib/src/js_ast/nodes.dart
index 9cd3b7b..36d2368 100644
--- a/pkg/dev_compiler/lib/src/js_ast/nodes.dart
+++ b/pkg/dev_compiler/lib/src/js_ast/nodes.dart
@@ -101,121 +101,197 @@
     return null;
   }
 
+  @override
   T visitProgram(Program node) => visitNode(node);
 
   T visitStatement(Statement node) => visitModuleItem(node);
   T visitLoop(Loop node) => visitStatement(node);
   T visitJump(Statement node) => visitStatement(node);
 
+  @override
   T visitBlock(Block node) => visitStatement(node);
+  @override
   T visitDebuggerStatement(node) => visitStatement(node);
+  @override
   T visitExpressionStatement(ExpressionStatement node) => visitStatement(node);
+  @override
   T visitEmptyStatement(EmptyStatement node) => visitStatement(node);
+  @override
   T visitIf(If node) => visitStatement(node);
+  @override
   T visitFor(For node) => visitLoop(node);
+  @override
   T visitForIn(ForIn node) => visitLoop(node);
+  @override
   T visitForOf(ForOf node) => visitLoop(node);
+  @override
   T visitWhile(While node) => visitLoop(node);
+  @override
   T visitDo(Do node) => visitLoop(node);
+  @override
   T visitContinue(Continue node) => visitJump(node);
+  @override
   T visitBreak(Break node) => visitJump(node);
+  @override
   T visitReturn(Return node) => visitJump(node);
+  @override
   T visitThrow(Throw node) => visitJump(node);
+  @override
   T visitTry(Try node) => visitStatement(node);
+  @override
   T visitSwitch(Switch node) => visitStatement(node);
+  @override
   T visitFunctionDeclaration(FunctionDeclaration node) => visitStatement(node);
+  @override
   T visitLabeledStatement(LabeledStatement node) => visitStatement(node);
+  @override
   T visitLiteralStatement(LiteralStatement node) => visitStatement(node);
 
+  @override
   T visitCatch(Catch node) => visitNode(node);
+  @override
   T visitSwitchCase(SwitchCase node) => visitNode(node);
 
   T visitExpression(Expression node) => visitNode(node);
 
+  @override
   T visitLiteralExpression(LiteralExpression node) => visitExpression(node);
+  @override
   T visitVariableDeclarationList(VariableDeclarationList node) =>
       visitExpression(node);
+  @override
   T visitAssignment(Assignment node) => visitExpression(node);
+  @override
   T visitVariableInitialization(VariableInitialization node) =>
       visitExpression(node);
 
+  @override
   T visitConditional(Conditional node) => visitExpression(node);
+  @override
   T visitNew(New node) => visitExpression(node);
+  @override
   T visitCall(Call node) => visitExpression(node);
+  @override
   T visitBinary(Binary node) => visitExpression(node);
+  @override
   T visitPrefix(Prefix node) => visitExpression(node);
+  @override
   T visitPostfix(Postfix node) => visitExpression(node);
+  @override
   T visitSpread(Spread node) => visitPrefix(node);
+  @override
   T visitYield(Yield node) => visitExpression(node);
+  @override
   T visitAccess(PropertyAccess node) => visitExpression(node);
 
+  @override
   T visitIdentifier(Identifier node) => visitExpression(node);
+  @override
   T visitThis(This node) => visitExpression(node);
+  @override
   T visitSuper(Super node) => visitExpression(node);
 
+  @override
   T visitRestParameter(RestParameter node) => visitNode(node);
 
+  @override
   T visitNamedFunction(NamedFunction node) => visitExpression(node);
   T visitFunctionExpression(FunctionExpression node) => visitExpression(node);
+  @override
   T visitFun(Fun node) => visitFunctionExpression(node);
+  @override
   T visitArrowFun(ArrowFun node) => visitFunctionExpression(node);
 
   T visitLiteral(Literal node) => visitExpression(node);
 
+  @override
   T visitLiteralBool(LiteralBool node) => visitLiteral(node);
+  @override
   T visitLiteralString(LiteralString node) => visitLiteral(node);
+  @override
   T visitLiteralNumber(LiteralNumber node) => visitLiteral(node);
+  @override
   T visitLiteralNull(LiteralNull node) => visitLiteral(node);
 
+  @override
   T visitArrayInitializer(ArrayInitializer node) => visitExpression(node);
+  @override
   T visitArrayHole(ArrayHole node) => visitExpression(node);
+  @override
   T visitObjectInitializer(ObjectInitializer node) => visitExpression(node);
+  @override
   T visitProperty(Property node) => visitNode(node);
+  @override
   T visitRegExpLiteral(RegExpLiteral node) => visitExpression(node);
+  @override
   T visitTemplateString(TemplateString node) => visitExpression(node);
+  @override
   T visitTaggedTemplate(TaggedTemplate node) => visitExpression(node);
 
+  @override
   T visitClassDeclaration(ClassDeclaration node) => visitStatement(node);
+  @override
   T visitClassExpression(ClassExpression node) => visitExpression(node);
+  @override
   T visitMethod(Method node) => visitProperty(node);
 
   T visitModuleItem(ModuleItem node) => visitNode(node);
+  @override
   T visitImportDeclaration(ImportDeclaration node) => visitModuleItem(node);
+  @override
   T visitExportDeclaration(ExportDeclaration node) => visitModuleItem(node);
+  @override
   T visitExportClause(ExportClause node) => visitNode(node);
+  @override
   T visitNameSpecifier(NameSpecifier node) => visitNode(node);
+  @override
   T visitModule(Module node) => visitNode(node);
 
   T visitInterpolatedNode(InterpolatedNode node) => visitNode(node);
 
+  @override
   T visitInterpolatedExpression(InterpolatedExpression node) =>
       visitInterpolatedNode(node);
+  @override
   T visitInterpolatedLiteral(InterpolatedLiteral node) =>
       visitInterpolatedNode(node);
+  @override
   T visitInterpolatedParameter(InterpolatedParameter node) =>
       visitInterpolatedNode(node);
+  @override
   T visitInterpolatedSelector(InterpolatedSelector node) =>
       visitInterpolatedNode(node);
+  @override
   T visitInterpolatedStatement(InterpolatedStatement node) =>
       visitInterpolatedNode(node);
+  @override
   T visitInterpolatedMethod(InterpolatedMethod node) =>
       visitInterpolatedNode(node);
+  @override
   T visitInterpolatedIdentifier(InterpolatedIdentifier node) =>
       visitInterpolatedNode(node);
 
   // Ignore comments by default.
+  @override
   T visitComment(Comment node) => null;
+  @override
   T visitCommentExpression(CommentExpression node) => null;
 
+  @override
   T visitAwait(Await node) => visitExpression(node);
+  @override
   T visitDartYield(DartYield node) => visitStatement(node);
 
   T visitBindingPattern(BindingPattern node) => visitNode(node);
+  @override
   T visitArrayBindingPattern(ArrayBindingPattern node) =>
       visitBindingPattern(node);
+  @override
   T visitObjectBindingPattern(ObjectBindingPattern node) =>
       visitBindingPattern(node);
+  @override
   T visitDestructuredVariable(DestructuredVariable node) => visitNode(node);
+  @override
   T visitSimpleBindingPattern(SimpleBindingPattern node) => visitNode(node);
 }
 
@@ -255,6 +331,7 @@
   }
 
   // For debugging
+  @override
   String toString() {
     var context = SimpleJavaScriptPrintingContext();
     var opts = JavaScriptPrintingOptions(allowKeywordsInProperties: true);
@@ -280,18 +357,23 @@
 
   Program(this.body, {this.scriptTag, this.name});
 
+  @override
   T accept<T>(NodeVisitor<T> visitor) => visitor.visitProgram(this);
+  @override
   void visitChildren(NodeVisitor visitor) {
-    for (ModuleItem statement in body) statement.accept(visitor);
+    for (ModuleItem statement in body) {
+      statement.accept(visitor);
+    }
   }
 
+  @override
   Program _clone() => Program(body);
 }
 
 abstract class Statement extends ModuleItem {
   static Statement from(List<Statement> statements) {
     // TODO(jmesserly): empty block singleton? Should this use empty statement?
-    if (statements.length == 0) return Block([]);
+    if (statements.isEmpty) return Block([]);
     if (statements.length == 1) return statements[0];
     return Block(statements);
   }
@@ -317,7 +399,9 @@
     return shadows(names) ? Block([this], isScope: true) : this;
   }
 
+  @override
   Statement toStatement() => this;
+  @override
   Statement toReturn() => Block([this, Return()]);
 
   Block toBlock() => Block([this]);
@@ -355,11 +439,16 @@
       ..sourceInformation = sourceInformation;
   }
 
+  @override
   T accept<T>(NodeVisitor<T> visitor) => visitor.visitBlock(this);
+  @override
   void visitChildren(NodeVisitor visitor) {
-    for (Statement statement in statements) statement.accept(visitor);
+    for (Statement statement in statements) {
+      statement.accept(visitor);
+    }
   }
 
+  @override
   Block _clone() => Block(statements);
 }
 
@@ -373,19 +462,25 @@
     return expression is VariableDeclarationList && expression.shadows(names);
   }
 
+  @override
   T accept<T>(NodeVisitor<T> visitor) => visitor.visitExpressionStatement(this);
+  @override
   void visitChildren(NodeVisitor visitor) {
     expression.accept(visitor);
   }
 
+  @override
   ExpressionStatement _clone() => ExpressionStatement(expression);
 }
 
 class EmptyStatement extends Statement {
   EmptyStatement();
 
+  @override
   T accept<T>(NodeVisitor<T> visitor) => visitor.visitEmptyStatement(this);
+  @override
   void visitChildren(NodeVisitor visitor) {}
+  @override
   EmptyStatement _clone() => EmptyStatement();
 }
 
@@ -403,14 +498,17 @@
 
   bool get hasElse => otherwise != null;
 
+  @override
   T accept<T>(NodeVisitor<T> visitor) => visitor.visitIf(this);
 
+  @override
   void visitChildren(NodeVisitor visitor) {
     condition.accept(visitor);
     then.accept(visitor);
     if (otherwise != null) otherwise.accept(visitor);
   }
 
+  @override
   If _clone() => If(condition, then, otherwise);
 }
 
@@ -426,8 +524,10 @@
 
   For(this.init, this.condition, this.update, Statement body) : super(body);
 
+  @override
   T accept<T>(NodeVisitor<T> visitor) => visitor.visitFor(this);
 
+  @override
   void visitChildren(NodeVisitor visitor) {
     if (init != null) init.accept(visitor);
     if (condition != null) condition.accept(visitor);
@@ -435,6 +535,7 @@
     body.accept(visitor);
   }
 
+  @override
   For _clone() => For(init, condition, update, body);
 }
 
@@ -446,14 +547,17 @@
 
   ForIn(this.leftHandSide, this.object, Statement body) : super(body);
 
+  @override
   T accept<T>(NodeVisitor<T> visitor) => visitor.visitForIn(this);
 
+  @override
   void visitChildren(NodeVisitor visitor) {
     leftHandSide.accept(visitor);
     object.accept(visitor);
     body.accept(visitor);
   }
 
+  @override
   ForIn _clone() => ForIn(leftHandSide, object, body);
 }
 
@@ -465,14 +569,17 @@
 
   ForOf(this.leftHandSide, this.iterable, Statement body) : super(body);
 
+  @override
   T accept<T>(NodeVisitor<T> visitor) => visitor.visitForOf(this);
 
+  @override
   void visitChildren(NodeVisitor visitor) {
     leftHandSide.accept(visitor);
     iterable.accept(visitor);
     body.accept(visitor);
   }
 
+  @override
   ForIn _clone() => ForIn(leftHandSide, iterable, body);
 }
 
@@ -481,13 +588,16 @@
 
   While(this.condition, Statement body) : super(body);
 
+  @override
   T accept<T>(NodeVisitor<T> visitor) => visitor.visitWhile(this);
 
+  @override
   void visitChildren(NodeVisitor visitor) {
     condition.accept(visitor);
     body.accept(visitor);
   }
 
+  @override
   While _clone() => While(condition, body);
 }
 
@@ -496,13 +606,16 @@
 
   Do(Statement body, this.condition) : super(body);
 
+  @override
   T accept<T>(NodeVisitor<T> visitor) => visitor.visitDo(this);
 
+  @override
   void visitChildren(NodeVisitor visitor) {
     body.accept(visitor);
     condition.accept(visitor);
   }
 
+  @override
   Do _clone() => Do(body, condition);
 }
 
@@ -511,9 +624,12 @@
 
   Continue(this.targetLabel);
 
+  @override
   T accept<T>(NodeVisitor<T> visitor) => visitor.visitContinue(this);
+  @override
   void visitChildren(NodeVisitor visitor) {}
 
+  @override
   Continue _clone() => Continue(targetLabel);
 }
 
@@ -522,28 +638,35 @@
 
   Break(this.targetLabel);
 
+  @override
   T accept<T>(NodeVisitor<T> visitor) => visitor.visitBreak(this);
+  @override
   void visitChildren(NodeVisitor visitor) {}
 
+  @override
   Break _clone() => Break(targetLabel);
 }
 
 class Return extends Statement {
   final Expression value; // Can be null.
 
-  Return([this.value = null]);
+  Return([this.value]);
 
   @override
   bool get alwaysReturns => true;
 
+  @override
   Statement toReturn() => this;
 
+  @override
   T accept<T>(NodeVisitor<T> visitor) => visitor.visitReturn(this);
 
+  @override
   void visitChildren(NodeVisitor visitor) {
     if (value != null) value.accept(visitor);
   }
 
+  @override
   Return _clone() => Return(value);
 
   static bool foundIn(Node node) {
@@ -557,10 +680,12 @@
 
 class _ReturnFinder extends BaseVisitor {
   bool found = false;
+  @override
   visitReturn(Return node) {
     found = true;
   }
 
+  @override
   visitNode(Node node) {
     if (!found) super.visitNode(node);
   }
@@ -571,12 +696,15 @@
 
   Throw(this.expression);
 
+  @override
   T accept<T>(NodeVisitor<T> visitor) => visitor.visitThrow(this);
 
+  @override
   void visitChildren(NodeVisitor visitor) {
     expression.accept(visitor);
   }
 
+  @override
   Throw _clone() => Throw(expression);
 }
 
@@ -589,14 +717,17 @@
     assert(catchPart != null || finallyPart != null);
   }
 
+  @override
   T accept<T>(NodeVisitor<T> visitor) => visitor.visitTry(this);
 
+  @override
   void visitChildren(NodeVisitor visitor) {
     body.accept(visitor);
     if (catchPart != null) catchPart.accept(visitor);
     if (finallyPart != null) finallyPart.accept(visitor);
   }
 
+  @override
   Try _clone() => Try(body, catchPart, finallyPart);
 }
 
@@ -606,13 +737,16 @@
 
   Catch(this.declaration, this.body);
 
+  @override
   T accept<T>(NodeVisitor<T> visitor) => visitor.visitCatch(this);
 
+  @override
   void visitChildren(NodeVisitor visitor) {
     declaration.accept(visitor);
     body.accept(visitor);
   }
 
+  @override
   Catch _clone() => Catch(declaration, body);
 }
 
@@ -622,13 +756,18 @@
 
   Switch(this.key, this.cases);
 
+  @override
   T accept<T>(NodeVisitor<T> visitor) => visitor.visitSwitch(this);
 
+  @override
   void visitChildren(NodeVisitor visitor) {
     key.accept(visitor);
-    for (var clause in cases) clause.accept(visitor);
+    for (var clause in cases) {
+      clause.accept(visitor);
+    }
   }
 
+  @override
   Switch _clone() => Switch(key, cases);
 }
 
@@ -641,13 +780,16 @@
 
   bool get isDefault => expression == null;
 
+  @override
   T accept<T>(NodeVisitor<T> visitor) => visitor.visitSwitchCase(this);
 
+  @override
   void visitChildren(NodeVisitor visitor) {
     expression?.accept(visitor);
     body.accept(visitor);
   }
 
+  @override
   SwitchCase _clone() => SwitchCase(expression, body);
 }
 
@@ -657,13 +799,16 @@
 
   FunctionDeclaration(this.name, this.function);
 
+  @override
   T accept<T>(NodeVisitor<T> visitor) => visitor.visitFunctionDeclaration(this);
 
+  @override
   void visitChildren(NodeVisitor visitor) {
     name.accept(visitor);
     function.accept(visitor);
   }
 
+  @override
   FunctionDeclaration _clone() => FunctionDeclaration(name, function);
 }
 
@@ -673,12 +818,15 @@
 
   LabeledStatement(this.label, this.body);
 
+  @override
   T accept<T>(NodeVisitor<T> visitor) => visitor.visitLabeledStatement(this);
 
+  @override
   void visitChildren(NodeVisitor visitor) {
     body.accept(visitor);
   }
 
+  @override
   LabeledStatement _clone() => LabeledStatement(label, body);
 }
 
@@ -687,9 +835,12 @@
 
   LiteralStatement(this.code);
 
+  @override
   T accept<T>(NodeVisitor<T> visitor) => visitor.visitLiteralStatement(this);
+  @override
   void visitChildren(NodeVisitor visitor) {}
 
+  @override
   LiteralStatement _clone() => LiteralStatement(code);
 }
 
@@ -702,12 +853,15 @@
 
   DartYield(this.expression, this.hasStar);
 
+  @override
   T accept<T>(NodeVisitor<T> visitor) => visitor.visitDartYield(this);
 
+  @override
   void visitChildren(NodeVisitor visitor) {
     expression.accept(visitor);
   }
 
+  @override
   DartYield _clone() => DartYield(expression, hasStar);
 }
 
@@ -715,7 +869,7 @@
   Expression();
 
   factory Expression.binary(List<Expression> exprs, String op) {
-    Expression comma = null;
+    Expression comma;
     for (var node in exprs) {
       comma = (comma == null) ? node : Binary(op, comma, node);
     }
@@ -724,7 +878,9 @@
 
   int get precedenceLevel;
 
+  @override
   Statement toStatement() => ExpressionStatement(toVoidExpression());
+  @override
   Statement toReturn() => Return(this);
 
   // TODO(jmesserly): make this return a Yield?
@@ -748,18 +904,24 @@
   LiteralExpression(this.template) : inputs = const [];
   LiteralExpression.withData(this.template, this.inputs);
 
+  @override
   T accept<T>(NodeVisitor<T> visitor) => visitor.visitLiteralExpression(this);
 
+  @override
   void visitChildren(NodeVisitor visitor) {
     if (inputs != null) {
-      for (Expression expr in inputs) expr.accept(visitor);
+      for (Expression expr in inputs) {
+        expr.accept(visitor);
+      }
     }
   }
 
+  @override
   LiteralExpression _clone() => LiteralExpression.withData(template, inputs);
 
   // Code that uses JS must take care of operator precedences, and
   // put parenthesis if needed.
+  @override
   int get precedenceLevel => PRIMARY;
 }
 
@@ -782,22 +944,28 @@
   /// Analogous to the predicate [Statement.shadows].
   bool shadows(Set<String> names) {
     if (keyword == 'var') return false;
-    for (var d in declarations) if (d.declaration.shadows(names)) return true;
+    for (var d in declarations) {
+      if (d.declaration.shadows(names)) return true;
+    }
     return false;
   }
 
+  @override
   T accept<T>(NodeVisitor<T> visitor) =>
       visitor.visitVariableDeclarationList(this);
 
+  @override
   void visitChildren(NodeVisitor visitor) {
     for (VariableInitialization declaration in declarations) {
       declaration.accept(visitor);
     }
   }
 
+  @override
   VariableDeclarationList _clone() =>
       VariableDeclarationList(keyword, declarations);
 
+  @override
   int get precedenceLevel => EXPRESSION;
 }
 
@@ -809,17 +977,21 @@
   Assignment(this.leftHandSide, this.value) : op = null;
   Assignment.compound(this.leftHandSide, this.op, this.value);
 
+  @override
   int get precedenceLevel => ASSIGNMENT;
 
   bool get isCompound => op != null;
 
+  @override
   T accept<T>(NodeVisitor<T> visitor) => visitor.visitAssignment(this);
 
+  @override
   void visitChildren(NodeVisitor visitor) {
     leftHandSide.accept(visitor);
     if (value != null) value.accept(visitor);
   }
 
+  @override
   Assignment _clone() => Assignment.compound(leftHandSide, op, value);
 }
 
@@ -830,13 +1002,17 @@
   /// [value] may be null.
   VariableInitialization(this.declaration, this.value);
 
+  @override
   T accept<T>(NodeVisitor<T> visitor) =>
       visitor.visitVariableInitialization(this);
 
+  @override
   VariableInitialization _clone() => VariableInitialization(declaration, value);
 
+  @override
   int get precedenceLevel => ASSIGNMENT;
 
+  @override
   void visitChildren(NodeVisitor visitor) {
     declaration.accept(visitor);
     if (value != null) value.accept(visitor);
@@ -872,13 +1048,16 @@
     assert(name != null || structure != null);
   }
 
+  @override
   bool shadows(Set<String> names) {
     return (name?.shadows(names) ?? false) ||
         (structure?.shadows(names) ?? false);
   }
 
+  @override
   T accept<T>(NodeVisitor<T> visitor) =>
       visitor.visitDestructuredVariable(this);
+  @override
   void visitChildren(NodeVisitor visitor) {
     name?.accept(visitor);
     structure?.accept(visitor);
@@ -902,13 +1081,19 @@
   final List<DestructuredVariable> variables;
   BindingPattern(this.variables);
 
+  @override
   bool shadows(Set<String> names) {
-    for (var v in variables) if (v.shadows(names)) return true;
+    for (var v in variables) {
+      if (v.shadows(names)) return true;
+    }
     return false;
   }
 
+  @override
   void visitChildren(NodeVisitor visitor) {
-    for (DestructuredVariable v in variables) v.accept(visitor);
+    for (DestructuredVariable v in variables) {
+      v.accept(visitor);
+    }
   }
 }
 
@@ -918,6 +1103,7 @@
       : name = name,
         super([DestructuredVariable(name: name)]);
 
+  @override
   T accept<T>(NodeVisitor<T> visitor) =>
       visitor.visitSimpleBindingPattern(this);
 
@@ -933,6 +1119,7 @@
 
 class ObjectBindingPattern extends BindingPattern {
   ObjectBindingPattern(List<DestructuredVariable> variables) : super(variables);
+  @override
   T accept<T>(NodeVisitor<T> visitor) =>
       visitor.visitObjectBindingPattern(this);
 
@@ -945,6 +1132,7 @@
 
 class ArrayBindingPattern extends BindingPattern {
   ArrayBindingPattern(List<DestructuredVariable> variables) : super(variables);
+  @override
   T accept<T>(NodeVisitor<T> visitor) => visitor.visitArrayBindingPattern(this);
 
   /// Avoid parenthesis when pretty-printing.
@@ -961,16 +1149,20 @@
 
   Conditional(this.condition, this.then, this.otherwise);
 
+  @override
   T accept<T>(NodeVisitor<T> visitor) => visitor.visitConditional(this);
 
+  @override
   void visitChildren(NodeVisitor visitor) {
     condition.accept(visitor);
     then.accept(visitor);
     otherwise.accept(visitor);
   }
 
+  @override
   Conditional _clone() => Conditional(condition, then, otherwise);
 
+  @override
   int get precedenceLevel => ASSIGNMENT;
 }
 
@@ -980,25 +1172,34 @@
 
   Call(this.target, this.arguments);
 
+  @override
   T accept<T>(NodeVisitor<T> visitor) => visitor.visitCall(this);
 
+  @override
   void visitChildren(NodeVisitor visitor) {
     target.accept(visitor);
-    for (Expression arg in arguments) arg.accept(visitor);
+    for (Expression arg in arguments) {
+      arg.accept(visitor);
+    }
   }
 
+  @override
   Call _clone() => Call(target, arguments);
 
+  @override
   int get precedenceLevel => CALL;
 }
 
 class New extends Call {
   New(Expression cls, List<Expression> arguments) : super(cls, arguments);
 
+  @override
   T accept<T>(NodeVisitor<T> visitor) => visitor.visitNew(this);
 
+  @override
   New _clone() => New(target, arguments);
 
+  @override
   int get precedenceLevel => ACCESS;
 }
 
@@ -1009,17 +1210,22 @@
 
   Binary(this.op, this.left, this.right);
 
+  @override
   T accept<T>(NodeVisitor<T> visitor) => visitor.visitBinary(this);
 
+  @override
   Binary _clone() => Binary(op, left, right);
 
+  @override
   void visitChildren(NodeVisitor visitor) {
     left.accept(visitor);
     right.accept(visitor);
   }
 
+  @override
   bool get isCommaOperator => op == ',';
 
+  @override
   Expression toVoidExpression() {
     if (!isCommaOperator) return super.toVoidExpression();
     var l = left.toVoidExpression();
@@ -1028,16 +1234,19 @@
     return Binary(',', l, r);
   }
 
+  @override
   Statement toStatement() {
     if (!isCommaOperator) return super.toStatement();
     return Block([left.toStatement(), right.toStatement()]);
   }
 
+  @override
   Statement toReturn() {
     if (!isCommaOperator) return super.toReturn();
     return Block([left.toStatement(), right.toReturn()]);
   }
 
+  @override
   Statement toYieldStatement({bool star = false}) {
     if (!isCommaOperator) return super.toYieldStatement(star: star);
     return Block([left.toStatement(), right.toYieldStatement(star: star)]);
@@ -1060,6 +1269,7 @@
     }
   }
 
+  @override
   int get precedenceLevel {
     // TODO(floitsch): switch to constant map.
     switch (op) {
@@ -1110,14 +1320,18 @@
 
   Prefix(this.op, this.argument);
 
+  @override
   T accept<T>(NodeVisitor<T> visitor) => visitor.visitPrefix(this);
 
+  @override
   Prefix _clone() => Prefix(op, argument);
 
+  @override
   void visitChildren(NodeVisitor visitor) {
     argument.accept(visitor);
   }
 
+  @override
   int get precedenceLevel => UNARY;
 }
 
@@ -1127,7 +1341,9 @@
 class Spread extends Prefix {
   Spread(Expression operand) : super('...', operand);
 
+  @override
   T accept<T>(NodeVisitor<T> visitor) => visitor.visitSpread(this);
+  @override
   Spread _clone() => Spread(argument);
 }
 
@@ -1137,14 +1353,18 @@
 
   Postfix(this.op, this.argument);
 
+  @override
   T accept<T>(NodeVisitor<T> visitor) => visitor.visitPostfix(this);
 
+  @override
   Postfix _clone() => Postfix(op, argument);
 
+  @override
   void visitChildren(NodeVisitor visitor) {
     argument.accept(visitor);
   }
 
+  @override
   int get precedenceLevel => UNARY;
 }
 
@@ -1163,12 +1383,18 @@
   }
   static RegExp _identifierRE = RegExp(r'^[A-Za-z_$][A-Za-z_$0-9]*$');
 
+  @override
   bool shadows(Set<String> names) => names.contains(name);
 
+  @override
   Identifier _clone() => Identifier(name, allowRename: allowRename);
+  @override
   T accept<T>(NodeVisitor<T> visitor) => visitor.visitIdentifier(this);
+  @override
   int get precedenceLevel => PRIMARY;
+  @override
   String get parameterName => name;
+  @override
   void visitChildren(NodeVisitor visitor) {}
 }
 
@@ -1178,31 +1404,45 @@
 
   RestParameter(this.parameter);
 
+  @override
   bool shadows(Set<String> names) => names.contains(parameter.name);
 
+  @override
   RestParameter _clone() => RestParameter(parameter);
+  @override
   T accept<T>(NodeVisitor<T> visitor) => visitor.visitRestParameter(this);
+  @override
   void visitChildren(NodeVisitor visitor) {
     parameter.accept(visitor);
   }
 
+  @override
   int get precedenceLevel => PRIMARY;
+  @override
   String get parameterName => parameter.parameterName;
 }
 
 class This extends Expression {
+  @override
   T accept<T>(NodeVisitor<T> visitor) => visitor.visitThis(this);
+  @override
   This _clone() => This();
+  @override
   int get precedenceLevel => PRIMARY;
+  @override
   void visitChildren(NodeVisitor visitor) {}
 }
 
 // `super` is more restricted in the ES6 spec, but for simplicity we accept
 // it anywhere that `this` is accepted.
 class Super extends Expression {
+  @override
   T accept<T>(NodeVisitor<T> visitor) => visitor.visitSuper(this);
+  @override
   Super _clone() => Super();
+  @override
   int get precedenceLevel => PRIMARY;
+  @override
   void visitChildren(NodeVisitor visitor) {}
 }
 
@@ -1216,15 +1456,19 @@
 
   NamedFunction(this.name, this.function, [this.immediatelyInvoked = false]);
 
+  @override
   T accept<T>(NodeVisitor<T> visitor) => visitor.visitNamedFunction(this);
 
+  @override
   void visitChildren(NodeVisitor visitor) {
     name.accept(visitor);
     function.accept(visitor);
   }
 
+  @override
   NamedFunction _clone() => NamedFunction(name, function, immediatelyInvoked);
 
+  @override
   int get precedenceLevel =>
       immediatelyInvoked ? EXPRESSION : PRIMARY_LOW_PRECEDENCE;
 }
@@ -1235,7 +1479,9 @@
 }
 
 class Fun extends FunctionExpression {
+  @override
   final List<Parameter> params;
+  @override
   final Block body;
 
   /** Whether this is a JS generator (`function*`) that may contain `yield`. */
@@ -1247,34 +1493,48 @@
       {this.isGenerator = false,
       this.asyncModifier = const AsyncModifier.sync()});
 
+  @override
   T accept<T>(NodeVisitor<T> visitor) => visitor.visitFun(this);
 
+  @override
   void visitChildren(NodeVisitor visitor) {
-    for (Parameter param in params) param.accept(visitor);
+    for (Parameter param in params) {
+      param.accept(visitor);
+    }
     body.accept(visitor);
   }
 
+  @override
   Fun _clone() =>
       Fun(params, body, isGenerator: isGenerator, asyncModifier: asyncModifier);
 
+  @override
   int get precedenceLevel => PRIMARY_LOW_PRECEDENCE;
 }
 
 class ArrowFun extends FunctionExpression {
+  @override
   final List<Parameter> params;
+  @override
   final body; // Expression or Block
 
   ArrowFun(this.params, this.body);
 
+  @override
   T accept<T>(NodeVisitor<T> visitor) => visitor.visitArrowFun(this);
 
+  @override
   void visitChildren(NodeVisitor visitor) {
-    for (Parameter param in params) param.accept(visitor);
+    for (Parameter param in params) {
+      param.accept(visitor);
+    }
     body.accept(visitor);
   }
 
+  @override
   int get precedenceLevel => PRIMARY_LOW_PRECEDENCE;
 
+  @override
   ArrowFun _clone() => ArrowFun(params, body);
 }
 
@@ -1305,6 +1565,7 @@
       : isAsync = false,
         isYielding = true,
         description = "sync*";
+  @override
   toString() => description;
 }
 
@@ -1318,21 +1579,27 @@
   PropertyAccess.indexed(this.receiver, int index)
       : selector = LiteralNumber('$index');
 
+  @override
   T accept<T>(NodeVisitor<T> visitor) => visitor.visitAccess(this);
 
+  @override
   void visitChildren(NodeVisitor visitor) {
     receiver.accept(visitor);
     selector.accept(visitor);
   }
 
+  @override
   PropertyAccess _clone() => PropertyAccess(receiver, selector);
 
+  @override
   int get precedenceLevel => ACCESS;
 }
 
 abstract class Literal extends Expression {
+  @override
   void visitChildren(NodeVisitor visitor) {}
 
+  @override
   int get precedenceLevel => PRIMARY;
 }
 
@@ -1341,15 +1608,19 @@
 
   LiteralBool(this.value);
 
+  @override
   T accept<T>(NodeVisitor<T> visitor) => visitor.visitLiteralBool(this);
   // [visitChildren] inherited from [Literal].
+  @override
   LiteralBool _clone() => LiteralBool(value);
 }
 
 class LiteralNull extends Literal {
   LiteralNull();
 
+  @override
   T accept<T>(NodeVisitor<T> visitor) => visitor.visitLiteralNull(this);
+  @override
   LiteralNull _clone() => LiteralNull();
 }
 
@@ -1371,7 +1642,9 @@
   /// Gets the value inside the string without the beginning and end quotes.
   String get valueWithoutQuotes => value.substring(1, value.length - 1);
 
+  @override
   T accept<T>(NodeVisitor<T> visitor) => visitor.visitLiteralString(this);
+  @override
   LiteralString _clone() => LiteralString(value);
 }
 
@@ -1380,13 +1653,16 @@
 
   LiteralNumber(this.value);
 
+  @override
   T accept<T>(NodeVisitor<T> visitor) => visitor.visitLiteralNumber(this);
+  @override
   LiteralNumber _clone() => LiteralNumber(value);
 
   /**
    * Use a different precedence level depending on whether the value contains a
    * dot to ensure we generate `(1).toString()` and `1.0.toString()`.
    */
+  @override
   int get precedenceLevel => value.contains('.') ? PRIMARY : UNARY;
 }
 
@@ -1396,14 +1672,20 @@
 
   ArrayInitializer(this.elements, {this.multiline = false});
 
+  @override
   T accept<T>(NodeVisitor<T> visitor) => visitor.visitArrayInitializer(this);
 
+  @override
   void visitChildren(NodeVisitor visitor) {
-    for (Expression element in elements) element.accept(visitor);
+    for (Expression element in elements) {
+      element.accept(visitor);
+    }
   }
 
+  @override
   ArrayInitializer _clone() => ArrayInitializer(elements);
 
+  @override
   int get precedenceLevel => PRIMARY;
 }
 
@@ -1412,12 +1694,16 @@
  * For example the list [1, , , 2] would contain two holes.
  */
 class ArrayHole extends Expression {
+  @override
   T accept<T>(NodeVisitor<T> visitor) => visitor.visitArrayHole(this);
 
+  @override
   void visitChildren(NodeVisitor visitor) {}
 
+  @override
   ArrayHole _clone() => ArrayHole();
 
+  @override
   int get precedenceLevel => PRIMARY;
 }
 
@@ -1431,14 +1717,20 @@
   ObjectInitializer(this.properties, {bool multiline = false})
       : _multiline = multiline;
 
+  @override
   T accept<T>(NodeVisitor<T> visitor) => visitor.visitObjectInitializer(this);
 
+  @override
   void visitChildren(NodeVisitor visitor) {
-    for (Property init in properties) init.accept(visitor);
+    for (Property init in properties) {
+      init.accept(visitor);
+    }
   }
 
+  @override
   ObjectInitializer _clone() => ObjectInitializer(properties);
 
+  @override
   int get precedenceLevel => PRIMARY;
   /**
    * If set to true, forces a vertical layout when using the [Printer].
@@ -1456,13 +1748,16 @@
 
   Property(this.name, this.value);
 
+  @override
   T accept<T>(NodeVisitor<T> visitor) => visitor.visitProperty(this);
 
+  @override
   void visitChildren(NodeVisitor visitor) {
     name.accept(visitor);
     value.accept(visitor);
   }
 
+  @override
   Property _clone() => Property(name, value);
 }
 
@@ -1492,16 +1787,20 @@
     assert(strings.length == interpolations.length + 1);
   }
 
+  @override
   T accept<T>(NodeVisitor<T> visitor) => visitor.visitTemplateString(this);
 
+  @override
   void visitChildren(NodeVisitor visitor) {
     for (var element in interpolations) {
       element.accept(visitor);
     }
   }
 
+  @override
   TemplateString _clone() => TemplateString(strings, interpolations);
 
+  @override
   int get precedenceLevel => PRIMARY;
 }
 
@@ -1512,15 +1811,19 @@
 
   TaggedTemplate(this.tag, this.template);
 
+  @override
   T accept<T>(NodeVisitor<T> visitor) => visitor.visitTaggedTemplate(this);
 
+  @override
   void visitChildren(NodeVisitor visitor) {
     tag.accept(visitor);
     template.accept(visitor);
   }
 
+  @override
   TaggedTemplate _clone() => TaggedTemplate(tag, template);
 
+  @override
   int get precedenceLevel => CALL;
 }
 
@@ -1536,14 +1839,18 @@
 
   Yield(this.value, {this.star = false});
 
+  @override
   T accept<T>(NodeVisitor<T> visitor) => visitor.visitYield(this);
 
+  @override
   void visitChildren(NodeVisitor visitor) {
     if (value != null) value.accept(visitor);
   }
 
+  @override
   Yield _clone() => Yield(value);
 
+  @override
   int get precedenceLevel => YIELD;
 }
 
@@ -1552,8 +1859,11 @@
 
   ClassDeclaration(this.classExpr);
 
+  @override
   T accept<T>(NodeVisitor<T> visitor) => visitor.visitClassDeclaration(this);
+  @override
   visitChildren(NodeVisitor visitor) => classExpr.accept(visitor);
+  @override
   ClassDeclaration _clone() => ClassDeclaration(classExpr);
 }
 
@@ -1564,23 +1874,30 @@
 
   ClassExpression(this.name, this.heritage, this.methods);
 
+  @override
   T accept<T>(NodeVisitor<T> visitor) => visitor.visitClassExpression(this);
 
+  @override
   void visitChildren(NodeVisitor visitor) {
     name.accept(visitor);
     if (heritage != null) heritage.accept(visitor);
-    for (Method element in methods) element.accept(visitor);
+    for (Method element in methods) {
+      element.accept(visitor);
+    }
   }
 
   @override
   ClassDeclaration toStatement() => ClassDeclaration(this);
 
+  @override
   ClassExpression _clone() => ClassExpression(name, heritage, methods);
 
+  @override
   int get precedenceLevel => PRIMARY_LOW_PRECEDENCE;
 }
 
 class Method extends Node implements Property {
+  @override
   final Expression name;
   final Fun function;
   final bool isGetter;
@@ -1589,20 +1906,24 @@
 
   Method(this.name, this.function,
       {this.isGetter = false, this.isSetter = false, this.isStatic = false}) {
-    assert(!isGetter || function.params.length == 0);
+    assert(!isGetter || function.params.isEmpty);
     assert(!isSetter || function.params.length == 1);
     assert(!isGetter && !isSetter || !function.isGenerator);
   }
 
+  @override
   Fun get value => function;
 
+  @override
   T accept<T>(NodeVisitor<T> visitor) => visitor.visitMethod(this);
 
+  @override
   void visitChildren(NodeVisitor visitor) {
     name.accept(visitor);
     function.accept(visitor);
   }
 
+  @override
   Method _clone() => Method(name, function,
       isGetter: isGetter, isSetter: isSetter, isStatic: isStatic);
 }
@@ -1616,76 +1937,103 @@
 }
 
 class InterpolatedExpression extends Expression with InterpolatedNode {
+  @override
   final nameOrPosition;
 
   InterpolatedExpression(this.nameOrPosition);
 
+  @override
   T accept<T>(NodeVisitor<T> visitor) =>
       visitor.visitInterpolatedExpression(this);
+  @override
   void visitChildren(NodeVisitor visitor) {}
+  @override
   InterpolatedExpression _clone() => InterpolatedExpression(nameOrPosition);
 
+  @override
   int get precedenceLevel => PRIMARY;
 }
 
 class InterpolatedLiteral extends Literal with InterpolatedNode {
+  @override
   final nameOrPosition;
 
   InterpolatedLiteral(this.nameOrPosition);
 
+  @override
   T accept<T>(NodeVisitor<T> visitor) => visitor.visitInterpolatedLiteral(this);
+  @override
   void visitChildren(NodeVisitor visitor) {}
+  @override
   InterpolatedLiteral _clone() => InterpolatedLiteral(nameOrPosition);
 }
 
 class InterpolatedParameter extends Expression
     with InterpolatedNode
     implements Identifier {
+  @override
   final nameOrPosition;
 
+  @override
   String get name {
     throw "InterpolatedParameter.name must not be invoked";
   }
 
+  @override
   String get parameterName {
     throw "InterpolatedParameter.parameterName must not be invoked";
   }
 
+  @override
   bool shadows(Set<String> names) => false;
 
+  @override
   bool get allowRename => false;
 
   InterpolatedParameter(this.nameOrPosition);
 
+  @override
   T accept<T>(NodeVisitor<T> visitor) =>
       visitor.visitInterpolatedParameter(this);
+  @override
   void visitChildren(NodeVisitor visitor) {}
+  @override
   InterpolatedParameter _clone() => InterpolatedParameter(nameOrPosition);
 
+  @override
   int get precedenceLevel => PRIMARY;
 }
 
 class InterpolatedSelector extends Expression with InterpolatedNode {
+  @override
   final nameOrPosition;
 
   InterpolatedSelector(this.nameOrPosition);
 
+  @override
   T accept<T>(NodeVisitor<T> visitor) =>
       visitor.visitInterpolatedSelector(this);
+  @override
   void visitChildren(NodeVisitor visitor) {}
+  @override
   InterpolatedSelector _clone() => InterpolatedSelector(nameOrPosition);
 
+  @override
   int get precedenceLevel => PRIMARY;
 }
 
 class InterpolatedStatement extends Statement with InterpolatedNode {
+  @override
   final nameOrPosition;
 
   InterpolatedStatement(this.nameOrPosition);
 
+  @override
   T accept<T>(NodeVisitor<T> visitor) =>
       visitor.visitInterpolatedStatement(this);
+  @override
   void visitChildren(NodeVisitor visitor) {}
+  @override
   InterpolatedStatement _clone() => InterpolatedStatement(nameOrPosition);
 }
 
@@ -1693,20 +2041,31 @@
 class InterpolatedMethod extends Expression
     with InterpolatedNode
     implements Method {
+  @override
   final nameOrPosition;
 
   InterpolatedMethod(this.nameOrPosition);
 
+  @override
   T accept<T>(NodeVisitor<T> visitor) => visitor.visitInterpolatedMethod(this);
+  @override
   void visitChildren(NodeVisitor visitor) {}
+  @override
   InterpolatedMethod _clone() => InterpolatedMethod(nameOrPosition);
 
+  @override
   int get precedenceLevel => PRIMARY;
+  @override
   Expression get name => throw _unsupported;
+  @override
   Fun get value => throw _unsupported;
+  @override
   bool get isGetter => throw _unsupported;
+  @override
   bool get isSetter => throw _unsupported;
+  @override
   bool get isStatic => throw _unsupported;
+  @override
   Fun get function => throw _unsupported;
   Error get _unsupported =>
       UnsupportedError('$runtimeType does not support this member.');
@@ -1715,21 +2074,30 @@
 class InterpolatedIdentifier extends Expression
     with InterpolatedNode
     implements Identifier {
+  @override
   final nameOrPosition;
 
   InterpolatedIdentifier(this.nameOrPosition);
 
+  @override
   bool shadows(Set<String> names) => false;
 
+  @override
   T accept<T>(NodeVisitor<T> visitor) =>
       visitor.visitInterpolatedIdentifier(this);
+  @override
   void visitChildren(NodeVisitor visitor) {}
+  @override
   InterpolatedIdentifier _clone() => InterpolatedIdentifier(nameOrPosition);
 
+  @override
   int get precedenceLevel => PRIMARY;
+  @override
   String get name => throw '$runtimeType does not support this member.';
+  @override
   String get parameterName =>
       throw '$runtimeType does not support this member.';
+  @override
   bool get allowRename => false;
 }
 
@@ -1744,10 +2112,14 @@
 
   RegExpLiteral(this.pattern);
 
+  @override
   T accept<T>(NodeVisitor<T> visitor) => visitor.visitRegExpLiteral(this);
+  @override
   void visitChildren(NodeVisitor visitor) {}
+  @override
   RegExpLiteral _clone() => RegExpLiteral(pattern);
 
+  @override
   int get precedenceLevel => PRIMARY;
 }
 
@@ -1763,9 +2135,13 @@
 
   Await(this.expression);
 
+  @override
   int get precedenceLevel => UNARY;
+  @override
   T accept<T>(NodeVisitor<T> visitor) => visitor.visitAwait(this);
+  @override
   void visitChildren(NodeVisitor visitor) => expression.accept(visitor);
+  @override
   Await _clone() => Await(expression);
 }
 
@@ -1780,9 +2156,12 @@
 
   Comment(this.comment);
 
+  @override
   T accept<T>(NodeVisitor<T> visitor) => visitor.visitComment(this);
+  @override
   Comment _clone() => Comment(comment);
 
+  @override
   void visitChildren(NodeVisitor visitor) {}
 }
 
@@ -1798,16 +2177,23 @@
 
   CommentExpression(this.comment, this.expression);
 
+  @override
   int get precedenceLevel => PRIMARY;
+  @override
   T accept<T>(NodeVisitor<T> visitor) => visitor.visitCommentExpression(this);
+  @override
   CommentExpression _clone() => CommentExpression(comment, expression);
 
+  @override
   void visitChildren(NodeVisitor visitor) => expression.accept(visitor);
 }
 
 class DebuggerStatement extends Statement {
+  @override
   T accept<T>(NodeVisitor<T> visitor) => visitor.visitDebuggerStatement(this);
+  @override
   DebuggerStatement _clone() => DebuggerStatement();
+  @override
   void visitChildren(NodeVisitor visitor) {}
 }
 
@@ -1842,14 +2228,19 @@
     return null;
   }
 
+  @override
   T accept<T>(NodeVisitor<T> visitor) => visitor.visitImportDeclaration(this);
+  @override
   void visitChildren(NodeVisitor visitor) {
     if (namedImports != null) {
-      for (NameSpecifier name in namedImports) name.accept(visitor);
+      for (NameSpecifier name in namedImports) {
+        name.accept(visitor);
+      }
     }
     from.accept(visitor);
   }
 
+  @override
   ImportDeclaration _clone() => ImportDeclaration(
       defaultBinding: defaultBinding, namedImports: namedImports, from: from);
 }
@@ -1897,8 +2288,11 @@
     throw StateError('invalid export declaration');
   }
 
+  @override
   T accept<T>(NodeVisitor<T> visitor) => visitor.visitExportDeclaration(this);
+  @override
   visitChildren(NodeVisitor visitor) => exported.accept(visitor);
+  @override
   ExportDeclaration _clone() =>
       ExportDeclaration(exported, isDefault: isDefault);
 }
@@ -1916,12 +2310,17 @@
   /** True if this is an `export *`. */
   bool get exportStar => exports.length == 1 && exports[0].isStar;
 
+  @override
   T accept<T>(NodeVisitor<T> visitor) => visitor.visitExportClause(this);
+  @override
   void visitChildren(NodeVisitor visitor) {
-    for (NameSpecifier name in exports) name.accept(visitor);
+    for (NameSpecifier name in exports) {
+      name.accept(visitor);
+    }
     if (from != null) from.accept(visitor);
   }
 
+  @override
   ExportClause _clone() => ExportClause(exports, from: from);
 }
 
@@ -1936,8 +2335,11 @@
   /** True if this is a `* as someName` specifier. */
   bool get isStar => name == null;
 
+  @override
   T accept<T>(NodeVisitor<T> visitor) => visitor.visitNameSpecifier(this);
+  @override
   void visitChildren(NodeVisitor visitor) {}
+  @override
   NameSpecifier _clone() => NameSpecifier(name, asName: asName);
 }
 
@@ -1951,10 +2353,15 @@
   final List<ModuleItem> body;
   Module(this.body, {this.name});
 
+  @override
   T accept<T>(NodeVisitor<T> visitor) => visitor.visitModule(this);
+  @override
   void visitChildren(NodeVisitor visitor) {
-    for (ModuleItem item in body) item.accept(visitor);
+    for (ModuleItem item in body) {
+      item.accept(visitor);
+    }
   }
 
+  @override
   Module _clone() => Module(body);
 }
diff --git a/pkg/dev_compiler/lib/src/js_ast/printer.dart b/pkg/dev_compiler/lib/src/js_ast/printer.dart
index bdd29bd..38b7fea 100644
--- a/pkg/dev_compiler/lib/src/js_ast/printer.dart
+++ b/pkg/dev_compiler/lib/src/js_ast/printer.dart
@@ -47,6 +47,7 @@
 class SimpleJavaScriptPrintingContext extends JavaScriptPrintingContext {
   final StringBuffer buffer = StringBuffer();
 
+  @override
   void emit(String string) {
     buffer.write(string);
   }
@@ -129,7 +130,7 @@
     if (!shouldCompressOutput) out(" ");
   }
 
-  String lastAddedString = null;
+  String lastAddedString;
   int get lastCharCode {
     if (lastAddedString == null) return 0;
     assert(lastAddedString.length != "");
@@ -233,6 +234,7 @@
     nodes.forEach(visit);
   }
 
+  @override
   visitProgram(Program program) {
     if (program.scriptTag != null) {
       out('#!${program.scriptTag}\n');
@@ -284,14 +286,17 @@
     if (needsNewline) lineOut();
   }
 
+  @override
   visitBlock(Block block) {
     blockOut(block, true, true);
   }
 
+  @override
   visitDebuggerStatement(node) {
     outIndentLn('debugger;');
   }
 
+  @override
   visitExpressionStatement(ExpressionStatement expressionStatement) {
     indent();
     visitNestedExpression(expressionStatement.expression, EXPRESSION,
@@ -299,6 +304,7 @@
     outSemicolonLn();
   }
 
+  @override
   visitEmptyStatement(EmptyStatement nop) {
     outIndentLn(";");
   }
@@ -352,10 +358,12 @@
     }
   }
 
+  @override
   visitIf(If node) {
     ifOut(node, true);
   }
 
+  @override
   visitFor(For loop) {
     outIndent("for");
     spaceOut();
@@ -380,6 +388,7 @@
     blockBody(loop.body, needsSeparation: false, needsNewline: true);
   }
 
+  @override
   visitForIn(ForIn loop) {
     outIndent("for");
     spaceOut();
@@ -394,6 +403,7 @@
     blockBody(loop.body, needsSeparation: false, needsNewline: true);
   }
 
+  @override
   visitForOf(ForOf loop) {
     outIndent("for");
     spaceOut();
@@ -408,6 +418,7 @@
     blockBody(loop.body, needsSeparation: false, needsNewline: true);
   }
 
+  @override
   visitWhile(While loop) {
     outIndent("while");
     spaceOut();
@@ -418,6 +429,7 @@
     blockBody(loop.body, needsSeparation: false, needsNewline: true);
   }
 
+  @override
   visitDo(Do loop) {
     outIndent("do");
     if (blockBody(loop.body, needsSeparation: true, needsNewline: false)) {
@@ -434,6 +446,7 @@
     outSemicolonLn();
   }
 
+  @override
   visitContinue(Continue node) {
     if (node.targetLabel == null) {
       outIndent("continue");
@@ -443,6 +456,7 @@
     outSemicolonLn();
   }
 
+  @override
   visitBreak(Break node) {
     if (node.targetLabel == null) {
       outIndent("break");
@@ -452,6 +466,7 @@
     outSemicolonLn();
   }
 
+  @override
   visitReturn(Return node) {
     if (node.value == null) {
       outIndent("return");
@@ -464,6 +479,7 @@
     outSemicolonLn();
   }
 
+  @override
   visitDartYield(DartYield node) {
     if (node.hasStar) {
       outIndent("yield*");
@@ -476,6 +492,7 @@
     outSemicolonLn();
   }
 
+  @override
   visitThrow(Throw node) {
     outIndent("throw");
     pendingSpace = true;
@@ -484,6 +501,7 @@
     outSemicolonLn();
   }
 
+  @override
   visitTry(Try node) {
     outIndent("try");
     blockBody(node.body, needsSeparation: true, needsNewline: false);
@@ -499,6 +517,7 @@
     }
   }
 
+  @override
   visitCatch(Catch node) {
     spaceOut();
     out("catch");
@@ -510,6 +529,7 @@
     blockBody(node.body, needsSeparation: false, needsNewline: false);
   }
 
+  @override
   visitSwitch(Switch node) {
     outIndent("switch");
     spaceOut();
@@ -525,6 +545,7 @@
     outIndentLn("}");
   }
 
+  @override
   visitSwitchCase(SwitchCase node) {
     if (node.isDefault) {
       outIndentLn("default:");
@@ -535,11 +556,12 @@
           newInForInit: false, newAtStatementBegin: false);
       outLn(":");
     }
-    if (!node.body.statements.isEmpty) {
+    if (node.body.statements.isNotEmpty) {
       blockOut(node.body, true, true);
     }
   }
 
+  @override
   visitLabeledStatement(LabeledStatement node) {
     outIndent("${node.label}:");
     blockBody(node.body, needsSeparation: false, needsNewline: true);
@@ -578,6 +600,7 @@
     localNamer.leaveScope();
   }
 
+  @override
   visitFunctionDeclaration(FunctionDeclaration declaration) {
     indent();
     var f = declaration.function;
@@ -616,6 +639,7 @@
     }
   }
 
+  @override
   visitVariableDeclarationList(VariableDeclarationList list) {
     // Note: keyword can be null for non-static field declarations.
     if (list.keyword != null) {
@@ -626,6 +650,7 @@
         newInForInit: inForInit, newAtStatementBegin: false);
   }
 
+  @override
   visitArrayBindingPattern(ArrayBindingPattern node) {
     out("[");
     visitCommaSeparated(node.variables, EXPRESSION,
@@ -633,6 +658,7 @@
     out("]");
   }
 
+  @override
   visitObjectBindingPattern(ObjectBindingPattern node) {
     out("{");
     visitCommaSeparated(node.variables, EXPRESSION,
@@ -640,6 +666,7 @@
     out("}");
   }
 
+  @override
   visitDestructuredVariable(DestructuredVariable node) {
     var name = node.name;
     var property = node.property;
@@ -668,10 +695,12 @@
     }
   }
 
+  @override
   visitSimpleBindingPattern(SimpleBindingPattern node) {
     visit(node.name);
   }
 
+  @override
   visitAssignment(Assignment assignment) {
     visitNestedExpression(assignment.leftHandSide, LEFT_HAND_SIDE,
         newInForInit: inForInit, newAtStatementBegin: atStatementBegin);
@@ -686,6 +715,7 @@
     }
   }
 
+  @override
   visitVariableInitialization(VariableInitialization init) {
     visitNestedExpression(init.declaration, LEFT_HAND_SIDE,
         newInForInit: inForInit, newAtStatementBegin: atStatementBegin);
@@ -698,6 +728,7 @@
     }
   }
 
+  @override
   visitConditional(Conditional cond) {
     visitNestedExpression(cond.condition, LOGICAL_OR,
         newInForInit: inForInit, newAtStatementBegin: atStatementBegin);
@@ -714,6 +745,7 @@
         newInForInit: inForInit, newAtStatementBegin: false);
   }
 
+  @override
   visitNew(New node) {
     out("new ");
     inNewTarget = true;
@@ -726,6 +758,7 @@
     out(")");
   }
 
+  @override
   visitCall(Call call) {
     visitNestedExpression(call.target, LEFT_HAND_SIDE,
         newInForInit: inForInit, newAtStatementBegin: atStatementBegin);
@@ -735,6 +768,7 @@
     out(")");
   }
 
+  @override
   visitBinary(Binary binary) {
     Expression left = binary.left;
     Expression right = binary.right;
@@ -835,6 +869,7 @@
         newInForInit: inForInit, newAtStatementBegin: false);
   }
 
+  @override
   visitPrefix(Prefix unary) {
     String op = unary.op;
     switch (op) {
@@ -863,8 +898,10 @@
         newInForInit: inForInit, newAtStatementBegin: false);
   }
 
+  @override
   visitSpread(Spread unary) => visitPrefix(unary);
 
+  @override
   visitYield(Yield yield) {
     out(yield.star ? "yield*" : "yield");
     if (yield.value == null) return;
@@ -873,24 +910,29 @@
         newInForInit: inForInit, newAtStatementBegin: false);
   }
 
+  @override
   visitPostfix(Postfix postfix) {
     visitNestedExpression(postfix.argument, LEFT_HAND_SIDE,
         newInForInit: inForInit, newAtStatementBegin: atStatementBegin);
     out(postfix.op);
   }
 
+  @override
   visitThis(This node) {
     out("this");
   }
 
+  @override
   visitSuper(Super node) {
     out("super");
   }
 
+  @override
   visitIdentifier(Identifier node) {
     out(localNamer.getName(node));
   }
 
+  @override
   visitRestParameter(RestParameter node) {
     out('...');
     visitIdentifier(node.parameter);
@@ -921,6 +963,7 @@
     return options.allowKeywordsInProperties || field != '"super"';
   }
 
+  @override
   visitAccess(PropertyAccess access) {
     // Normally we can omit parens on the receiver if it is a Call, even though
     // Call expressions have lower precedence. However this optimization doesn't
@@ -943,6 +986,7 @@
     propertyNameOut(access.selector, inAccess: true);
   }
 
+  @override
   visitNamedFunction(NamedFunction namedFunction) {
     var f = namedFunction.function;
     context.enterNode(f);
@@ -950,10 +994,12 @@
     context.exitNode(f);
   }
 
+  @override
   visitFun(Fun fun) {
     functionOut(fun, null);
   }
 
+  @override
   visitArrowFun(ArrowFun fun) {
     localNamer.enterScope(fun);
     if (fun.params.length == 1 && fun.params[0] is Identifier) {
@@ -984,14 +1030,17 @@
     localNamer.leaveScope();
   }
 
+  @override
   visitLiteralBool(LiteralBool node) {
     out(node.value ? "true" : "false");
   }
 
+  @override
   visitLiteralString(LiteralString node) {
     out(node.value);
   }
 
+  @override
   visitLiteralNumber(LiteralNumber node) {
     int charCode = node.value.codeUnitAt(0);
     if (charCode == charCodes.$MINUS && lastCharCode == charCodes.$MINUS) {
@@ -1000,10 +1049,12 @@
     out(node.value);
   }
 
+  @override
   visitLiteralNull(LiteralNull node) {
     out("null");
   }
 
+  @override
   visitArrayInitializer(ArrayInitializer node) {
     out("[");
     indentMore();
@@ -1038,10 +1089,12 @@
     out("]");
   }
 
+  @override
   visitArrayHole(ArrayHole node) {
     throw "Unreachable";
   }
 
+  @override
   visitObjectInitializer(ObjectInitializer node) {
     List<Property> properties = node.properties;
     out("{");
@@ -1067,6 +1120,7 @@
     out("}");
   }
 
+  @override
   visitProperty(Property node) {
     propertyNameOut(node.name);
     out(":");
@@ -1075,10 +1129,12 @@
         newInForInit: false, newAtStatementBegin: false);
   }
 
+  @override
   visitRegExpLiteral(RegExpLiteral node) {
     out(node.pattern);
   }
 
+  @override
   visitTemplateString(TemplateString node) {
     out('`');
     int len = node.interpolations.length;
@@ -1092,17 +1148,20 @@
     out('`');
   }
 
+  @override
   visitTaggedTemplate(TaggedTemplate node) {
     visit(node.tag);
     visit(node.template);
   }
 
+  @override
   visitClassDeclaration(ClassDeclaration node) {
     indent();
     visit(node.classExpr);
     lineOut();
   }
 
+  @override
   visitClassExpression(ClassExpression node) {
     localNamer.enterScope(node);
     out('class ');
@@ -1130,6 +1189,7 @@
     localNamer.leaveScope();
   }
 
+  @override
   visitMethod(Method node) {
     if (node.isStatic) {
       out('static ');
@@ -1189,6 +1249,7 @@
     }
   }
 
+  @override
   visitImportDeclaration(ImportDeclaration node) {
     indent();
     out('import ');
@@ -1204,6 +1265,7 @@
     outSemicolonLn();
   }
 
+  @override
   visitExportDeclaration(ExportDeclaration node) {
     indent();
     out('export ');
@@ -1213,6 +1275,7 @@
     outSemicolonLn();
   }
 
+  @override
   visitExportClause(ExportClause node) {
     nameSpecifierListOut(node.exports, true);
     fromClauseOut(node.from);
@@ -1248,6 +1311,7 @@
   }
 
   /// This is unused, see [nameSpecifierOut].
+  @override
   visitNameSpecifier(NameSpecifier node) {
     throw UnsupportedError('visitNameSpecifier');
   }
@@ -1276,10 +1340,12 @@
     }
   }
 
+  @override
   visitModule(Module node) {
     visitAll(node.body);
   }
 
+  @override
   visitLiteralExpression(LiteralExpression node) {
     String template = node.template;
     List<Expression> inputs = node.inputs;
@@ -1298,6 +1364,7 @@
     }
   }
 
+  @override
   visitLiteralStatement(LiteralStatement node) {
     outLn(node.code);
   }
@@ -1306,28 +1373,36 @@
     out('#${node.nameOrPosition}');
   }
 
+  @override
   visitInterpolatedExpression(InterpolatedExpression node) =>
       visitInterpolatedNode(node);
 
+  @override
   visitInterpolatedLiteral(InterpolatedLiteral node) =>
       visitInterpolatedNode(node);
 
+  @override
   visitInterpolatedParameter(InterpolatedParameter node) =>
       visitInterpolatedNode(node);
 
+  @override
   visitInterpolatedSelector(InterpolatedSelector node) =>
       visitInterpolatedNode(node);
 
+  @override
   visitInterpolatedMethod(InterpolatedMethod node) =>
       visitInterpolatedNode(node);
 
+  @override
   visitInterpolatedIdentifier(InterpolatedIdentifier node) =>
       visitInterpolatedNode(node);
 
+  @override
   visitInterpolatedStatement(InterpolatedStatement node) {
     outLn('#${node.nameOrPosition}');
   }
 
+  @override
   void visitComment(Comment node) {
     if (shouldCompressOutput) return;
     String comment = node.comment.trim();
@@ -1341,6 +1416,7 @@
     }
   }
 
+  @override
   void visitCommentExpression(CommentExpression node) {
     if (shouldCompressOutput) return;
     String comment = node.comment.trim();
@@ -1353,6 +1429,7 @@
     visit(node.expression);
   }
 
+  @override
   void visitAwait(Await node) {
     out("await ");
     visit(node.expression);
@@ -1389,39 +1466,49 @@
     }
   }
 
+  @override
   void visitFunctionDeclaration(FunctionDeclaration declaration) {
     // Note that we don't bother collecting the name of the function.
     collectVarsInFunction(declaration.function);
   }
 
+  @override
   void visitNamedFunction(NamedFunction namedFunction) {
     // Note that we don't bother collecting the name of the function.
     collectVarsInFunction(namedFunction.function);
   }
 
+  @override
   void visitMethod(Method declaration) {
     collectVarsInFunction(declaration.function);
   }
 
+  @override
   void visitFun(Fun fun) {
     collectVarsInFunction(fun);
   }
 
+  @override
   void visitArrowFun(ArrowFun fun) {
     collectVarsInFunction(fun);
   }
 
+  @override
   void visitClassExpression(ClassExpression node) {
     // Note that we don't bother collecting the name of the class.
     if (node.heritage != null) node.heritage.accept(this);
-    for (Method method in node.methods) method.accept(this);
+    for (Method method in node.methods) {
+      method.accept(this);
+    }
   }
 
+  @override
   void visitCatch(Catch node) {
     declareVariable(node.declaration);
     node.body.accept(this);
   }
 
+  @override
   void visitVariableInitialization(VariableInitialization node) {
     // TODO(jmesserly): add ES6 support. Currently not needed because
     // dart2js does not emit ES6 rest param or destructuring.
@@ -1443,30 +1530,46 @@
 
   DanglingElseVisitor(this.context);
 
+  @override
   bool visitProgram(Program node) => false;
 
+  @override
   bool visitNode(Node node) {
     context.error("Forgot node: $node");
     return null;
   }
 
+  @override
   bool visitBlock(Block node) => false;
+  @override
   bool visitExpressionStatement(ExpressionStatement node) => false;
+  @override
   bool visitEmptyStatement(EmptyStatement node) => false;
+  @override
   bool visitIf(If node) {
     if (!node.hasElse) return true;
     return node.otherwise.accept(this);
   }
 
+  @override
   bool visitFor(For node) => node.body.accept(this);
+  @override
   bool visitForIn(ForIn node) => node.body.accept(this);
+  @override
   bool visitForOf(ForOf node) => node.body.accept(this);
+  @override
   bool visitWhile(While node) => node.body.accept(this);
+  @override
   bool visitDo(Do node) => false;
+  @override
   bool visitContinue(Continue node) => false;
+  @override
   bool visitBreak(Break node) => false;
+  @override
   bool visitReturn(Return node) => false;
+  @override
   bool visitThrow(Throw node) => false;
+  @override
   bool visitTry(Try node) {
     if (node.finallyPart != null) {
       return node.finallyPart.accept(this);
@@ -1475,14 +1578,22 @@
     }
   }
 
+  @override
   bool visitCatch(Catch node) => node.body.accept(this);
+  @override
   bool visitSwitch(Switch node) => false;
+  @override
   bool visitSwitchCase(SwitchCase node) => false;
+  @override
   bool visitFunctionDeclaration(FunctionDeclaration node) => false;
+  @override
   bool visitLabeledStatement(LabeledStatement node) => node.body.accept(this);
+  @override
   bool visitLiteralStatement(LiteralStatement node) => true;
+  @override
   bool visitClassDeclaration(ClassDeclaration node) => false;
 
+  @override
   bool visitExpression(Expression node) => false;
 }
 
@@ -1493,8 +1604,11 @@
 }
 
 class IdentityNamer implements LocalNamer {
+  @override
   String getName(Identifier node) => node.name;
+  @override
   void enterScope(Node node) {}
+  @override
   void leaveScope() {}
 }
 
@@ -1505,6 +1619,7 @@
   int parameterNumber = 0;
   int variableNumber = 0;
 
+  @override
   void enterScope(Node node) {
     var vars = VarCollector();
     node.accept(vars);
@@ -1515,12 +1630,14 @@
     vars.forEachParam(declareParameter);
   }
 
+  @override
   void leaveScope() {
     maps.removeLast();
     variableNumber = variableNumberStack.removeLast();
     parameterNumber = parameterNumberStack.removeLast();
   }
 
+  @override
   String getName(Identifier node) {
     String oldName = node.name;
     // Go from inner scope to outer looking for mapping of name.
@@ -1625,6 +1742,7 @@
 abstract class VariableDeclarationVisitor extends BaseVisitor<void> {
   declare(Identifier node);
 
+  @override
   visitFunctionExpression(FunctionExpression node) {
     node.params.forEach(_scanVariableBinding);
     node.body.accept(this);
@@ -1638,45 +1756,55 @@
     }
   }
 
+  @override
   visitRestParameter(RestParameter node) {
     _scanVariableBinding(node.parameter);
     super.visitRestParameter(node);
   }
 
+  @override
   visitDestructuredVariable(DestructuredVariable node) {
     var name = node.name;
     if (name is Identifier) _scanVariableBinding(name);
     super.visitDestructuredVariable(node);
   }
 
+  @override
   visitSimpleBindingPattern(SimpleBindingPattern node) {
     _scanVariableBinding(node.name);
     super.visitSimpleBindingPattern(node);
   }
 
+  @override
   visitVariableInitialization(VariableInitialization node) {
     _scanVariableBinding(node.declaration);
     if (node.value != null) node.value.accept(this);
   }
 
+  @override
   visitCatch(Catch node) {
     declare(node.declaration);
     node.body.accept(this);
   }
 
+  @override
   visitFunctionDeclaration(FunctionDeclaration node) {
     declare(node.name);
     node.function.accept(this);
   }
 
+  @override
   visitNamedFunction(NamedFunction node) {
     declare(node.name);
     node.function.accept(this);
   }
 
+  @override
   visitClassExpression(ClassExpression node) {
     declare(node.name);
     if (node.heritage != null) node.heritage.accept(this);
-    for (Method element in node.methods) element.accept(this);
+    for (Method element in node.methods) {
+      element.accept(this);
+    }
   }
 }
diff --git a/pkg/dev_compiler/lib/src/js_ast/source_map_printer.dart b/pkg/dev_compiler/lib/src/js_ast/source_map_printer.dart
index af5a5b6..d9e7da8 100644
--- a/pkg/dev_compiler/lib/src/js_ast/source_map_printer.dart
+++ b/pkg/dev_compiler/lib/src/js_ast/source_map_printer.dart
@@ -9,12 +9,14 @@
 class NodeEnd {
   final SourceLocation end;
   NodeEnd(this.end);
+  @override
   toString() => '#<NodeEnd $end>';
 }
 
 class NodeSpan {
   final SourceLocation start, end;
   NodeSpan(this.start, this.end);
+  @override
   toString() => '#<NodeSpan $start to $end>';
 }
 
@@ -22,6 +24,7 @@
   final SourceLocation start, end;
   final Expression expression;
   HoverComment(this.expression, this.start, this.end);
+  @override
   toString() => '#<HoverComment `$expression` @ $start to $end>';
 }
 
diff --git a/pkg/dev_compiler/lib/src/js_ast/template.dart b/pkg/dev_compiler/lib/src/js_ast/template.dart
index 178b15c..b876e7c 100644
--- a/pkg/dev_compiler/lib/src/js_ast/template.dart
+++ b/pkg/dev_compiler/lib/src/js_ast/template.dart
@@ -176,6 +176,7 @@
     throw UnimplementedError('visit${node.runtimeType}');
   }
 
+  @override
   Instantiator<Expression> visitInterpolatedExpression(
       InterpolatedExpression node) {
     var nameOrPosition = node.nameOrPosition;
@@ -212,7 +213,9 @@
     for (var instantiator in makers) {
       var result = instantiator(args);
       if (result is Iterable) {
-        for (var e in result) exprs.add(e as T);
+        for (var e in result) {
+          exprs.add(e as T);
+        }
       } else {
         exprs.add(result as T);
       }
@@ -220,6 +223,7 @@
     return exprs;
   }
 
+  @override
   Instantiator<Literal> visitInterpolatedLiteral(InterpolatedLiteral node) {
     var nameOrPosition = node.nameOrPosition;
     return (arguments) {
@@ -230,6 +234,7 @@
     };
   }
 
+  @override
   Instantiator visitInterpolatedParameter(InterpolatedParameter node) {
     var nameOrPosition = node.nameOrPosition;
     return (arguments) {
@@ -248,6 +253,7 @@
     };
   }
 
+  @override
   Instantiator<Expression> visitInterpolatedSelector(
       InterpolatedSelector node) {
     // A selector is an expression, as in `a[selector]`.
@@ -263,6 +269,7 @@
     };
   }
 
+  @override
   Instantiator<Statement> visitInterpolatedStatement(
       InterpolatedStatement node) {
     var nameOrPosition = node.nameOrPosition;
@@ -274,6 +281,7 @@
     };
   }
 
+  @override
   Instantiator visitInterpolatedMethod(InterpolatedMethod node) {
     var nameOrPosition = node.nameOrPosition;
     return (arguments) {
@@ -289,6 +297,7 @@
     };
   }
 
+  @override
   Instantiator<Identifier> visitInterpolatedIdentifier(
       InterpolatedIdentifier node) {
     var nameOrPosition = node.nameOrPosition;
@@ -320,6 +329,7 @@
     return visit(node);
   }
 
+  @override
   Instantiator<Program> visitProgram(Program node) {
     var instantiators = node.body.map(visitSplayableStatement).toList();
     return (a) => Program(splayStatements(instantiators, a));
@@ -331,7 +341,9 @@
       var node = instantiator(arguments);
       if (node is EmptyStatement) continue;
       if (node is Iterable) {
-        for (var n in node) statements.add(n as Statement);
+        for (var n in node) {
+          statements.add(n as Statement);
+        }
       } else if (node is Block && !node.isScope) {
         statements.addAll(node.statements);
       } else {
@@ -341,22 +353,27 @@
     return statements;
   }
 
+  @override
   Instantiator<Block> visitBlock(Block node) {
     var instantiators = node.statements.map(visitSplayableStatement).toList();
     return (a) => Block(splayStatements(instantiators, a));
   }
 
+  @override
   Instantiator<Statement> visitExpressionStatement(ExpressionStatement node) {
     Instantiator<Expression> makeExpression = visit(node.expression);
     return (a) => makeExpression(a).toStatement();
   }
 
+  @override
   Instantiator<DebuggerStatement> visitDebuggerStatement(node) =>
       (a) => DebuggerStatement();
 
+  @override
   Instantiator<EmptyStatement> visitEmptyStatement(EmptyStatement node) =>
       (a) => EmptyStatement();
 
+  @override
   Instantiator<Statement> visitIf(If node) {
     var condition = node.condition;
     if (condition is InterpolatedExpression) {
@@ -389,6 +406,7 @@
     return (a) => If(makeCondition(a), makeThen(a), makeOtherwise(a));
   }
 
+  @override
   Instantiator<Statement> visitFor(For node) {
     Instantiator<Expression> makeInit = visitNullable(node.init);
     Instantiator<Expression> makeCondition = visitNullable(node.condition);
@@ -398,6 +416,7 @@
         makeUpdate(a)?.toVoidExpression(), makeBody(a));
   }
 
+  @override
   Instantiator<ForIn> visitForIn(ForIn node) {
     Instantiator<Expression> makeLeftHandSide = visit(node.leftHandSide);
     Instantiator<Expression> makeObject = visit(node.object);
@@ -405,6 +424,7 @@
     return (a) => ForIn(makeLeftHandSide(a), makeObject(a), makeBody(a));
   }
 
+  @override
   Instantiator<ForOf> visitForOf(ForOf node) {
     Instantiator<Expression> makeLeftHandSide = visit(node.leftHandSide);
     Instantiator<Expression> makeObject = visit(node.iterable);
@@ -412,39 +432,47 @@
     return (a) => ForOf(makeLeftHandSide(a), makeObject(a), makeBody(a));
   }
 
+  @override
   Instantiator<While> visitWhile(While node) {
     Instantiator<Expression> makeCondition = visit(node.condition);
     Instantiator<Statement> makeBody = visit(node.body);
     return (a) => While(makeCondition(a), makeBody(a));
   }
 
+  @override
   Instantiator<Do> visitDo(Do node) {
     Instantiator<Statement> makeBody = visit(node.body);
     Instantiator<Expression> makeCondition = visit(node.condition);
     return (a) => Do(makeBody(a), makeCondition(a));
   }
 
+  @override
   Instantiator<Continue> visitContinue(Continue node) =>
       (a) => Continue(node.targetLabel);
 
+  @override
   Instantiator<Break> visitBreak(Break node) => (a) => Break(node.targetLabel);
 
+  @override
   Instantiator<Statement> visitReturn(Return node) {
     if (node.value == null) return (args) => Return();
     Instantiator<Expression> makeExpression = visit(node.value);
     return (a) => makeExpression(a).toReturn();
   }
 
+  @override
   Instantiator<DartYield> visitDartYield(DartYield node) {
     Instantiator<Expression> makeExpression = visit(node.expression);
     return (a) => DartYield(makeExpression(a), node.hasStar);
   }
 
+  @override
   Instantiator<Throw> visitThrow(Throw node) {
     Instantiator<Expression> makeExpression = visit(node.expression);
     return (a) => Throw(makeExpression(a));
   }
 
+  @override
   Instantiator<Try> visitTry(Try node) {
     Instantiator<Block> makeBody = visit(node.body);
     Instantiator<Catch> makeCatch = visitNullable(node.catchPart);
@@ -452,18 +480,21 @@
     return (a) => Try(makeBody(a), makeCatch(a), makeFinally(a));
   }
 
+  @override
   Instantiator<Catch> visitCatch(Catch node) {
     Instantiator<Identifier> makeDeclaration = visit(node.declaration);
     Instantiator<Block> makeBody = visit(node.body);
     return (a) => Catch(makeDeclaration(a), makeBody(a));
   }
 
+  @override
   Instantiator<Switch> visitSwitch(Switch node) {
     Instantiator<Expression> makeKey = visit(node.key);
     var makeCases = node.cases.map(visitSwitchCase).toList();
     return (a) => Switch(makeKey(a), makeCases.map((m) => m(a)).toList());
   }
 
+  @override
   Instantiator<SwitchCase> visitSwitchCase(SwitchCase node) {
     Instantiator<Expression> makeExpression = visitNullable(node.expression);
     Instantiator<Block> makeBody = visit(node.body);
@@ -472,6 +503,7 @@
     };
   }
 
+  @override
   Instantiator<FunctionDeclaration> visitFunctionDeclaration(
       FunctionDeclaration node) {
     Instantiator<Identifier> makeName = visit(node.name);
@@ -479,15 +511,19 @@
     return (a) => FunctionDeclaration(makeName(a), makeFunction(a));
   }
 
+  @override
   Instantiator<LabeledStatement> visitLabeledStatement(LabeledStatement node) {
     Instantiator<Statement> makeBody = visit(node.body);
     return (a) => LabeledStatement(node.label, makeBody(a));
   }
 
+  @override
   Instantiator visitLiteralStatement(LiteralStatement node) => visitNode(node);
+  @override
   Instantiator visitLiteralExpression(LiteralExpression node) =>
       visitNode(node);
 
+  @override
   Instantiator<VariableDeclarationList> visitVariableDeclarationList(
       VariableDeclarationList node) {
     var declarationMakers =
@@ -496,6 +532,7 @@
         node.keyword, declarationMakers.map((m) => m(a)).toList());
   }
 
+  @override
   Instantiator<Expression> visitAssignment(Assignment node) {
     Instantiator makeLeftHandSide = visit(node.leftHandSide);
     String op = node.op;
@@ -506,6 +543,7 @@
     };
   }
 
+  @override
   Instantiator<VariableInitialization> visitVariableInitialization(
       VariableInitialization node) {
     Instantiator<VariableBinding> makeDeclaration = visit(node.declaration);
@@ -513,6 +551,7 @@
     return (a) => VariableInitialization(makeDeclaration(a), makeValue(a));
   }
 
+  @override
   Instantiator<Conditional> visitConditional(Conditional cond) {
     Instantiator<Expression> makeCondition = visit(cond.condition);
     Instantiator<Expression> makeThen = visit(cond.then);
@@ -520,8 +559,10 @@
     return (a) => Conditional(makeCondition(a), makeThen(a), makeOtherwise(a));
   }
 
+  @override
   Instantiator<Call> visitNew(New node) => handleCallOrNew(node, true);
 
+  @override
   Instantiator<Call> visitCall(Call node) => handleCallOrNew(node, false);
 
   Instantiator<Call> handleCallOrNew(Call node, bool isNew) {
@@ -537,6 +578,7 @@
     };
   }
 
+  @override
   Instantiator<Binary> visitBinary(Binary node) {
     Instantiator<Expression> makeLeft = visit(node.left);
     Instantiator<Expression> makeRight = visit(node.right);
@@ -544,51 +586,62 @@
     return (a) => Binary(op, makeLeft(a), makeRight(a));
   }
 
+  @override
   Instantiator<Prefix> visitPrefix(Prefix node) {
     Instantiator<Expression> makeOperand = visit(node.argument);
     String op = node.op;
     return (a) => Prefix(op, makeOperand(a));
   }
 
+  @override
   Instantiator<Postfix> visitPostfix(Postfix node) {
     Instantiator<Expression> makeOperand = visit(node.argument);
     String op = node.op;
     return (a) => Postfix(op, makeOperand(a));
   }
 
+  @override
   Instantiator<This> visitThis(This node) => (a) => This();
+  @override
   Instantiator<Super> visitSuper(Super node) => (a) => Super();
 
+  @override
   Instantiator<Identifier> visitIdentifier(Identifier node) =>
       (a) => Identifier(node.name);
 
+  @override
   Instantiator<Spread> visitSpread(Spread node) {
     var maker = visit(node.argument);
     return (a) => Spread(maker(a) as Expression);
   }
 
+  @override
   Instantiator<Yield> visitYield(Yield node) {
     var maker = visitNullable(node.value);
     return (a) => Yield(maker(a) as Expression, star: node.star);
   }
 
+  @override
   Instantiator<RestParameter> visitRestParameter(RestParameter node) {
     var maker = visit(node.parameter);
     return (a) => RestParameter(maker(a) as Identifier);
   }
 
+  @override
   Instantiator<PropertyAccess> visitAccess(PropertyAccess node) {
     Instantiator<Expression> makeReceiver = visit(node.receiver);
     Instantiator<Expression> makeSelector = visit(node.selector);
     return (a) => PropertyAccess(makeReceiver(a), makeSelector(a));
   }
 
+  @override
   Instantiator<NamedFunction> visitNamedFunction(NamedFunction node) {
     Instantiator<Identifier> makeDeclaration = visit(node.name);
     Instantiator<Fun> makeFunction = visit(node.function);
     return (a) => NamedFunction(makeDeclaration(a), makeFunction(a));
   }
 
+  @override
   Instantiator<Fun> visitFun(Fun node) {
     var paramMakers = node.params.map(visitSplayable).toList();
     Instantiator<Block> makeBody = visit(node.body);
@@ -596,64 +649,78 @@
         isGenerator: node.isGenerator, asyncModifier: node.asyncModifier);
   }
 
+  @override
   Instantiator<ArrowFun> visitArrowFun(ArrowFun node) {
     var paramMakers = node.params.map(visitSplayable).toList();
     Instantiator makeBody = visit(node.body);
     return (a) => ArrowFun(splayNodes(paramMakers, a), makeBody(a));
   }
 
+  @override
   Instantiator<LiteralBool> visitLiteralBool(LiteralBool node) =>
       (a) => LiteralBool(node.value);
 
+  @override
   Instantiator<LiteralString> visitLiteralString(LiteralString node) =>
       (a) => LiteralString(node.value);
 
+  @override
   Instantiator<LiteralNumber> visitLiteralNumber(LiteralNumber node) =>
       (a) => LiteralNumber(node.value);
 
+  @override
   Instantiator<LiteralNull> visitLiteralNull(LiteralNull node) =>
       (a) => LiteralNull();
 
+  @override
   Instantiator<ArrayInitializer> visitArrayInitializer(ArrayInitializer node) {
     var makers = node.elements.map(visitSplayableExpression).toList();
     return (a) => ArrayInitializer(splayNodes(makers, a));
   }
 
+  @override
   Instantiator visitArrayHole(ArrayHole node) {
     return (arguments) => ArrayHole();
   }
 
+  @override
   Instantiator<ObjectInitializer> visitObjectInitializer(
       ObjectInitializer node) {
     var propertyMakers = node.properties.map(visitSplayable).toList();
     return (a) => ObjectInitializer(splayNodes(propertyMakers, a));
   }
 
+  @override
   Instantiator<Property> visitProperty(Property node) {
     Instantiator<Expression> makeName = visit(node.name);
     Instantiator<Expression> makeValue = visit(node.value);
     return (a) => Property(makeName(a), makeValue(a));
   }
 
+  @override
   Instantiator<RegExpLiteral> visitRegExpLiteral(RegExpLiteral node) =>
       (a) => RegExpLiteral(node.pattern);
 
+  @override
   Instantiator<TemplateString> visitTemplateString(TemplateString node) {
     var makeElements = node.interpolations.map(visit).toList();
     return (a) => TemplateString(node.strings, splayNodes(makeElements, a));
   }
 
+  @override
   Instantiator<TaggedTemplate> visitTaggedTemplate(TaggedTemplate node) {
     Instantiator<Expression> makeTag = visit(node.tag);
     var makeTemplate = visitTemplateString(node.template);
     return (a) => TaggedTemplate(makeTag(a), makeTemplate(a));
   }
 
+  @override
   Instantiator visitClassDeclaration(ClassDeclaration node) {
     var makeClass = visitClassExpression(node.classExpr);
     return (a) => ClassDeclaration(makeClass(a));
   }
 
+  @override
   Instantiator<ClassExpression> visitClassExpression(ClassExpression node) {
     var makeMethods = node.methods.map(visitSplayableExpression).toList();
     Instantiator<Identifier> makeName = visit(node.name);
@@ -663,6 +730,7 @@
         makeName(a), makeHeritage(a), splayNodes(makeMethods, a));
   }
 
+  @override
   Instantiator<Method> visitMethod(Method node) {
     Instantiator<Expression> makeName = visit(node.name);
     Instantiator<Fun> makeFunction = visit(node.function);
@@ -672,31 +740,39 @@
         isStatic: node.isStatic);
   }
 
+  @override
   Instantiator<Comment> visitComment(Comment node) =>
       (a) => Comment(node.comment);
 
+  @override
   Instantiator<CommentExpression> visitCommentExpression(
       CommentExpression node) {
     Instantiator<Expression> makeExpr = visit(node.expression);
     return (a) => CommentExpression(node.comment, makeExpr(a));
   }
 
+  @override
   Instantiator<Await> visitAwait(Await node) {
     Instantiator<Expression> makeExpr = visit(node.expression);
     return (a) => Await(makeExpr(a));
   }
 
   // Note: these are not supported yet in the interpolation grammar.
+  @override
   Instantiator visitModule(Module node) => throw UnimplementedError();
+  @override
   Instantiator visitNameSpecifier(NameSpecifier node) =>
       throw UnimplementedError();
 
+  @override
   Instantiator visitImportDeclaration(ImportDeclaration node) =>
       throw UnimplementedError();
 
+  @override
   Instantiator visitExportDeclaration(ExportDeclaration node) =>
       throw UnimplementedError();
 
+  @override
   Instantiator visitExportClause(ExportClause node) =>
       throw UnimplementedError();
 
@@ -751,6 +827,7 @@
     node.accept(this);
   }
 
+  @override
   void visitNode(Node node) {
     int before = count;
     node.visitChildren(this);
@@ -758,6 +835,7 @@
     return null;
   }
 
+  @override
   visitInterpolatedNode(InterpolatedNode node) {
     containsInterpolatedNode.add(node);
     if (node.isNamed) holeNames.add(node.nameOrPosition as String);
diff --git a/pkg/dev_compiler/lib/src/kernel/command.dart b/pkg/dev_compiler/lib/src/kernel/command.dart
index cf0f5bc..8794109 100644
--- a/pkg/dev_compiler/lib/src/kernel/command.dart
+++ b/pkg/dev_compiler/lib/src/kernel/command.dart
@@ -11,6 +11,7 @@
 import 'package:cli_util/cli_util.dart' show getSdkPath;
 import 'package:front_end/src/api_unstable/ddc.dart' as fe;
 import 'package:kernel/kernel.dart' hide MapEntry;
+import 'package:kernel/target/targets.dart';
 import 'package:kernel/text/ast_to_text.dart' as kernel show Printer;
 import 'package:kernel/binary/ast_to_binary.dart' as kernel show BinaryPrinter;
 import 'package:path/path.dart' as path;
@@ -20,7 +21,6 @@
 import '../compiler/module_builder.dart';
 import '../compiler/shared_command.dart';
 import '../compiler/shared_compiler.dart';
-import '../flutter/track_widget_constructor_locations.dart';
 import '../js_ast/js_ast.dart' as JS;
 import '../js_ast/js_ast.dart' show js;
 import '../js_ast/source_map_printer.dart' show SourceMapPrintingContext;
@@ -36,7 +36,7 @@
 /// Returns `true` if the program compiled without any fatal errors.
 Future<CompilerResult> compile(List<String> args,
     {fe.InitializedCompilerState compilerState,
-    bool useIncrementalCompiler: false}) async {
+    bool useIncrementalCompiler = false}) async {
   try {
     return await _compile(args,
         compilerState: compilerState,
@@ -67,7 +67,7 @@
 
 Future<CompilerResult> _compile(List<String> args,
     {fe.InitializedCompilerState compilerState,
-    bool useIncrementalCompiler: false}) async {
+    bool useIncrementalCompiler = false}) async {
   // TODO(jmesserly): refactor options to share code with dartdevc CLI.
   var argParser = ArgParser(allowTrailingOptions: true)
     ..addFlag('help',
@@ -213,6 +213,9 @@
     }
   }
 
+  bool trackWidgetCreation =
+      argResults['track-widget-creation'] as bool ?? false;
+
   var oldCompilerState = compilerState;
   List<Component> doneInputSummaries;
   fe.IncrementalCompiler incrementalCompiler;
@@ -224,7 +227,8 @@
         sourcePathToUri(packageFile),
         sourcePathToUri(librarySpecPath),
         summaryModules.keys.toList(),
-        DevCompilerTarget(),
+        DevCompilerTarget(
+            TargetFlags(trackWidgetCreation: trackWidgetCreation)),
         fileSystem: fileSystem,
         experiments: experiments);
   } else {
@@ -236,7 +240,8 @@
         sourcePathToUri(packageFile),
         sourcePathToUri(librarySpecPath),
         summaryModules.keys.toList(),
-        DevCompilerTarget(),
+        DevCompilerTarget(
+            TargetFlags(trackWidgetCreation: trackWidgetCreation)),
         fileSystem: fileSystem,
         experiments: experiments);
     incrementalCompiler = compilerState.incrementalCompiler;
@@ -320,13 +325,6 @@
     hierarchy = target.hierarchy;
   }
 
-  // TODO(jmesserly): remove this hack once Flutter SDK has a `dartdevc` with
-  // support for the widget inspector.
-  if (argResults['track-widget-creation'] as bool) {
-    component.computeCanonicalNames();
-    WidgetCreatorTracker(hierarchy).transform(component);
-  }
-
   var compiler =
       ProgramCompiler(component, hierarchy, options, declaredVariables);
 
diff --git a/pkg/dev_compiler/lib/src/kernel/compiler.dart b/pkg/dev_compiler/lib/src/kernel/compiler.dart
index 3267966..7427bbc 100644
--- a/pkg/dev_compiler/lib/src/kernel/compiler.dart
+++ b/pkg/dev_compiler/lib/src/kernel/compiler.dart
@@ -2480,7 +2480,7 @@
     }
 
     var args = type.typeArguments;
-    Iterable<JS.Expression> jsArgs = null;
+    Iterable<JS.Expression> jsArgs;
     if (args.any((a) => a != const DynamicType())) {
       jsArgs = args.map(_emitType);
     }
@@ -2789,8 +2789,9 @@
             .toList();
         return mutatedParams;
       });
-      if (mutatedParams.isNotEmpty)
+      if (mutatedParams.isNotEmpty) {
         gen = js.call('() => #(#)', [gen, mutatedParams]);
+      }
 
       var returnType =
           _getExpectedReturnType(function, coreTypes.iterableClass);
@@ -3223,7 +3224,9 @@
         statements.add(labeled);
         target = labeled.body;
       }
-      for (var statement in statements) _effectiveTargets[statement] = target;
+      for (var statement in statements) {
+        _effectiveTargets[statement] = target;
+      }
 
       // If the effective target will compile to something that can have a
       // break from it without a label (e.g., a loop but not a block), then any
@@ -3484,7 +3487,7 @@
   /// switch statements with labeled continues must explicitly break/continue
   /// to escape the surrounding infinite loop.
   List<JS.SwitchCase> _visitSwitchCase(SwitchCase node,
-      {bool lastSwitchCase: false}) {
+      {bool lastSwitchCase = false}) {
     var cases = <JS.SwitchCase>[];
     var emptyBlock = JS.Block.empty();
     // TODO(jmesserly): make sure we are statically checking fall through
@@ -4801,9 +4804,9 @@
     // Only occurs inside unevaluated constants.
     List<JS.Expression> entries = [];
     _concatenate(Expression node) {
-      if (node is ListConcatenation)
+      if (node is ListConcatenation) {
         node.lists.forEach(_concatenate);
-      else {
+      } else {
         node.accept(this);
         if (node is ConstantExpression) {
           var list = node.constant as ListConstant;
@@ -4823,9 +4826,9 @@
     // Only occurs inside unevaluated constants.
     List<JS.Expression> entries = [];
     _concatenate(Expression node) {
-      if (node is SetConcatenation)
+      if (node is SetConcatenation) {
         node.sets.forEach(_concatenate);
-      else {
+      } else {
         node.accept(this);
         if (node is ConstantExpression) {
           var set = node.constant as SetConstant;
@@ -4845,9 +4848,9 @@
     // Only occurs inside unevaluated constants.
     List<JS.Expression> entries = [];
     _concatenate(Expression node) {
-      if (node is MapConcatenation)
+      if (node is MapConcatenation) {
         node.maps.forEach(_concatenate);
-      else {
+      } else {
         node.accept(this);
         if (node is ConstantExpression) {
           var map = node.constant as MapConstant;
diff --git a/pkg/dev_compiler/lib/src/kernel/constants.dart b/pkg/dev_compiler/lib/src/kernel/constants.dart
index 55885a5..4fe583b 100644
--- a/pkg/dev_compiler/lib/src/kernel/constants.dart
+++ b/pkg/dev_compiler/lib/src/kernel/constants.dart
@@ -120,12 +120,19 @@
 
   bool isConstant(Expression e) => e.accept(this);
 
+  @override
   defaultExpression(node) => false;
+  @override
   defaultBasicLiteral(node) => true;
+  @override
   visitTypeLiteral(node) => true; // TODO(jmesserly): deferred libraries?
+  @override
   visitSymbolLiteral(node) => true;
+  @override
   visitListLiteral(node) => node.isConst;
+  @override
   visitMapLiteral(node) => node.isConst;
+  @override
   visitStaticInvocation(node) {
     return node.isConst ||
         node.target == coreTypes.identicalProcedure &&
@@ -135,27 +142,34 @@
             node.arguments.named.every((n) => isConstant(n.value));
   }
 
+  @override
   visitDirectMethodInvocation(node) {
     return node.receiver is BasicLiteral &&
         isOperatorMethodName(node.name.name) &&
         node.arguments.positional.every((p) => p is BasicLiteral);
   }
 
+  @override
   visitMethodInvocation(node) {
     return node.receiver is BasicLiteral &&
         isOperatorMethodName(node.name.name) &&
         node.arguments.positional.every((p) => p is BasicLiteral);
   }
 
+  @override
   visitConstructorInvocation(node) => node.isConst;
+  @override
   visitStringConcatenation(node) =>
       node.expressions.every((e) => e is BasicLiteral);
+  @override
   visitStaticGet(node) {
     var target = node.target;
     return target is Procedure || target is Field && target.isConst;
   }
 
+  @override
   visitVariableGet(node) => node.variable.isConst;
+  @override
   visitNot(node) {
     var operand = node.operand;
     return operand is BoolLiteral ||
@@ -164,13 +178,16 @@
         operand is MethodInvocation && visitMethodInvocation(operand);
   }
 
+  @override
   visitLogicalExpression(node) =>
       node.left is BoolLiteral && node.right is BoolLiteral;
+  @override
   visitConditionalExpression(node) =>
       node.condition is BoolLiteral &&
       node.then is BoolLiteral &&
       node.otherwise is BoolLiteral;
 
+  @override
   visitLet(Let node) {
     var init = node.variable.initializer;
     return (init == null || isConstant(init)) && isConstant(node.body);
diff --git a/pkg/dev_compiler/lib/src/kernel/target.dart b/pkg/dev_compiler/lib/src/kernel/target.dart
index 4b08093..5738f30 100644
--- a/pkg/dev_compiler/lib/src/kernel/target.dart
+++ b/pkg/dev_compiler/lib/src/kernel/target.dart
@@ -8,19 +8,28 @@
 import 'package:kernel/core_types.dart';
 import 'package:kernel/class_hierarchy.dart';
 import 'package:kernel/target/targets.dart';
+import 'package:kernel/transformations/track_widget_constructor_locations.dart';
 import 'constants.dart' show DevCompilerConstantsBackend;
 import 'kernel_helpers.dart';
 
 /// A kernel [Target] to configure the Dart Front End for dartdevc.
 class DevCompilerTarget extends Target {
+  DevCompilerTarget(this.flags);
+
+  final TargetFlags flags;
+
   ClassHierarchy hierarchy;
 
+  @override
   bool get legacyMode => false;
 
+  @override
   bool get enableSuperMixins => true;
 
+  @override
   String get name => 'dartdevc';
 
+  @override
   List<String> get extraRequiredLibraries => const [
         'dart:_runtime',
         'dart:_debugger',
@@ -88,6 +97,18 @@
   }
 
   @override
+  void performPreConstantEvaluationTransformations(
+      Component component,
+      CoreTypes coreTypes,
+      List<Library> libraries,
+      DiagnosticReporter diagnosticReporter,
+      {void logger(String msg)}) {
+    if (flags.trackWidgetCreation) {
+      WidgetCreatorTracker().transform(component, libraries);
+    }
+  }
+
+  @override
   Expression instantiateInvocation(CoreTypes coreTypes, Expression receiver,
       String name, Arguments arguments, int offset, bool isSuper) {
     // TODO(jmesserly): preserve source information?
diff --git a/pkg/dev_compiler/lib/src/kernel/type_table.dart b/pkg/dev_compiler/lib/src/kernel/type_table.dart
index 313e8c9..7dd63c9 100644
--- a/pkg/dev_compiler/lib/src/kernel/type_table.dart
+++ b/pkg/dev_compiler/lib/src/kernel/type_table.dart
@@ -116,6 +116,7 @@
 
   _GeneratorTable(this._runtimeModule);
 
+  @override
   JS.Statement _dischargeType(DartType t) {
     var name = _names.remove(t);
     if (name != null) {
diff --git a/pkg/dev_compiler/test/nullable_inference_test.dart b/pkg/dev_compiler/test/nullable_inference_test.dart
index e7cb728..2390343 100644
--- a/pkg/dev_compiler/test/nullable_inference_test.dart
+++ b/pkg/dev_compiler/test/nullable_inference_test.dart
@@ -8,6 +8,7 @@
 import 'package:kernel/core_types.dart';
 import 'package:kernel/kernel.dart';
 import 'package:kernel/class_hierarchy.dart';
+import 'package:kernel/target/targets.dart';
 import 'package:test/test.dart';
 
 import 'package:dev_compiler/src/kernel/command.dart';
@@ -338,7 +339,7 @@
           // arithmetic operation results on `i` are themselves not null, even
           // though `i` is nullable.
           '0, i.{dart.core::num::<}(10), 10, i = i.{dart.core::num::+}(1), '
-          'i.{dart.core::num::+}(1), 1, i.{dart.core::num::>=}(10), 10');
+              'i.{dart.core::num::+}(1), 1, i.{dart.core::num::>=}(10), 10');
     });
     test('for-in', () async {
       await expectNotNull('''main() {
@@ -429,7 +430,7 @@
       test('parameters', () async {
         await expectNotNull(
             '$imports f(@notNull x, [@notNull y, @notNull z = 42]) '
-            '{ x; y; z; }',
+                '{ x; y; z; }',
             '42, x, y, z');
       });
       test('named parameters', () async {
@@ -456,7 +457,7 @@
     test('method', () async {
       await expectNotNull(
           'library b; $imports class C { @notNull m() {} } '
-          'main() { var c = new C(); c.m(); }',
+              'main() { var c = new C(); c.m(); }',
           'new b::C::•(), c.{b::C::m}(), c');
     });
   });
@@ -575,8 +576,8 @@
   var mainUri = Uri.file('/memory/test.dart');
   _fileSystem.entityForUri(mainUri).writeAsStringSync(code);
   var oldCompilerState = _compilerState;
-  _compilerState = await fe.initializeCompiler(
-      oldCompilerState, sdkUri, packagesUri, null, [], DevCompilerTarget(),
+  _compilerState = await fe.initializeCompiler(oldCompilerState, sdkUri,
+      packagesUri, null, [], DevCompilerTarget(TargetFlags()),
       fileSystem: _fileSystem, experiments: const {});
   if (!identical(oldCompilerState, _compilerState)) inference = null;
   fe.DdcResult result =
diff --git a/pkg/dev_compiler/test/sourcemap/common.dart b/pkg/dev_compiler/test/sourcemap/common.dart
index c4868c3..86f1e30 100644
--- a/pkg/dev_compiler/test/sourcemap/common.dart
+++ b/pkg/dev_compiler/test/sourcemap/common.dart
@@ -21,6 +21,7 @@
 abstract class ChainContextWithCleanupHelper extends ChainContext {
   Map<TestDescription, Data> cleanupHelper = {};
 
+  @override
   Future<void> cleanUp(TestDescription description, Result result) {
     if (debugging() && result.outcome != Expectation.Pass) {
       print("Not cleaning up: Running in debug-mode for non-passing test.");
@@ -38,8 +39,10 @@
 class Setup extends Step<TestDescription, Data, ChainContext> {
   const Setup();
 
+  @override
   String get name => "setup";
 
+  @override
   Future<Result<Data>> run(TestDescription input, ChainContext context) async {
     Data data = Data()..uri = input.uri;
     if (context is ChainContextWithCleanupHelper) {
@@ -52,8 +55,10 @@
 class SetCwdToSdkRoot extends Step<Data, Data, ChainContext> {
   const SetCwdToSdkRoot();
 
+  @override
   String get name => "setCWD";
 
+  @override
   Future<Result<Data>> run(Data input, ChainContext context) async {
     // stacktrace_helper assumes CWD is the sdk root dir.
     Directory.current = sdkRoot;
@@ -64,8 +69,10 @@
 class StepWithD8 extends Step<Data, Data, ChainContext> {
   const StepWithD8();
 
+  @override
   String get name => "step";
 
+  @override
   Future<Result<Data>> run(Data data, ChainContext context) async {
     var outWrapperPath = path.join(data.outDir.path, "wrapper.js");
     ProcessResult runResult =
@@ -80,8 +87,10 @@
 
   CheckSteps(this.debug);
 
+  @override
   String get name => "check";
 
+  @override
   Future<Result<Data>> run(Data data, ChainContext context) async {
     checkD8Steps(data.outDir.path, data.d8Output, data.code, debug: debug);
     return pass(data);
diff --git a/pkg/dev_compiler/test/sourcemap/ddc_common.dart b/pkg/dev_compiler/test/sourcemap/ddc_common.dart
index 437b008..74f2764 100644
--- a/pkg/dev_compiler/test/sourcemap/ddc_common.dart
+++ b/pkg/dev_compiler/test/sourcemap/ddc_common.dart
@@ -29,8 +29,10 @@
 
   const Compile(this.runner);
 
+  @override
   String get name => "compile";
 
+  @override
   Future<Result<Data>> run(Data data, ChainContext context) async {
     var dartScriptAbsolute = File.fromUri(data.uri).absolute;
     var inputFile = dartScriptAbsolute.path;
@@ -58,8 +60,10 @@
 
   const TestStackTrace(this.runner, this.marker, this.knownMarkers);
 
+  @override
   String get name => "TestStackTrace";
 
+  @override
   Future<Result<Data>> run(Data data, ChainContext context) async {
     data.outDir = await Directory.systemTemp.createTemp("stacktrace-test");
     String code = await File.fromUri(data.uri).readAsString();
@@ -99,8 +103,9 @@
     if (result.startsWith("Object.")) result = result.substring(7);
     String inputName =
         INPUT_FILE_NAME.substring(0, INPUT_FILE_NAME.indexOf(".") + 1);
-    if (result.startsWith(inputName))
+    if (result.startsWith(inputName)) {
       result = result.substring(inputName.length);
+    }
     return result;
   }
 }
diff --git a/pkg/dev_compiler/test/sourcemap/sourcemaps_ddc_suite.dart b/pkg/dev_compiler/test/sourcemap/sourcemaps_ddc_suite.dart
index d8b3c1a..d14cc6d 100644
--- a/pkg/dev_compiler/test/sourcemap/sourcemaps_ddc_suite.dart
+++ b/pkg/dev_compiler/test/sourcemap/sourcemaps_ddc_suite.dart
@@ -21,6 +21,7 @@
 
   List<Step> _steps;
 
+  @override
   List<Step> get steps => _steps ??= <Step>[
         const Setup(),
         Compile(DevCompilerRunner(environment.containsKey("debug"))),
@@ -28,6 +29,7 @@
         CheckSteps(environment.containsKey("debug")),
       ];
 
+  @override
   bool debugging() => environment.containsKey("debug");
 }
 
@@ -36,6 +38,7 @@
 
   const DevCompilerRunner([this.debugging = false]);
 
+  @override
   Future<Null> run(Uri inputFile, Uri outputFile, Uri outWrapperFile) async {
     Uri outDir = outputFile.resolve(".");
     String outputFilename = outputFile.pathSegments.last;
diff --git a/pkg/dev_compiler/test/sourcemap/sourcemaps_ddk_suite.dart b/pkg/dev_compiler/test/sourcemap/sourcemaps_ddk_suite.dart
index b275906..de9c620 100644
--- a/pkg/dev_compiler/test/sourcemap/sourcemaps_ddk_suite.dart
+++ b/pkg/dev_compiler/test/sourcemap/sourcemaps_ddk_suite.dart
@@ -21,12 +21,14 @@
 class SourceMapContext extends ChainContextWithCleanupHelper
     implements WithCompilerState {
   final Map<String, String> environment;
+  @override
   fe.InitializedCompilerState compilerState;
 
   SourceMapContext(this.environment);
 
   List<Step> _steps;
 
+  @override
   List<Step> get steps {
     return _steps ??= <Step>[
       const Setup(),
@@ -36,6 +38,7 @@
     ];
   }
 
+  @override
   bool debugging() => environment.containsKey("debug");
 }
 
@@ -45,6 +48,7 @@
 
   const DevCompilerRunner(this.context, [this.debugging = false]);
 
+  @override
   Future<Null> run(Uri inputFile, Uri outputFile, Uri outWrapperFile) async {
     Uri outDir = outputFile.resolve(".");
     String outputFilename = outputFile.pathSegments.last;
diff --git a/pkg/dev_compiler/test/sourcemap/stacktrace_ddc_suite.dart b/pkg/dev_compiler/test/sourcemap/stacktrace_ddc_suite.dart
index c4b1fae..1143568 100644
--- a/pkg/dev_compiler/test/sourcemap/stacktrace_ddc_suite.dart
+++ b/pkg/dev_compiler/test/sourcemap/stacktrace_ddc_suite.dart
@@ -10,6 +10,7 @@
 }
 
 class StackTraceContext extends ChainContextWithCleanupHelper {
+  @override
   final List<Step> steps = <Step>[
     const Setup(),
     const SetCwdToSdkRoot(),
diff --git a/pkg/dev_compiler/test/sourcemap/stacktrace_ddk_suite.dart b/pkg/dev_compiler/test/sourcemap/stacktrace_ddk_suite.dart
index 65fb257..aeaca51 100644
--- a/pkg/dev_compiler/test/sourcemap/stacktrace_ddk_suite.dart
+++ b/pkg/dev_compiler/test/sourcemap/stacktrace_ddk_suite.dart
@@ -12,10 +12,12 @@
 
 class StackTraceContext extends ChainContextWithCleanupHelper
     implements WithCompilerState {
+  @override
   fe.InitializedCompilerState compilerState;
 
   List<Step> _steps;
 
+  @override
   List<Step> get steps {
     return _steps ??= <Step>[
       const Setup(),
diff --git a/pkg/dev_compiler/test/sourcemap/testfiles/next_through_operator_bracket_on_super_test.dart b/pkg/dev_compiler/test/sourcemap/testfiles/next_through_operator_bracket_on_super_test.dart
index b84e3fa..27d4995 100644
--- a/pkg/dev_compiler/test/sourcemap/testfiles/next_through_operator_bracket_on_super_test.dart
+++ b/pkg/dev_compiler/test/sourcemap/testfiles/next_through_operator_bracket_on_super_test.dart
@@ -14,6 +14,7 @@
 }
 
 class Class3 extends Class2 {
+  @override
   code() {
     /*bl*/ /*sl:1*/ super[42];
     /*sl:2*/ return super[42];
diff --git a/pkg/dev_compiler/test/sourcemap/testfiles/next_through_string_concatenation.dart b/pkg/dev_compiler/test/sourcemap/testfiles/next_through_string_concatenation.dart
index 2db6757..38c5aa5 100644
--- a/pkg/dev_compiler/test/sourcemap/testfiles/next_through_string_concatenation.dart
+++ b/pkg/dev_compiler/test/sourcemap/testfiles/next_through_string_concatenation.dart
@@ -6,7 +6,7 @@
 
 main() {
   var qux;
-  qux = "${/*bc:1*/foo()} x ${/*bc:2*/bar()} x ${/*bc:3*/baz()}";
+  qux = "${/*bc:1*/ foo()} x ${/*bc:2*/ bar()} x ${/*bc:3*/ baz()}";
   print(qux);
 }
 
diff --git a/pkg/dev_compiler/test/sourcemap/testfiles/step_through_property_get_test.dart b/pkg/dev_compiler/test/sourcemap/testfiles/step_through_property_get_test.dart
index 061bfde..e4211c0 100644
--- a/pkg/dev_compiler/test/sourcemap/testfiles/step_through_property_get_test.dart
+++ b/pkg/dev_compiler/test/sourcemap/testfiles/step_through_property_get_test.dart
@@ -26,6 +26,7 @@
     data3 = this;
   }
 
+  @override
   void doStuff() {
     /* bl */
     /*s:1*/ print(data2);
diff --git a/pkg/dev_compiler/test/testing.dart b/pkg/dev_compiler/test/testing.dart
index d350f57..449f460 100644
--- a/pkg/dev_compiler/test/testing.dart
+++ b/pkg/dev_compiler/test/testing.dart
@@ -20,6 +20,7 @@
 class _TestUtils {}
 
 class TestUriResolver extends ResourceUriResolver {
+  @override
   final MemoryResourceProvider provider;
   TestUriResolver(this.provider) : super(provider);
 
diff --git a/pkg/dev_compiler/tool/ddb b/pkg/dev_compiler/tool/ddb
index c48fd81..0b3049e 100755
--- a/pkg/dev_compiler/tool/ddb
+++ b/pkg/dev_compiler/tool/ddb
@@ -21,11 +21,22 @@
 // configurable for manual testing.
 const ignoreWhitelistedErrors = false;
 
-void main(List<String> args) {
+void main(List<String> args) async {
+  void printUsage() {
+    print('Usage: ddb [options] <dart-script-file>\n');
+    print('Compiles <dart-script-file> with the dev_compiler and runs it on a '
+        'JS platform.\n');
+  }
+
   // Parse flags.
   var parser = new ArgParser()
+    ..addFlag('help', abbr: 'h', help: 'Display this message.')
     ..addFlag('kernel',
         abbr: 'k', help: 'Compile with the new kernel-based front end.')
+    ..addMultiOption('summary',
+        abbr: 's',
+        help: 'summary file(s) of imported libraries, optionally\n'
+            'with module import path: -s path.sum=js/import/path')
     ..addFlag('debug',
         abbr: 'd',
         help: 'Use current source instead of built SDK.',
@@ -39,13 +50,21 @@
         abbr: 'p',
         help: 'Run with the corresponding chrome/V8 debugging port open.',
         defaultsTo: '9222')
-    ..addOption('enable-experiment',
-        help: 'Run with specified experiments enabled.', defaultsTo: '')
+    ..addMultiOption('enable-experiment',
+        help: 'Run with specified experiments enabled.')
     ..addOption('binary', abbr: 'b', help: 'Runtime binary path.');
 
   var options = parser.parse(args);
+  if (options['help']) {
+    printUsage();
+    print('Available options:');
+    print(parser.usage);
+    exit(0);
+  }
   if (options.rest.length != 1) {
-    throw 'Expected a single dart entrypoint.';
+    print('Dart script file required.\n');
+    printUsage();
+    exit(1);
   }
   var entry = options.rest.first;
   var libRoot = path.dirname(entry);
@@ -54,7 +73,8 @@
   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 experiments = options['enable-experiment'] as List;
+  var summaries = options['summary'] as List;
   var port = int.parse(options['port'] as String);
 
   var dartBinary = Platform.resolvedExecutable;
@@ -79,13 +99,11 @@
   /// Writes stdout and stderr from [result] to this process.
   ///
   /// Will exit with the exit code from [result] when it's not zero.
-  void echoResult(ProcessResult result) {
-    stdout
-      ..write(result.stdout)
-      ..flush();
-    stderr
-      ..write(result.stderr)
-      ..flush();
+  void echoResult(ProcessResult result) async {
+    stdout.write(result.stdout);
+    await stdout.flush();
+    stderr.write(result.stderr);
+    await stderr.flush();
     if (result.exitCode != 0) exit(result.exitCode);
   }
 
@@ -127,28 +145,22 @@
         dartSdk, 'lib', '_internal', kernel ? 'ddc_sdk.dill' : 'ddc_sdk.sum');
   }
   ProcessResult result;
-  if (kernel) {
-    result = runDdc('dartdevc', [
-      '--kernel',
-      '--modules=$mod',
-      '--dart-sdk-summary=$ddcSdk',
-      '--enable-experiment=$experiment',
-      '-o',
-      '$libRoot/$basename.js',
-      entry
-    ]);
-  } else {
-    result = runDdc('dartdevc', [
-      '--modules=$mod',
-      '--dart-sdk-summary=$ddcSdk',
+  var ddcArgs = [
+    if (kernel) '--kernel',
+    '--modules=$mod',
+    '--dart-sdk-summary=$ddcSdk',
+    // TODO(nshahan) Cleanup when we settle on using or removing library-root.
+    if (!kernel)
       '--library-root=$libRoot',
-      '--enable-experiment=$experiment',
-      '-o',
-      '$libRoot/$basename.js',
-      entry
-    ]);
-  }
-  echoResult(result);
+    for (var summary in summaries) '--summary=$summary',
+    for (var experiment in experiments) '--enable-experiment=$experiment',
+    '-o',
+    '$libRoot/$basename.js',
+    entry
+  ];
+
+  result = runDdc('dartdevc', ddcArgs);
+  await echoResult(result);
 
   if (chrome) {
     String chromeBinary;
@@ -241,5 +253,5 @@
     var d8Binary = binary ?? 'd8';
     result = Process.runSync(d8Binary, ['--module', d8File]);
   }
-  echoResult(result);
+  await echoResult(result);
 }
diff --git a/pkg/dev_compiler/tool/global_compile.dart b/pkg/dev_compiler/tool/global_compile.dart
index de1bb64..a1f96fd 100644
--- a/pkg/dev_compiler/tool/global_compile.dart
+++ b/pkg/dev_compiler/tool/global_compile.dart
@@ -6,6 +6,7 @@
 import 'dart:async';
 import 'dart:io';
 
+// ignore: deprecated_member_use
 import 'package:analyzer/analyzer.dart' show parseDirectives;
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/src/dart/ast/ast.dart';
diff --git a/pkg/dev_compiler/tool/input_sdk/lib/js/dart2js/js_dart2js.dart b/pkg/dev_compiler/tool/input_sdk/lib/js/dart2js/js_dart2js.dart
index 6e5eb6d..b16c43e 100644
--- a/pkg/dev_compiler/tool/input_sdk/lib/js/dart2js/js_dart2js.dart
+++ b/pkg/dev_compiler/tool/input_sdk/lib/js/dart2js/js_dart2js.dart
@@ -291,12 +291,12 @@
     return JsFunction._fromJs(JS(
         '',
         'function(/*...arguments*/) {'
-        '  let args = [#(this)];'
-        '  for (let arg of arguments) {'
-        '    args.push(#(arg));'
-        '  }'
-        '  return #(#(...args));'
-        '}',
+            '  let args = [#(this)];'
+            '  for (let arg of arguments) {'
+            '    args.push(#(arg));'
+            '  }'
+            '  return #(#(...args));'
+            '}',
         _convertToDart,
         _convertToDart,
         _convertToJS,
@@ -445,15 +445,15 @@
 bool _isBrowserType(o) => JS(
     'bool',
     '# instanceof Object && ('
-    '# instanceof Blob || '
-    '# instanceof Event || '
-    '(window.KeyRange && # instanceof KeyRange) || '
-    '(window.IDBKeyRange && # instanceof IDBKeyRange) || '
-    '# instanceof ImageData || '
-    '# instanceof Node || '
-    // Int8Array.__proto__ is TypedArray.
-    '(window.Int8Array && # instanceof Int8Array.__proto__) || '
-    '# instanceof Window)',
+        '# instanceof Blob || '
+        '# instanceof Event || '
+        '(window.KeyRange && # instanceof KeyRange) || '
+        '(window.IDBKeyRange && # instanceof IDBKeyRange) || '
+        '# instanceof ImageData || '
+        '# instanceof Node || '
+        // Int8Array.__proto__ is TypedArray.
+        '(window.Int8Array && # instanceof Int8Array.__proto__) || '
+        '# instanceof Window)',
     o,
     o,
     o,
@@ -489,9 +489,9 @@
   var wrapper = JS(
       '',
       'function(/*...arguments*/) {'
-      '  let args = Array.prototype.map.call(arguments, #);'
-      '  return #(#(...args));'
-      '}',
+          '  let args = Array.prototype.map.call(arguments, #);'
+          '  return #(#(...args));'
+          '}',
       _convertToDart,
       _convertToJS,
       f);
@@ -571,12 +571,12 @@
     ret = JS(
         '',
         'function(/*...arguments*/) {'
-        '  let args = [this];'
-        '  for (let arg of arguments) {'
-        '    args.push(arg);'
-        '  }'
-        '  return #(...args);'
-        '}',
+            '  let args = [this];'
+            '  for (let arg of arguments) {'
+            '    args.push(arg);'
+            '  }'
+            '  return #(...args);'
+            '}',
         f);
     _interopCaptureThisExpando[f] = ret;
   }
diff --git a/pkg/dev_compiler/tool/input_sdk/libraries.dart b/pkg/dev_compiler/tool/input_sdk/libraries.dart
index 6009d0c..d5cffa2 100644
--- a/pkg/dev_compiler/tool/input_sdk/libraries.dart
+++ b/pkg/dev_compiler/tool/input_sdk/libraries.dart
@@ -281,26 +281,26 @@
       1,
       "Experimental",
       "This library is experimental and will likely change or be removed\n"
-      "in future versions.");
+          "in future versions.");
 
   static const Maturity UNSTABLE = const Maturity(
       2,
       "Unstable",
       "This library is in still changing and have not yet endured\n"
-      "sufficient real-world testing.\n"
-      "Backwards-compatibility is NOT guaranteed.");
+          "sufficient real-world testing.\n"
+          "Backwards-compatibility is NOT guaranteed.");
 
   static const Maturity WEB_STABLE = const Maturity(
       3,
       "Web Stable",
       "This library is tracking the DOM evolution as defined by WC3.\n"
-      "Backwards-compatibility is NOT guaranteed.");
+          "Backwards-compatibility is NOT guaranteed.");
 
   static const Maturity STABLE = const Maturity(
       4,
       "Stable",
       "The library is stable. API backwards-compatibility is guaranteed.\n"
-      "However implementation details might change.");
+          "However implementation details might change.");
 
   static const Maturity LOCKED = const Maturity(5, "Locked",
       "This library will not change except when serious bugs are encountered.");
diff --git a/pkg/dev_compiler/tool/input_sdk/patch/core_patch.dart b/pkg/dev_compiler/tool/input_sdk/patch/core_patch.dart
index da07a3c..a8103b3 100644
--- a/pkg/dev_compiler/tool/input_sdk/patch/core_patch.dart
+++ b/pkg/dev_compiler/tool/input_sdk/patch/core_patch.dart
@@ -720,8 +720,8 @@
   static final bool _isWindowsCached = JS(
       'bool',
       'typeof process != "undefined" && '
-      'Object.prototype.toString.call(process) == "[object process]" && '
-      'process.platform == "win32"');
+          'Object.prototype.toString.call(process) == "[object process]" && '
+          'process.platform == "win32"');
 
   // Matches a String that _uriEncodes to itself regardless of the kind of
   // component.  This corresponds to [_unreservedTable], i.e. characters that
diff --git a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/classes.dart b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/classes.dart
index 3f848d6..02b8aca 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/classes.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/classes.dart
@@ -61,7 +61,7 @@
       var obj = JS(
           '',
           '#.set = { __proto__: #.__proto__, '
-          'set [#](x) { return super[#] = x; } }',
+              'set [#](x) { return super[#] = x; } }',
           desc,
           to,
           name,
@@ -73,7 +73,7 @@
       var obj = JS(
           '',
           '#.get = { __proto__: #.__proto__, '
-          'get [#]() { return super[#]; } }',
+              'get [#]() { return super[#]; } }',
           desc,
           to,
           name,
diff --git a/pkg/dev_compiler/tool/input_sdk/private/js_helper.dart b/pkg/dev_compiler/tool/input_sdk/private/js_helper.dart
index cf6b1e6..95b822a 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/js_helper.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/js_helper.dart
@@ -165,7 +165,7 @@
     if (!JS(
         'bool',
         r'/^\s*[+-]?(?:Infinity|NaN|'
-        r'(?:\.\d+|\d+(?:\.\d*)?)(?:[eE][+-]?\d+)?)\s*$/.test(#)',
+            r'(?:\.\d+|\d+(?:\.\d*)?)(?:[eE][+-]?\d+)?)\s*$/.test(#)',
         source)) {
       return _parseDoubleError(source, handleError);
     }
@@ -207,7 +207,7 @@
     return JS(
         'bool',
         'typeof version == "function"'
-        ' && typeof os == "object" && "system" in os');
+            ' && typeof os == "object" && "system" in os');
   }
 
   static bool get isJsshell {
@@ -334,15 +334,15 @@
         'JSArray|Null',
         // Thu followed by a space.
         r'/^[A-Z,a-z]{3}\s'
-        // Oct 31 followed by space.
-        r'[A-Z,a-z]{3}\s\d+\s'
-        // Time followed by a space.
-        r'\d{2}:\d{2}:\d{2}\s'
-        // The time zone name followed by a space.
-        r'([A-Z]{3,5})\s'
-        // The year.
-        r'\d{4}$/'
-        '.exec(#.toString())',
+            // Oct 31 followed by space.
+            r'[A-Z,a-z]{3}\s\d+\s'
+            // Time followed by a space.
+            r'\d{2}:\d{2}:\d{2}\s'
+            // The time zone name followed by a space.
+            r'([A-Z]{3,5})\s'
+            // The year.
+            r'\d{4}$/'
+            '.exec(#.toString())',
         d);
     if (match != null) return match[1];
 
diff --git a/pkg/dev_compiler/tool/input_sdk/private/regexp_helper.dart b/pkg/dev_compiler/tool/input_sdk/private/regexp_helper.dart
index 744effc..1c31a09 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/regexp_helper.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/regexp_helper.dart
@@ -94,12 +94,12 @@
     var regexp = JS(
         '',
         '(function() {'
-        'try {'
-        'return new RegExp(#, # + # + # + # + #);'
-        '} catch (e) {'
-        'return e;'
-        '}'
-        '})()',
+            'try {'
+            'return new RegExp(#, # + # + # + # + #);'
+            '} catch (e) {'
+            'return e;'
+            '}'
+            '})()',
         source,
         m,
         i,
diff --git a/pkg/dev_compiler/tool/kernel_sdk.dart b/pkg/dev_compiler/tool/kernel_sdk.dart
index 2827fbe..d7e000d 100755
--- a/pkg/dev_compiler/tool/kernel_sdk.dart
+++ b/pkg/dev_compiler/tool/kernel_sdk.dart
@@ -16,6 +16,7 @@
 import 'package:front_end/src/api_unstable/ddc.dart'
     show CompilerOptions, kernelForComponent;
 import 'package:kernel/kernel.dart';
+import 'package:kernel/target/targets.dart';
 import 'package:path/path.dart' as path;
 
 Future main(List<String> args) async {
@@ -38,7 +39,7 @@
 
   var librarySpecPath = parserOptions['libraries'] as String;
 
-  var target = DevCompilerTarget();
+  var target = DevCompilerTarget(TargetFlags());
   var options = CompilerOptions()
     ..compileSdk = true
     // TODO(sigmund): remove this unnecessary option when possible.
diff --git a/pkg/dev_compiler/tool/patch_sdk.dart b/pkg/dev_compiler/tool/patch_sdk.dart
index e6d123b..d5cb090 100755
--- a/pkg/dev_compiler/tool/patch_sdk.dart
+++ b/pkg/dev_compiler/tool/patch_sdk.dart
@@ -9,6 +9,7 @@
 import 'dart:io';
 import 'dart:math' as math;
 
+// ignore: deprecated_member_use
 import 'package:analyzer/analyzer.dart'
     show parseCompilationUnit, parseDirectives;
 import 'package:analyzer/dart/ast/ast.dart';
@@ -391,7 +392,7 @@
   /// Creates a new transaction.
   StringEditBuffer(this.original);
 
-  bool get hasEdits => _edits.length > 0;
+  bool get hasEdits => _edits.isNotEmpty;
 
   /// Edit the original text, replacing text on the range [begin] and
   /// exclusive [end] with the [replacement] string.
@@ -415,9 +416,10 @@
   ///
   /// Throws [UnsupportedError] if the edits were overlapping. If no edits were
   /// made, the original string will be returned.
+  @override
   String toString() {
     var sb = StringBuffer();
-    if (_edits.length == 0) return original;
+    if (_edits.isEmpty) return original;
 
     // Sort edits by start location.
     _edits.sort();
@@ -461,8 +463,10 @@
 
   int get length => end - begin;
 
+  @override
   String toString() => '(Edit @ $begin,$end: "$replace")';
 
+  @override
   int compareTo(_StringEdit other) {
     int diff = begin - other.begin;
     if (diff != 0) return diff;
diff --git a/pkg/dev_compiler/web/stack_trace_mapper.dart b/pkg/dev_compiler/web/stack_trace_mapper.dart
index de9e2b6..9044aa6 100644
--- a/pkg/dev_compiler/web/stack_trace_mapper.dart
+++ b/pkg/dev_compiler/web/stack_trace_mapper.dart
@@ -66,6 +66,7 @@
 
   List toJson() => _bundle.toJson();
 
+  @override
   SourceMapSpan spanFor(int line, int column,
       {Map<String, SourceFile> files, String uri}) {
     if (uri == null) {
diff --git a/pkg/dev_compiler/web/web_command.dart b/pkg/dev_compiler/web/web_command.dart
index 2904b5a..2a7496d 100644
--- a/pkg/dev_compiler/web/web_command.dart
+++ b/pkg/dev_compiler/web/web_command.dart
@@ -59,8 +59,10 @@
 
 /// The command for invoking the modular compiler.
 class WebCompileCommand extends Command {
+  @override
   get name => 'compile';
 
+  @override
   get description => 'Compile a set of Dart files into a JavaScript module.';
   final MessageHandler messageHandler;
 
@@ -146,7 +148,7 @@
       var bytes = summaryBytes[i];
 
       // Packages with no dart source files will have empty invalid summaries.
-      if (bytes.length == 0) continue;
+      if (bytes.isEmpty) continue;
 
       var moduleId = moduleIds[i];
       var url = '/$moduleId.api.ds';
@@ -164,7 +166,7 @@
       var uri = Uri.parse(url);
       var base = path.basename(url);
       var parts = uri.pathSegments;
-      var match = null;
+      var match;
       int bestScore = 0;
       for (var candidate in summaryData.uriToSummaryPath.keys) {
         if (path.basename(candidate) != base) continue;
@@ -306,5 +308,6 @@
 
 /// Thrown when the input source code has errors.
 class CompileErrorException implements Exception {
+  @override
   toString() => '\nPlease fix all errors before compiling (warnings are okay).';
 }
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 1e74242..3606b3d 100644
--- a/pkg/front_end/lib/src/api_unstable/bazel_worker.dart
+++ b/pkg/front_end/lib/src/api_unstable/bazel_worker.dart
@@ -55,7 +55,10 @@
     Target target,
     FileSystem fileSystem,
     bool outlineOnly) async {
-  List<int> sdkDigest = workerInputDigests[sdkSummary];
+  final List<int> sdkDigest = workerInputDigests[sdkSummary];
+  if (sdkDigest == null) {
+    throw new StateError("Expected to get digest for $sdkSummary");
+  }
   IncrementalCompiler incrementalCompiler;
   CompilerOptions options;
   ProcessedOptions processedOpts;
@@ -67,15 +70,20 @@
   if (oldState == null ||
       oldState.incrementalCompiler == null ||
       oldState.incrementalCompiler.outlineOnly != outlineOnly) {
-    // No previous state.
+    // No - or immediately not correct - previous state.
     startOver = true;
+
+    // We'll load a new sdk, anything loaded already will have a wrong root.
+    workerInputCache.clear();
   } else {
     // We do have a previous state.
     cachedSdkInput = workerInputCache[sdkSummary];
     if (cachedSdkInput == null ||
-        !digestsEqual(cachedSdkInput.digest, workerInputDigests[sdkSummary])) {
+        !digestsEqual(cachedSdkInput.digest, sdkDigest)) {
       // The sdk is out of date.
       startOver = true;
+      // We'll load a new sdk, anything loaded already will have a wrong root.
+      workerInputCache.clear();
     }
   }
 
@@ -102,7 +110,6 @@
   } else {
     options = oldState.options;
     processedOpts = oldState.processedOpts;
-
     var sdkComponent = cachedSdkInput.component;
     // Reset the state of the component.
     for (var lib in sdkComponent.libraries) {
@@ -118,6 +125,7 @@
     incrementalCompiler.invalidateAllSources();
     options.packagesFileUri = packagesFile;
     options.fileSystem = fileSystem;
+    processedOpts.clearFileSystemCache();
   }
 
   // Then read all the input summary components.
@@ -127,6 +135,9 @@
   for (Uri summary in summaryInputs) {
     var cachedInput = workerInputCache[summary];
     var summaryDigest = workerInputDigests[summary];
+    if (summaryDigest == null) {
+      throw new StateError("Expected to get digest for $summary");
+    }
     if (cachedInput == null ||
         cachedInput.component.root != nameRoot ||
         !digestsEqual(cachedInput.digest, summaryDigest)) {
@@ -145,7 +156,10 @@
 
   for (int i = 0; i < loadFromDill.length; i++) {
     Uri summary = loadFromDill[i];
-    var summaryDigest = workerInputDigests[summary];
+    List<int> summaryDigest = workerInputDigests[summary];
+    if (summaryDigest == null) {
+      throw new StateError("Expected to get digest for $summary");
+    }
     WorkerInputComponent cachedInput = WorkerInputComponent(
         summaryDigest,
         await processedOpts.loadComponent(
@@ -193,7 +207,7 @@
 
 Future<CompilerResult> _compile(InitializedCompilerState compilerState,
     List<Uri> inputs, DiagnosticMessageHandler diagnosticMessageHandler,
-    {bool summaryOnly}) {
+    {bool summaryOnly, bool includeOffsets: true}) {
   summaryOnly ??= true;
   CompilerOptions options = compilerState.options;
   options..onDiagnostic = diagnosticMessageHandler;
@@ -203,13 +217,16 @@
   processedOpts.inputs.addAll(inputs);
 
   return generateKernel(processedOpts,
-      buildSummary: summaryOnly, buildComponent: !summaryOnly);
+      buildSummary: summaryOnly,
+      buildComponent: !summaryOnly,
+      includeOffsets: includeOffsets);
 }
 
 Future<List<int>> compileSummary(InitializedCompilerState compilerState,
-    List<Uri> inputs, DiagnosticMessageHandler diagnosticMessageHandler) async {
+    List<Uri> inputs, DiagnosticMessageHandler diagnosticMessageHandler,
+    {bool includeOffsets: false}) async {
   var result = await _compile(compilerState, inputs, diagnosticMessageHandler,
-      summaryOnly: true);
+      summaryOnly: true, includeOffsets: includeOffsets);
   return result?.summary;
 }
 
diff --git a/pkg/front_end/lib/src/api_unstable/ddc.dart b/pkg/front_end/lib/src/api_unstable/ddc.dart
index ef61212..3230a6b 100644
--- a/pkg/front_end/lib/src/api_unstable/ddc.dart
+++ b/pkg/front_end/lib/src/api_unstable/ddc.dart
@@ -165,6 +165,9 @@
       ..fileSystem = fileSystem ?? StandardFileSystem.instance;
     if (experiments != null) options.experimentalFlags = experiments;
 
+    // We'll load a new sdk, anything loaded already will have a wrong root.
+    workerInputCache.clear();
+
     processedOpts = new ProcessedOptions(options: options);
 
     cachedSdkInput = new WorkerInputComponent(null /* not compared anyway */,
@@ -190,6 +193,7 @@
     incrementalCompiler.invalidateAllSources();
     options.packagesFileUri = packagesFile;
     options.fileSystem = fileSystem;
+    processedOpts.clearFileSystemCache();
   }
   InitializedCompilerState compilerState = new InitializedCompilerState(
       options, processedOpts,
diff --git a/pkg/front_end/lib/src/fasta/builder/named_type_builder.dart b/pkg/front_end/lib/src/fasta/builder/named_type_builder.dart
index 1a17041..9644f64 100644
--- a/pkg/front_end/lib/src/fasta/builder/named_type_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/named_type_builder.dart
@@ -82,9 +82,11 @@
           typeName = name;
           typeNameOffset = charOffset;
         }
-        declaration = buildInvalidType(templateTypeArgumentsOnTypeVariable
-            .withArguments(typeName)
-            .withLocation(fileUri, typeNameOffset, typeName.length));
+        Message message =
+            templateTypeArgumentsOnTypeVariable.withArguments(typeName);
+        library.addProblem(message, typeNameOffset, typeName.length, fileUri);
+        declaration = buildInvalidType(
+            message.withLocation(fileUri, typeNameOffset, typeName.length));
       }
       return;
     } else if (member is TypeDeclarationBuilder) {
@@ -120,20 +122,22 @@
     }
     int length =
         name is Identifier ? name.endCharOffset - charOffset : flatName.length;
+    Message message = template.withArguments(flatName);
+    library.addProblem(message, charOffset, length, fileUri, context: context);
     declaration = buildInvalidType(
-        template
-            .withArguments(flatName)
-            .withLocation(fileUri, charOffset, length),
+        message.withLocation(fileUri, charOffset, length),
         context: context);
   }
 
   @override
-  void check(int charOffset, Uri fileUri) {
+  void check(LibraryBuilder library, int charOffset, Uri fileUri) {
     if (arguments != null &&
         arguments.length != declaration.typeVariablesCount) {
-      declaration = buildInvalidType(templateTypeArgumentMismatch
-          .withArguments(declaration.typeVariablesCount)
-          .withLocation(fileUri, charOffset, noLength));
+      Message message = templateTypeArgumentMismatch
+          .withArguments(declaration.typeVariablesCount);
+      library.addProblem(message, charOffset, noLength, fileUri);
+      declaration =
+          buildInvalidType(message.withLocation(fileUri, charOffset, noLength));
     }
   }
 
diff --git a/pkg/front_end/lib/src/fasta/builder/type_builder.dart b/pkg/front_end/lib/src/fasta/builder/type_builder.dart
index bebc060..0758872 100644
--- a/pkg/front_end/lib/src/fasta/builder/type_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/type_builder.dart
@@ -18,7 +18,7 @@
       Scope scope, int charOffset, Uri fileUri, LibraryBuilder library) {}
 
   /// See `UnresolvedType.checkType`.
-  void check(int charOffset, Uri fileUri) {}
+  void check(LibraryBuilder library, int charOffset, Uri fileUri) {}
 
   /// See `UnresolvedType.normalizeType`.
   void normalize(int charOffset, Uri fileUri) {}
diff --git a/pkg/front_end/lib/src/fasta/builder/unresolved_type.dart b/pkg/front_end/lib/src/fasta/builder/unresolved_type.dart
index c716335..9c8ce77 100644
--- a/pkg/front_end/lib/src/fasta/builder/unresolved_type.dart
+++ b/pkg/front_end/lib/src/fasta/builder/unresolved_type.dart
@@ -18,7 +18,9 @@
       builder.resolveIn(scope, charOffset, fileUri, library);
 
   /// Performs checks on the type after it's resolved.
-  void checkType() => builder.check(charOffset, fileUri);
+  void checkType(LibraryBuilder library) {
+    return builder.check(library, charOffset, fileUri);
+  }
 
   /// Normalizes the type arguments in accordance with Dart 1 semantics.
   void normalizeType() => builder.normalize(charOffset, fileUri);
diff --git a/pkg/front_end/lib/src/fasta/dill/dill_library_builder.dart b/pkg/front_end/lib/src/fasta/dill/dill_library_builder.dart
index c76a2bc..d2e1703 100644
--- a/pkg/front_end/lib/src/fasta/dill/dill_library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/dill/dill_library_builder.dart
@@ -24,6 +24,7 @@
 import '../fasta_codes.dart'
     show
         Message,
+        noLength,
         templateDuplicatedDeclaration,
         templateTypeNotFound,
         templateUnspecified;
@@ -160,11 +161,10 @@
     // mapping `k` to `d` is added to the exported namespace of `L` unless a
     // top-level declaration with the name `k` exists in `L`.
     if (builder.parent == this) return builder;
+    Message message = templateDuplicatedDeclaration.withArguments(name);
+    addProblem(message, charOffset, name.length, fileUri);
     return new KernelInvalidTypeBuilder(
-        name,
-        templateDuplicatedDeclaration
-            .withArguments(name)
-            .withLocation(fileUri, charOffset, name.length));
+        name, message.withLocation(fileUri, charOffset, name.length));
   }
 
   @override
@@ -187,6 +187,7 @@
           Message message = messageText == null
               ? templateTypeNotFound.withArguments(name)
               : templateUnspecified.withArguments(messageText);
+          addProblem(message, -1, noLength, null);
           declaration =
               new KernelInvalidTypeBuilder(name, message.withoutLocation());
       }
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 0c4177b..991c13b 100644
--- a/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
+++ b/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
@@ -1486,36 +1486,6 @@
 }
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-const Code<Null> codeConstEvalIterationInConstList =
-    messageConstEvalIterationInConstList;
-
-// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-const MessageCode messageConstEvalIterationInConstList = const MessageCode(
-    "ConstEvalIterationInConstList",
-    analyzerCodes: <String>["NON_CONSTANT_LIST_ELEMENT"],
-    message: r"""Iteration can't be used in a constant list.""");
-
-// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-const Code<Null> codeConstEvalIterationInConstMap =
-    messageConstEvalIterationInConstMap;
-
-// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-const MessageCode messageConstEvalIterationInConstMap = const MessageCode(
-    "ConstEvalIterationInConstMap",
-    analyzerCodes: <String>["NON_CONSTANT_MAP_ELEMENT"],
-    message: r"""Iteration can't be used in a constant map.""");
-
-// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-const Code<Null> codeConstEvalIterationInConstSet =
-    messageConstEvalIterationInConstSet;
-
-// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-const MessageCode messageConstEvalIterationInConstSet = const MessageCode(
-    "ConstEvalIterationInConstSet",
-    analyzerCodes: <String>["NON_CONSTANT_SET_ELEMENT"],
-    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)>(
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 d780212..46f4f5e 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -2336,8 +2336,7 @@
       return;
     }
 
-    if (constantContext != ConstantContext.none &&
-        !library.loader.target.enableConstantUpdate2018) {
+    if (constantContext != ConstantContext.none) {
       handleRecoverableError(
           fasta.templateCantUseControlFlowOrSpreadAsConstant
               .withArguments(forToken),
@@ -2710,14 +2709,15 @@
         String name = getNodeName(prefix);
         String displayName = debugName(name, suffix.lexeme);
         int offset = offsetForToken(beginToken);
+        Message message = fasta.templateNotAType.withArguments(displayName);
+        library.addProblem(
+            message, offset, lengthOfSpan(beginToken, suffix), uri);
         push(new UnresolvedType<KernelTypeBuilder>(
             new KernelNamedTypeBuilder(name, null)
               ..bind(new KernelInvalidTypeBuilder(
                   name,
-                  fasta.templateNotAType
-                      .withArguments(displayName)
-                      .withLocation(
-                          uri, offset, lengthOfSpan(beginToken, suffix)))),
+                  message.withLocation(
+                      uri, offset, lengthOfSpan(beginToken, suffix)))),
             offset,
             uri));
         return;
@@ -2736,6 +2736,8 @@
       }
     } else if (name is ProblemBuilder) {
       // TODO(ahe): Arguments could be passed here.
+      library.addProblem(
+          name.message, name.charOffset, name.name.length, name.fileUri);
       result = new KernelNamedTypeBuilder(name.name, null)
         ..bind(new KernelInvalidTypeBuilder(
             name.name,
@@ -4185,8 +4187,7 @@
       return;
     }
 
-    if (constantContext != ConstantContext.none &&
-        !library.loader.target.enableConstantUpdate2018) {
+    if (constantContext != ConstantContext.none) {
       handleRecoverableError(
           fasta.templateCantUseControlFlowOrSpreadAsConstant
               .withArguments(forToken),
@@ -5127,19 +5128,12 @@
     if (builder is KernelNamedTypeBuilder &&
         builder.declaration.isTypeVariable) {
       TypeParameter typeParameter = builder.declaration.target;
-      bool isConstant = constantContext != ConstantContext.none;
       LocatedMessage message;
-      bool suppressMessage = false;
       if (!isInstanceContext && typeParameter.parent is Class) {
         message = fasta.messageTypeVariableInStaticContext.withLocation(
             unresolved.fileUri,
             unresolved.charOffset,
             typeParameter.name.length);
-        if (!nonInstanceAccessIsError && !isConstant && legacyMode) {
-          // This is a warning in legacy mode.
-          addProblem(message.messageObject, message.charOffset, message.length);
-          suppressMessage = true;
-        }
       } else if (constantContext == ConstantContext.inferred) {
         message = fasta.messageTypeVariableInConstantContext.withLocation(
             unresolved.fileUri,
@@ -5148,10 +5142,10 @@
       } else {
         return unresolved;
       }
+      addProblem(message.messageObject, message.charOffset, message.length);
       return new UnresolvedType<KernelTypeBuilder>(
           new KernelNamedTypeBuilder(typeParameter.name, null)
-            ..bind(new KernelInvalidTypeBuilder(typeParameter.name, message,
-                suppressMessage: suppressMessage)),
+            ..bind(new KernelInvalidTypeBuilder(typeParameter.name, message)),
           unresolved.charOffset,
           unresolved.fileUri);
     }
diff --git a/pkg/front_end/lib/src/fasta/kernel/constant_collection_builders.dart b/pkg/front_end/lib/src/fasta/kernel/constant_collection_builders.dart
index 9173c09..b3b7d64 100644
--- a/pkg/front_end/lib/src/fasta/kernel/constant_collection_builders.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/constant_collection_builders.dart
@@ -4,8 +4,7 @@
 
 part of 'constant_evaluator.dart';
 
-abstract class _ListOrSetConstantBuilder<L extends Expression,
-    C extends Constant> {
+abstract class _ListOrSetConstantBuilder<L extends Expression> {
   final ConstantEvaluator evaluator;
   final Expression original;
   final DartType elementType;
@@ -18,97 +17,26 @@
 
   L makeLiteral(List<Expression> elements);
 
-  C makeConstant(List<Constant> elements);
-
-  Message get messageForIteration;
-
-  _ListOrSetConstantBuilder<L, C> newTempBuilder();
-
-  /// Add an element (which is possibly a spread or an if element) to the
-  /// constant list being built by this builder.
+  /// Add an element to the constant list being built by this builder.
   void add(Expression element) {
-    if (element is SpreadElement) {
-      addSpread(element.expression, isNullAware: element.isNullAware);
-    } else if (element is IfElement) {
-      Constant condition = evaluator._evaluateSubexpression(element.condition);
-      if (evaluator.shouldBeUnevaluated) {
-        // Unevaluated if
-        evaluator.enterLazy();
-        Constant then = (newTempBuilder()..add(element.then)).build();
-        Constant otherwise;
-        if (element.otherwise != null) {
-          otherwise = (newTempBuilder()..add(element.otherwise)).build();
-        } else {
-          otherwise = makeConstant([]);
-        }
-        evaluator.leaveLazy();
-        parts.add(evaluator.unevaluated(
-            element.condition,
-            new ConditionalExpression(
-                evaluator.extract(condition),
-                evaluator.extract(then),
-                evaluator.extract(otherwise),
-                const DynamicType())));
-      } else {
-        // Fully evaluated if
-        if (condition == evaluator.trueConstant) {
-          add(element.then);
-        } else if (condition == evaluator.falseConstant) {
-          if (element.otherwise != null) {
-            add(element.otherwise);
-          }
-        } else if (condition == evaluator.nullConstant) {
-          evaluator.report(element.condition, messageConstEvalNullValue);
-        } else {
-          evaluator.report(
-              element.condition,
-              templateConstEvalInvalidType.withArguments(
-                  condition,
-                  evaluator.typeEnvironment.boolType,
-                  condition.getType(evaluator.typeEnvironment)));
-        }
-      }
-    } else if (element is ForElement || element is ForInElement) {
-      // For or for-in
-      evaluator.report(element, messageForIteration);
+    Constant constant = evaluator._evaluateSubexpression(element);
+    if (evaluator.shouldBeUnevaluated) {
+      parts.add(evaluator.unevaluated(
+          element, makeLiteral([evaluator.extract(constant)])));
     } else {
-      // Ordinary expression element
-      Constant constant = evaluator._evaluateSubexpression(element);
-      if (evaluator.shouldBeUnevaluated) {
-        parts.add(evaluator.unevaluated(
-            element, makeLiteral([evaluator.extract(constant)])));
-      } else {
-        addConstant(constant, element);
-      }
+      addConstant(constant, element);
     }
   }
 
-  void addSpread(Expression spreadExpression, {bool isNullAware}) {
+  void addSpread(Expression spreadExpression) {
     Constant spread =
         evaluator.unlower(evaluator._evaluateSubexpression(spreadExpression));
     if (evaluator.shouldBeUnevaluated) {
       // Unevaluated spread
-      if (isNullAware) {
-        VariableDeclaration temp = new VariableDeclaration(null,
-            initializer: evaluator.extract(spread));
-        parts.add(evaluator.unevaluated(
-            spreadExpression,
-            new Let(
-                temp,
-                new ConditionalExpression(
-                    new MethodInvocation(new VariableGet(temp), new Name('=='),
-                        new Arguments([new NullLiteral()])),
-                    new ListLiteral([], isConst: true),
-                    new VariableGet(temp),
-                    const DynamicType()))));
-      } else {
-        parts.add(spread);
-      }
+      parts.add(spread);
     } else if (spread == evaluator.nullConstant) {
       // Null spread
-      if (!isNullAware) {
-        evaluator.report(spreadExpression, messageConstEvalNullValue);
-      }
+      evaluator.report(spreadExpression, messageConstEvalNullValue);
     } else {
       // Fully evaluated spread
       List<Constant> entries;
@@ -132,8 +60,7 @@
   Constant build();
 }
 
-class ListConstantBuilder
-    extends _ListOrSetConstantBuilder<ListLiteral, ListConstant> {
+class ListConstantBuilder extends _ListOrSetConstantBuilder<ListLiteral> {
   ListConstantBuilder(
       Expression original, DartType elementType, ConstantEvaluator evaluator)
       : super(original, elementType, evaluator);
@@ -143,17 +70,6 @@
       new ListLiteral(elements, isConst: true);
 
   @override
-  ListConstant makeConstant(List<Constant> elements) =>
-      new ListConstant(const DynamicType(), elements);
-
-  @override
-  Message get messageForIteration => messageConstEvalIterationInConstList;
-
-  @override
-  ListConstantBuilder newTempBuilder() =>
-      new ListConstantBuilder(original, const DynamicType(), evaluator);
-
-  @override
   void addConstant(Constant constant, TreeNode context) {
     List<Constant> lastPart;
     if (parts.last is List<Constant>) {
@@ -186,8 +102,7 @@
   }
 }
 
-class SetConstantBuilder
-    extends _ListOrSetConstantBuilder<SetLiteral, SetConstant> {
+class SetConstantBuilder extends _ListOrSetConstantBuilder<SetLiteral> {
   final Set<Constant> seen = new Set<Constant>.identity();
 
   SetConstantBuilder(
@@ -199,17 +114,6 @@
       new SetLiteral(elements, isConst: true);
 
   @override
-  SetConstant makeConstant(List<Constant> elements) =>
-      new SetConstant(const DynamicType(), elements);
-
-  @override
-  Message get messageForIteration => messageConstEvalIterationInConstSet;
-
-  @override
-  SetConstantBuilder newTempBuilder() =>
-      new SetConstantBuilder(original, const DynamicType(), evaluator);
-
-  @override
   void addConstant(Constant constant, TreeNode context) {
     if (!evaluator.hasPrimitiveEqual(constant)) {
       evaluator.report(context,
@@ -286,99 +190,30 @@
   MapConstantBuilder(
       this.original, this.keyType, this.valueType, this.evaluator);
 
-  MapConstantBuilder newTempBuilder() => new MapConstantBuilder(
-      original, const DynamicType(), const DynamicType(), evaluator);
-
-  /// Add a map entry (which is possibly a spread or an if map entry) to the
-  /// constant map being built by this builder
+  /// Add a map entry to the constant map being built by this builder
   void add(MapEntry element) {
-    if (element is SpreadMapEntry) {
-      addSpread(element.expression, isNullAware: element.isNullAware);
-    } else if (element is IfMapEntry) {
-      Constant condition = evaluator._evaluateSubexpression(element.condition);
-      if (evaluator.shouldBeUnevaluated) {
-        // Unevaluated if
-        evaluator.enterLazy();
-        Constant then = (newTempBuilder()..add(element.then)).build();
-        Constant otherwise;
-        if (element.otherwise != null) {
-          otherwise = (newTempBuilder()..add(element.otherwise)).build();
-        } else {
-          otherwise =
-              new MapConstant(const DynamicType(), const DynamicType(), []);
-        }
-        evaluator.leaveLazy();
-        parts.add(evaluator.unevaluated(
-            element.condition,
-            new ConditionalExpression(
-                evaluator.extract(condition),
-                evaluator.extract(then),
-                evaluator.extract(otherwise),
-                const DynamicType())));
-      } else {
-        // Fully evaluated if
-        if (condition == evaluator.trueConstant) {
-          add(element.then);
-        } else if (condition == evaluator.falseConstant) {
-          if (element.otherwise != null) {
-            add(element.otherwise);
-          }
-        } else if (condition == evaluator.nullConstant) {
-          evaluator.report(element.condition, messageConstEvalNullValue);
-        } else {
-          evaluator.report(
-              element.condition,
-              templateConstEvalInvalidType.withArguments(
-                  condition,
-                  evaluator.typeEnvironment.boolType,
-                  condition.getType(evaluator.typeEnvironment)));
-        }
-      }
-    } else if (element is ForMapEntry || element is ForInMapEntry) {
-      // For or for-in
-      evaluator.report(element, messageConstEvalIterationInConstMap);
+    Constant key = evaluator._evaluateSubexpression(element.key);
+    Constant value = evaluator._evaluateSubexpression(element.value);
+    if (evaluator.shouldBeUnevaluated) {
+      parts.add(evaluator.unevaluated(
+          element.key,
+          new MapLiteral(
+              [new MapEntry(evaluator.extract(key), evaluator.extract(value))],
+              isConst: true)));
     } else {
-      // Ordinary map entry
-      Constant key = evaluator._evaluateSubexpression(element.key);
-      Constant value = evaluator._evaluateSubexpression(element.value);
-      if (evaluator.shouldBeUnevaluated) {
-        parts.add(evaluator.unevaluated(
-            element.key,
-            new MapLiteral([
-              new MapEntry(evaluator.extract(key), evaluator.extract(value))
-            ], isConst: true)));
-      } else {
-        addConstant(key, value, element.key, element.value);
-      }
+      addConstant(key, value, element.key, element.value);
     }
   }
 
-  void addSpread(Expression spreadExpression, {bool isNullAware}) {
+  void addSpread(Expression spreadExpression) {
     Constant spread =
         evaluator.unlower(evaluator._evaluateSubexpression(spreadExpression));
     if (evaluator.shouldBeUnevaluated) {
       // Unevaluated spread
-      if (isNullAware) {
-        VariableDeclaration temp = new VariableDeclaration(null,
-            initializer: evaluator.extract(spread));
-        parts.add(evaluator.unevaluated(
-            spreadExpression,
-            new Let(
-                temp,
-                new ConditionalExpression(
-                    new MethodInvocation(new VariableGet(temp), new Name('=='),
-                        new Arguments([new NullLiteral()])),
-                    new MapLiteral([], isConst: true),
-                    new VariableGet(temp),
-                    const DynamicType()))));
-      } else {
-        parts.add(spread);
-      }
+      parts.add(spread);
     } else if (spread == evaluator.nullConstant) {
       // Null spread
-      if (!isNullAware) {
-        evaluator.report(spreadExpression, messageConstEvalNullValue);
-      }
+      evaluator.report(spreadExpression, messageConstEvalNullValue);
     } else {
       // Fully evaluated spread
       if (spread is MapConstant) {
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 d50ce8d..51d5070 100644
--- a/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
@@ -39,9 +39,6 @@
         messageConstEvalCircularity,
         messageConstEvalContext,
         messageConstEvalFailedAssertion,
-        messageConstEvalIterationInConstList,
-        messageConstEvalIterationInConstSet,
-        messageConstEvalIterationInConstMap,
         messageConstEvalNotListOrSetInSpread,
         messageConstEvalNotMapInSpread,
         messageConstEvalNullValue,
@@ -67,17 +64,6 @@
         templateConstEvalNonConstantVariableGet,
         templateConstEvalZeroDivisor;
 
-import 'collections.dart'
-    show
-        ForElement,
-        ForInElement,
-        IfElement,
-        SpreadElement,
-        ForMapEntry,
-        ForInMapEntry,
-        IfMapEntry,
-        SpreadMapEntry;
-
 part 'constant_collection_builders.dart';
 
 Component transformComponent(Component component, ConstantsBackend backend,
@@ -397,6 +383,10 @@
     return super.visitListLiteral(node);
   }
 
+  visitListConcatenation(ListConcatenation node) {
+    return evaluateAndTransformWithContext(node, node);
+  }
+
   visitSetLiteral(SetLiteral node) {
     if (node.isConst) {
       return evaluateAndTransformWithContext(node, node);
@@ -404,6 +394,10 @@
     return super.visitSetLiteral(node);
   }
 
+  visitSetConcatenation(SetConcatenation node) {
+    return evaluateAndTransformWithContext(node, node);
+  }
+
   visitMapLiteral(MapLiteral node) {
     if (node.isConst) {
       return evaluateAndTransformWithContext(node, node);
@@ -411,6 +405,10 @@
     return super.visitMapLiteral(node);
   }
 
+  visitMapConcatenation(MapConcatenation node) {
+    return evaluateAndTransformWithContext(node, node);
+  }
+
   visitConstructorInvocation(ConstructorInvocation node) {
     if (node.isConst) {
       return evaluateAndTransformWithContext(node, node);
@@ -784,7 +782,7 @@
     final ListConstantBuilder builder =
         new ListConstantBuilder(node, node.typeArgument, this);
     for (Expression list in node.lists) {
-      builder.addSpread(list, isNullAware: false);
+      builder.addSpread(list);
     }
     return builder.build();
   }
@@ -806,7 +804,7 @@
     final SetConstantBuilder builder =
         new SetConstantBuilder(node, node.typeArgument, this);
     for (Expression set_ in node.sets) {
-      builder.addSpread(set_, isNullAware: false);
+      builder.addSpread(set_);
     }
     return builder.build();
   }
@@ -828,7 +826,7 @@
     final MapConstantBuilder builder =
         new MapConstantBuilder(node, node.keyType, node.valueType, this);
     for (Expression map in node.maps) {
-      builder.addSpread(map, isNullAware: false);
+      builder.addSpread(map);
     }
     return builder.build();
   }
@@ -1499,7 +1497,7 @@
               extract(otherwise), node.staticType));
     } else {
       return report(
-          node,
+          node.condition,
           templateConstEvalInvalidType.withArguments(condition,
               typeEnvironment.boolType, condition.getType(typeEnvironment)));
     }
diff --git a/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart b/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
index db33cf1..9b94ff4 100644
--- a/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
@@ -215,9 +215,11 @@
       List<UnresolvedType<KernelTypeBuilder>> arguments) {
     KernelNamedTypeBuilder result =
         new KernelNamedTypeBuilder(token.lexeme, null);
-    result.bind(result.buildInvalidType(templateNotAType
-        .withArguments(token.lexeme)
-        .withLocation(uri, offsetForToken(token), lengthForToken(token))));
+    Message message = templateNotAType.withArguments(token.lexeme);
+    helper.library
+        .addProblem(message, offsetForToken(token), lengthForToken(token), uri);
+    result.bind(result.buildInvalidType(message.withLocation(
+        uri, offsetForToken(token), lengthForToken(token))));
     return result;
   }
 
@@ -541,6 +543,8 @@
               uri, charOffset, lengthOfSpan(prefixGenerator.token, token));
     }
     KernelNamedTypeBuilder result = new KernelNamedTypeBuilder(name, null);
+    helper.library.addProblem(
+        message.messageObject, message.charOffset, message.length, message.uri);
     result.bind(result.buildInvalidType(message));
     return result;
   }
@@ -1161,10 +1165,14 @@
         : templateNotAPrefixInTypeAnnotation;
     KernelNamedTypeBuilder result =
         new KernelNamedTypeBuilder(plainNameForRead, null);
-    result.bind(result.buildInvalidType(template
-        .withArguments(prefixGenerator.token.lexeme, token.lexeme)
-        .withLocation(uri, offsetForToken(prefixGenerator.token),
-            lengthOfSpan(prefixGenerator.token, token))));
+    Message message =
+        template.withArguments(prefixGenerator.token.lexeme, token.lexeme);
+    helper.library.addProblem(message, offsetForToken(prefixGenerator.token),
+        lengthOfSpan(prefixGenerator.token, token), uri);
+    result.bind(result.buildInvalidType(message.withLocation(
+        uri,
+        offsetForToken(prefixGenerator.token),
+        lengthOfSpan(prefixGenerator.token, token))));
     return result;
   }
 
@@ -1250,6 +1258,7 @@
       List<UnresolvedType<KernelTypeBuilder>> arguments) {
     KernelNamedTypeBuilder result =
         new KernelNamedTypeBuilder(token.lexeme, null);
+    helper.library.addProblem(message, offsetForToken(token), noLength, uri);
     result.bind(result.buildInvalidType(
         message.withLocation(uri, offsetForToken(token), noLength)));
     return result;
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_class_builder.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_class_builder.dart
index 151c074..6ad083c 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_class_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_class_builder.dart
@@ -338,7 +338,7 @@
     for (TypeParameter parameter in cls.typeParameters) {
       List<TypeArgumentIssue> issues = findTypeArgumentIssues(
           parameter.bound, typeEnvironment,
-          allowSuperBounded: false);
+          allowSuperBounded: true);
       if (issues != null) {
         for (TypeArgumentIssue issue in issues) {
           DartType argument = issue.argument;
@@ -923,9 +923,9 @@
       library.addProblem(
           templateOverrideTypeVariablesMismatch.withArguments(
               "${declaredMember.enclosingClass.name}."
-              "${declaredMember.name.name}",
+                  "${declaredMember.name.name}",
               "${interfaceMember.enclosingClass.name}."
-              "${interfaceMember.name.name}"),
+                  "${interfaceMember.name.name}"),
           declaredMember.fileOffset,
           noLength,
           declaredMember.fileUri,
@@ -960,9 +960,9 @@
             library.addProblem(
                 templateOverrideTypeVariablesMismatch.withArguments(
                     "${declaredMember.enclosingClass.name}."
-                    "${declaredMember.name.name}",
+                        "${declaredMember.name.name}",
                     "${interfaceMember.enclosingClass.name}."
-                    "${interfaceMember.name.name}"),
+                        "${interfaceMember.name.name}"),
                 declaredMember.fileOffset,
                 noLength,
                 declaredMember.fileUri,
@@ -1103,9 +1103,9 @@
       library.addProblem(
           templateOverrideFewerPositionalArguments.withArguments(
               "${declaredMember.enclosingClass.name}."
-              "${declaredMember.name.name}",
+                  "${declaredMember.name.name}",
               "${interfaceMember.enclosingClass.name}."
-              "${interfaceMember.name.name}"),
+                  "${interfaceMember.name.name}"),
           declaredMember.fileOffset,
           noLength,
           declaredMember.fileUri,
@@ -1122,9 +1122,9 @@
       library.addProblem(
           templateOverrideMoreRequiredArguments.withArguments(
               "${declaredMember.enclosingClass.name}."
-              "${declaredMember.name.name}",
+                  "${declaredMember.name.name}",
               "${interfaceMember.enclosingClass.name}."
-              "${interfaceMember.name.name}"),
+                  "${interfaceMember.name.name}"),
           declaredMember.fileOffset,
           noLength,
           declaredMember.fileUri,
@@ -1164,9 +1164,9 @@
       library.addProblem(
           templateOverrideFewerNamedArguments.withArguments(
               "${declaredMember.enclosingClass.name}."
-              "${declaredMember.name.name}",
+                  "${declaredMember.name.name}",
               "${interfaceMember.enclosingClass.name}."
-              "${interfaceMember.name.name}"),
+                  "${interfaceMember.name.name}"),
           declaredMember.fileOffset,
           noLength,
           declaredMember.fileUri,
@@ -1201,10 +1201,10 @@
           library.addProblem(
               templateOverrideMismatchNamedParameter.withArguments(
                   "${declaredMember.enclosingClass.name}."
-                  "${declaredMember.name.name}",
+                      "${declaredMember.name.name}",
                   interfaceNamedParameters.current.name,
                   "${interfaceMember.enclosingClass.name}."
-                  "${interfaceMember.name.name}"),
+                      "${interfaceMember.name.name}"),
               declaredMember.fileOffset,
               noLength,
               declaredMember.fileUri,
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_invalid_type_builder.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_invalid_type_builder.dart
index 60fba36..729323f 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_invalid_type_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_invalid_type_builder.dart
@@ -21,7 +21,7 @@
   final bool suppressMessage;
 
   KernelInvalidTypeBuilder(String name, this.message,
-      {this.context, this.suppressMessage: false})
+      {this.context, this.suppressMessage: true})
       : super(name, message.charOffset, message.uri);
 
   @override
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_library_builder.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_library_builder.dart
index c1d8ca8..80db2c8 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_library_builder.dart
@@ -1139,16 +1139,18 @@
     var builderTemplate = isExport
         ? templateDuplicatedExportInType
         : templateDuplicatedImportInType;
-    return new KernelInvalidTypeBuilder(
+    message = builderTemplate.withArguments(
         name,
-        builderTemplate
-            .withArguments(
-                name,
-                // TODO(ahe): We should probably use a context object here
-                // instead of including URIs in this message.
-                uri,
-                otherUri)
-            .withLocation(fileUri, charOffset, name.length));
+        // TODO(ahe): We should probably use a context object here
+        // instead of including URIs in this message.
+        uri,
+        otherUri);
+    // We report the error lazily (setting suppressMessage to false) because the
+    // spec 18.1 states that 'It is not an error if N is introduced by two or
+    // more imports but never referred to.'
+    return new KernelInvalidTypeBuilder(
+        name, message.withLocation(fileUri, charOffset, name.length),
+        suppressMessage: false);
   }
 
   int finishDeferredLoadTearoffs() {
@@ -1568,7 +1570,7 @@
       for (TypeParameter parameter in typeParameters) {
         checkBoundsInType(
             parameter.bound, typeEnvironment, parameter.fileOffset,
-            allowSuperBounded: false);
+            allowSuperBounded: true);
       }
     }
     if (positionalParameters != null) {
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
index 4dd4cca..49d0344 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
@@ -774,6 +774,12 @@
   /// Run all transformations that are needed when building a bundle of
   /// libraries for the first time.
   void runBuildTransformations() {
+    backendTarget.performPreConstantEvaluationTransformations(
+        component,
+        loader.coreTypes,
+        loader.libraries,
+        new KernelDiagnosticReporter(loader),
+        logger: (String msg) => ticker.logMs(msg));
     if (loader.target.enableConstantUpdate2018) {
       TypeEnvironment environment =
           new TypeEnvironment(loader.coreTypes, loader.hierarchy);
diff --git a/pkg/front_end/lib/src/fasta/kernel/transform_collections.dart b/pkg/front_end/lib/src/fasta/kernel/transform_collections.dart
index bbc7186..6cab740 100644
--- a/pkg/front_end/lib/src/fasta/kernel/transform_collections.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/transform_collections.dart
@@ -13,6 +13,7 @@
         Block,
         BlockExpression,
         Class,
+        ConditionalExpression,
         DartType,
         DynamicType,
         Expression,
@@ -22,7 +23,10 @@
         ForStatement,
         IfStatement,
         InterfaceType,
+        Let,
+        ListConcatenation,
         ListLiteral,
+        MapConcatenation,
         MapEntry,
         MapLiteral,
         MethodInvocation,
@@ -31,6 +35,7 @@
         NullLiteral,
         Procedure,
         PropertyGet,
+        SetConcatenation,
         SetLiteral,
         Statement,
         StaticInvocation,
@@ -58,6 +63,8 @@
         SpreadElement,
         SpreadMapEntry;
 
+import '../problems.dart' show getFileUri, unhandled;
+
 import '../source/source_loader.dart' show SourceLoader;
 
 import 'redirecting_factory_body.dart' show RedirectingFactoryBody;
@@ -277,8 +284,10 @@
 
   @override
   TreeNode visitListLiteral(ListLiteral node) {
-    // Const collections are handled by the constant evaluator.
-    if (node.isConst) return node;
+    if (node.isConst) {
+      return _translateConstListOrSet(node, node.typeArgument, node.expressions,
+          isSet: false);
+    }
 
     return _translateListOrSet(node, node.typeArgument, node.expressions,
         isSet: false);
@@ -286,8 +295,10 @@
 
   @override
   TreeNode visitSetLiteral(SetLiteral node) {
-    // Const collections are handled by the constant evaluator.
-    if (node.isConst) return node;
+    if (node.isConst) {
+      return _translateConstListOrSet(node, node.typeArgument, node.expressions,
+          isSet: true);
+    }
 
     return _translateListOrSet(node, node.typeArgument, node.expressions,
         isSet: true);
@@ -295,8 +306,9 @@
 
   @override
   TreeNode visitMapLiteral(MapLiteral node) {
-    // Const collections are handled by the constant evaluator.
-    if (node.isConst) return node;
+    if (node.isConst) {
+      return _translateConstMap(node);
+    }
 
     // Translate entries in place up to the first control-flow entry, if any.
     int i = 0;
@@ -479,4 +491,150 @@
     }
     body.add(statement);
   }
+
+  TreeNode _translateConstListOrSet(
+      Expression node, DartType elementType, List<Expression> elements,
+      {bool isSet: false}) {
+    // Translate elements in place up to the first non-expression, if any.
+    int i = 0;
+    for (; i < elements.length; ++i) {
+      if (elements[i] is ControlFlowElement) break;
+      elements[i] = elements[i].accept(this)..parent = node;
+    }
+
+    // If there were only expressions, we are done.
+    if (i == elements.length) return node;
+
+    Expression makeLiteral(List<Expression> expressions) {
+      return isSet
+          ? new SetLiteral(expressions,
+              typeArgument: elementType, isConst: true)
+          : new ListLiteral(expressions,
+              typeArgument: elementType, isConst: true);
+    }
+
+    // Build a concatenation node.
+    List<Expression> parts = [];
+    List<Expression> currentPart = i > 0 ? elements.sublist(0, i) : null;
+
+    for (; i < elements.length; ++i) {
+      Expression element = elements[i];
+      if (element is SpreadElement) {
+        if (currentPart != null) {
+          parts.add(makeLiteral(currentPart));
+          currentPart = null;
+        }
+        Expression spreadExpression = element.expression.accept(this);
+        if (element.isNullAware) {
+          VariableDeclaration temp =
+              new VariableDeclaration(null, initializer: spreadExpression);
+          parts.add(new Let(
+              temp,
+              new ConditionalExpression(
+                  new MethodInvocation(new VariableGet(temp), new Name('=='),
+                      new Arguments([new NullLiteral()])),
+                  makeLiteral([]),
+                  new VariableGet(temp),
+                  const DynamicType())));
+        } else {
+          parts.add(spreadExpression);
+        }
+      } else if (element is IfElement) {
+        if (currentPart != null) {
+          parts.add(makeLiteral(currentPart));
+          currentPart = null;
+        }
+        Expression condition = element.condition.accept(this);
+        Expression then = makeLiteral([element.then]).accept(this);
+        Expression otherwise = element.otherwise != null
+            ? makeLiteral([element.otherwise]).accept(this)
+            : makeLiteral([]);
+        parts.add(new ConditionalExpression(
+            condition, then, otherwise, const DynamicType()));
+      } else if (element is ForElement || element is ForInElement) {
+        // Rejected earlier.
+        unhandled("${element.runtimeType}", "_translateConstListOrSet",
+            element.fileOffset, getFileUri(element));
+      } else {
+        currentPart ??= <Expression>[];
+        currentPart.add(element.accept(this));
+      }
+    }
+    if (currentPart != null) {
+      parts.add(makeLiteral(currentPart));
+    }
+    return isSet
+        ? new SetConcatenation(parts, typeArgument: elementType)
+        : new ListConcatenation(parts, typeArgument: elementType);
+  }
+
+  TreeNode _translateConstMap(MapLiteral node) {
+    // Translate entries in place up to the first control-flow entry, if any.
+    int i = 0;
+    for (; i < node.entries.length; ++i) {
+      if (node.entries[i] is ControlFlowMapEntry) break;
+      node.entries[i] = node.entries[i].accept(this)..parent = node;
+    }
+
+    // If there were no control-flow entries we are done.
+    if (i == node.entries.length) return node;
+
+    MapLiteral makeLiteral(List<MapEntry> entries) {
+      return new MapLiteral(entries,
+          keyType: node.keyType, valueType: node.valueType, isConst: true);
+    }
+
+    // Build a concatenation node.
+    List<Expression> parts = [];
+    List<MapEntry> currentPart = i > 0 ? node.entries.sublist(0, i) : null;
+
+    for (; i < node.entries.length; ++i) {
+      MapEntry entry = node.entries[i];
+      if (entry is SpreadMapEntry) {
+        if (currentPart != null) {
+          parts.add(makeLiteral(currentPart));
+          currentPart = null;
+        }
+        Expression spreadExpression = entry.expression.accept(this);
+        if (entry.isNullAware) {
+          VariableDeclaration temp =
+              new VariableDeclaration(null, initializer: spreadExpression);
+          parts.add(new Let(
+              temp,
+              new ConditionalExpression(
+                  new MethodInvocation(new VariableGet(temp), new Name('=='),
+                      new Arguments([new NullLiteral()])),
+                  makeLiteral([]),
+                  new VariableGet(temp),
+                  const DynamicType())));
+        } else {
+          parts.add(spreadExpression);
+        }
+      } else if (entry is IfMapEntry) {
+        if (currentPart != null) {
+          parts.add(makeLiteral(currentPart));
+          currentPart = null;
+        }
+        Expression condition = entry.condition.accept(this);
+        Expression then = makeLiteral([entry.then]).accept(this);
+        Expression otherwise = entry.otherwise != null
+            ? makeLiteral([entry.otherwise]).accept(this)
+            : makeLiteral([]);
+        parts.add(new ConditionalExpression(
+            condition, then, otherwise, const DynamicType()));
+      } else if (entry is ForMapEntry || entry is ForInMapEntry) {
+        // Rejected earlier.
+        unhandled("${entry.runtimeType}", "_translateConstMap",
+            entry.fileOffset, getFileUri(entry));
+      } else {
+        currentPart ??= <MapEntry>[];
+        currentPart.add(entry.accept(this));
+      }
+    }
+    if (currentPart != null) {
+      parts.add(makeLiteral(currentPart));
+    }
+    return new MapConcatenation(parts,
+        keyType: node.keyType, valueType: node.valueType);
+  }
 }
diff --git a/pkg/front_end/lib/src/fasta/kernel/utils.dart b/pkg/front_end/lib/src/fasta/kernel/utils.dart
index 1b96164..c074608 100644
--- a/pkg/front_end/lib/src/fasta/kernel/utils.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/utils.dart
@@ -60,12 +60,15 @@
 
 /// Serialize the libraries in [component] that match [filter].
 List<int> serializeComponent(Component component,
-    {bool filter(Library library), bool includeSources: true}) {
+    {bool filter(Library library),
+    bool includeSources: true,
+    bool includeOffsets: true}) {
   ByteSink byteSink = new ByteSink();
   BinaryPrinter printer = filter == null
-      ? new BinaryPrinter(byteSink, includeSources: includeSources)
-      : new LimitedBinaryPrinter(
-          byteSink, filter ?? (_) => true, !includeSources);
+      ? new BinaryPrinter(byteSink,
+          includeSources: includeSources, includeOffsets: includeOffsets)
+      : new LimitedBinaryPrinter(byteSink, filter, !includeSources,
+          includeOffsets: includeOffsets);
   printer.writeComponentFile(component);
   return byteSink.builder.takeBytes();
 }
diff --git a/pkg/front_end/lib/src/fasta/parser/parser.dart b/pkg/front_end/lib/src/fasta/parser/parser.dart
index 51b32e6..6e60793 100644
--- a/pkg/front_end/lib/src/fasta/parser/parser.dart
+++ b/pkg/front_end/lib/src/fasta/parser/parser.dart
@@ -330,6 +330,11 @@
   /// ;
   /// ```
   Token parseUnit(Token token) {
+    // Skip over error tokens and report them at the end
+    // so that the parser has the chance to adjust the error location.
+    Token errorToken = token;
+    token = skipErrorTokens(errorToken);
+
     listener.beginCompilationUnit(token);
     int count = 0;
     DirectiveContext directiveState = new DirectiveContext();
@@ -358,6 +363,7 @@
       }
     }
     token = token.next;
+    reportAllErrorTokens(errorToken);
     listener.endCompilationUnit(count, token);
     // Clear fields that could lead to memory leak.
     cachedRewriter = null;
@@ -6297,6 +6303,21 @@
     listener.handleErrorToken(token);
   }
 
+  Token reportAllErrorTokens(Token token) {
+    while (token is ErrorToken) {
+      reportErrorToken(token);
+      token = token.next;
+    }
+    return token;
+  }
+
+  Token skipErrorTokens(Token token) {
+    while (token is ErrorToken) {
+      token = token.next;
+    }
+    return token;
+  }
+
   Token parseInvalidTopLevelDeclaration(Token token) {
     Token next = token.next;
     reportRecoverableErrorWithToken(
diff --git a/pkg/front_end/lib/src/fasta/scanner.dart b/pkg/front_end/lib/src/fasta/scanner.dart
index db6a662..b80f201 100644
--- a/pkg/front_end/lib/src/fasta/scanner.dart
+++ b/pkg/front_end/lib/src/fasta/scanner.dart
@@ -15,7 +15,7 @@
 
 import 'scanner/utf8_bytes_scanner.dart' show Utf8BytesScanner;
 
-import 'scanner/recover.dart' show defaultRecoveryStrategy;
+import 'scanner/recover.dart' show scannerRecovery;
 
 export 'scanner/abstract_scanner.dart'
     show LanguageVersionChanged, ScannerConfiguration;
@@ -68,12 +68,10 @@
 }
 
 /// Scan/tokenize the given UTF8 [bytes].
-/// If [recover] is null, then the [defaultRecoveryStrategy] is used.
 ScannerResult scan(List<int> bytes,
     {ScannerConfiguration configuration,
     bool includeComments: false,
-    LanguageVersionChanged languageVersionChanged,
-    Recover recover}) {
+    LanguageVersionChanged languageVersionChanged}) {
   if (bytes.last != 0) {
     throw new ArgumentError("[bytes]: the last byte must be null.");
   }
@@ -81,31 +79,28 @@
       configuration: configuration,
       includeComments: includeComments,
       languageVersionChanged: languageVersionChanged);
-  return _tokenizeAndRecover(scanner, recover, bytes: bytes);
+  return _tokenizeAndRecover(scanner, bytes: bytes);
 }
 
 /// Scan/tokenize the given [source].
-/// If [recover] is null, then the [defaultRecoveryStrategy] is used.
 ScannerResult scanString(String source,
     {ScannerConfiguration configuration,
     bool includeComments: false,
-    LanguageVersionChanged languageVersionChanged,
-    Recover recover}) {
+    LanguageVersionChanged languageVersionChanged}) {
   assert(source != null, 'source must not be null');
   StringScanner scanner = new StringScanner(source,
       configuration: configuration,
       includeComments: includeComments,
       languageVersionChanged: languageVersionChanged);
-  return _tokenizeAndRecover(scanner, recover, source: source);
+  return _tokenizeAndRecover(scanner, source: source);
 }
 
-ScannerResult _tokenizeAndRecover(Scanner scanner, Recover recover,
+ScannerResult _tokenizeAndRecover(Scanner scanner,
     {List<int> bytes, String source}) {
   Token tokens = scanner.tokenize();
   if (scanner.hasErrors) {
     if (bytes == null) bytes = utf8.encode(source);
-    recover ??= defaultRecoveryStrategy;
-    tokens = recover(bytes, tokens, scanner.lineStarts);
+    tokens = scannerRecovery(bytes, tokens, scanner.lineStarts);
   }
   return new ScannerResult(tokens, scanner.lineStarts, scanner.hasErrors);
 }
diff --git a/pkg/front_end/lib/src/fasta/scanner/abstract_scanner.dart b/pkg/front_end/lib/src/fasta/scanner/abstract_scanner.dart
index 637bbc1..e59d613 100644
--- a/pkg/front_end/lib/src/fasta/scanner/abstract_scanner.dart
+++ b/pkg/front_end/lib/src/fasta/scanner/abstract_scanner.dart
@@ -51,15 +51,18 @@
   /// based upon the specified language version.
   final LanguageVersionChanged languageVersionChanged;
 
-  /// Experimental flag for enabling scanning of `>>>`.
-  /// See https://github.com/dart-lang/language/issues/61
-  /// and https://github.com/dart-lang/language/issues/60
-  bool _enableTripleShift = false;
+  /// Experimental flag for enabling scanning of the `extension` token.
+  bool _enableExtensionMethods = false;
 
   /// Experimental flag for enabling scanning of NNBD tokens
   /// such as 'required' and 'late'.
   bool _enableNonNullable = false;
 
+  /// Experimental flag for enabling scanning of `>>>`.
+  /// See https://github.com/dart-lang/language/issues/61
+  /// and https://github.com/dart-lang/language/issues/60
+  bool _enableTripleShift = false;
+
   /**
    * The string offset for the next token that will be created.
    *
@@ -108,6 +111,7 @@
   @override
   set configuration(ScannerConfiguration config) {
     if (config != null) {
+      _enableExtensionMethods = config.enableExtensionMethods;
       _enableNonNullable = config.enableNonNullable;
       _enableTripleShift = config.enableTripleShift;
     }
@@ -1135,6 +1139,9 @@
     if (state == null || state.keyword == null) {
       return tokenizeIdentifier(next, start, allowDollar);
     }
+    if (!_enableExtensionMethods && state.keyword == Keyword.EXTENSION) {
+      return tokenizeIdentifier(next, start, allowDollar);
+    }
     if (!_enableNonNullable &&
         (state.keyword == Keyword.LATE || state.keyword == Keyword.REQUIRED)) {
       return tokenizeIdentifier(next, start, allowDollar);
@@ -1533,6 +1540,9 @@
   static const classic = ScannerConfiguration();
   static const nonNullable = ScannerConfiguration(enableNonNullable: true);
 
+  /// Experimental flag for enabling scanning of the `extension` keyword.
+  final bool enableExtensionMethods;
+
   /// Experimental flag for enabling scanning of NNBD tokens
   /// such as 'required' and 'late'
   final bool enableNonNullable;
@@ -1543,8 +1553,10 @@
   final bool enableTripleShift;
 
   const ScannerConfiguration({
-    bool enableTripleShift,
+    bool enableExtensionMethods,
     bool enableNonNullable,
-  })  : this.enableTripleShift = enableTripleShift ?? false,
-        this.enableNonNullable = enableNonNullable ?? false;
+    bool enableTripleShift,
+  })  : this.enableExtensionMethods = enableExtensionMethods ?? false,
+        this.enableNonNullable = enableNonNullable ?? false,
+        this.enableTripleShift = enableTripleShift ?? false;
 }
diff --git a/pkg/front_end/lib/src/fasta/scanner/recover.dart b/pkg/front_end/lib/src/fasta/scanner/recover.dart
index 588e658..51b59d6 100644
--- a/pkg/front_end/lib/src/fasta/scanner/recover.dart
+++ b/pkg/front_end/lib/src/fasta/scanner/recover.dart
@@ -30,8 +30,7 @@
 /// [bytes]. [lineStarts] are the beginning character offsets of lines, and
 /// must be updated if recovery is performed rewriting the original source
 /// code.
-Token defaultRecoveryStrategy(
-    List<int> bytes, Token tokens, List<int> lineStarts) {
+Token scannerRecovery(List<int> bytes, Token tokens, List<int> lineStarts) {
   // See [Parser.reportErrorToken](../parser/src/parser.dart) for how
   // it currently handles lexical errors. In addition, notice how the parser
   // calls [handleInvalidExpression], [handleInvalidFunctionBody], and
diff --git a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
index ede5fec..fb12c34 100644
--- a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
@@ -854,7 +854,7 @@
     for (UnresolvedType<T> t in types) {
       t.resolveIn(scope, this);
       if (!loader.target.legacyMode) {
-        t.checkType();
+        t.checkType(this);
       } else {
         t.normalizeType();
       }
@@ -995,14 +995,16 @@
         parent.addType(type);
       } else if (nameOrQualified is QualifiedName) {
         // Attempt to use a member or type variable as a prefix.
-        type.builder.bind(type.builder.buildInvalidType(
-            templateNotAPrefixInTypeAnnotation
-                .withArguments(
-                    flattenName(nameOrQualified.qualifier, type.charOffset,
-                        type.fileUri),
-                    nameOrQualified.name)
-                .withLocation(type.fileUri, type.charOffset,
-                    nameOrQualified.endCharOffset - type.charOffset)));
+        Message message = templateNotAPrefixInTypeAnnotation.withArguments(
+            flattenName(
+                nameOrQualified.qualifier, type.charOffset, type.fileUri),
+            nameOrQualified.name);
+        library.addProblem(message, type.charOffset,
+            nameOrQualified.endCharOffset - type.charOffset, type.fileUri);
+        type.builder.bind(type.builder.buildInvalidType(message.withLocation(
+            type.fileUri,
+            type.charOffset,
+            nameOrQualified.endCharOffset - type.charOffset)));
       } else {
         scope ??= toScope(null).withTypeVariables(typeVariables);
         type.resolveIn(scope, library);
diff --git a/pkg/front_end/lib/src/kernel_generator_impl.dart b/pkg/front_end/lib/src/kernel_generator_impl.dart
index 0a4fad1..f967227 100644
--- a/pkg/front_end/lib/src/kernel_generator_impl.dart
+++ b/pkg/front_end/lib/src/kernel_generator_impl.dart
@@ -35,19 +35,22 @@
 Future<CompilerResult> generateKernel(ProcessedOptions options,
     {bool buildSummary: false,
     bool buildComponent: true,
-    bool truncateSummary: false}) async {
+    bool truncateSummary: false,
+    bool includeOffsets: true}) async {
   return await CompilerContext.runWithOptions(options, (_) async {
     return await generateKernelInternal(
         buildSummary: buildSummary,
         buildComponent: buildComponent,
-        truncateSummary: truncateSummary);
+        truncateSummary: truncateSummary,
+        includeOffsets: includeOffsets);
   });
 }
 
 Future<CompilerResult> generateKernelInternal(
     {bool buildSummary: false,
     bool buildComponent: true,
-    bool truncateSummary: false}) async {
+    bool truncateSummary: false,
+    bool includeOffsets: true}) async {
   var options = CompilerContext.current.options;
   var fs = options.fileSystem;
 
@@ -138,8 +141,8 @@
         options.ticker.logMs("Transformed outline");
       }
       // Don't include source (but do add it above to include importUris).
-      summary =
-          serializeComponent(trimmedSummaryComponent, includeSources: false);
+      summary = serializeComponent(trimmedSummaryComponent,
+          includeSources: false, includeOffsets: includeOffsets);
       options.ticker.logMs("Generated outline");
     }
 
diff --git a/pkg/front_end/lib/src/scanner/token.dart b/pkg/front_end/lib/src/scanner/token.dart
index 0ffd35b..5947f80 100644
--- a/pkg/front_end/lib/src/scanner/token.dart
+++ b/pkg/front_end/lib/src/scanner/token.dart
@@ -173,6 +173,9 @@
 
   static const Keyword EXTENDS = const Keyword("extends", "EXTENDS");
 
+  static const Keyword EXTENSION = const Keyword("extension", "EXTENSION",
+      isBuiltIn: true, isTopLevelKeyword: true);
+
   static const Keyword EXTERNAL =
       const Keyword("external", "EXTERNAL", isBuiltIn: true, isModifier: true);
 
@@ -303,6 +306,7 @@
     ENUM,
     EXPORT,
     EXTENDS,
+    EXTENSION,
     EXTERNAL,
     FACTORY,
     FALSE,
@@ -1153,7 +1157,7 @@
       stringValue: null);
 
   static const TokenType IDENTIFIER = const TokenType(
-      'identifier', 'STRING_INT', NO_PRECEDENCE, IDENTIFIER_TOKEN,
+      'identifier', 'IDENTIFIER', NO_PRECEDENCE, IDENTIFIER_TOKEN,
       stringValue: null);
 
   static const TokenType INT = const TokenType(
diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml
index 53c901f..42b24b6 100644
--- a/pkg/front_end/messages.yaml
+++ b/pkg/front_end/messages.yaml
@@ -181,18 +181,6 @@
   template: "Only maps can be used in spreads in constant maps."
   analyzerCode: CONST_SPREAD_EXPECTED_MAP
 
-ConstEvalIterationInConstList:
-  template: "Iteration can't be used in a constant list."
-  analyzerCode: NON_CONSTANT_LIST_ELEMENT
-
-ConstEvalIterationInConstSet:
-  template: "Iteration can't be used in a constant set."
-  analyzerCode: NON_CONSTANT_SET_ELEMENT
-
-ConstEvalIterationInConstMap:
-  template: "Iteration can't be used in a constant map."
-  analyzerCode: NON_CONSTANT_MAP_ELEMENT
-
 ConstEvalUnevaluated:
   template: "Could not evaluate constant expression."
 
@@ -335,7 +323,7 @@
   #
   analyzerCode: ParserErrorCode.EXPECTED_INSTEAD
   script:
-    - "mixin A extends B { }"
+    - "class B {} mixin A extends B { }"
 
 MultipleLibraryDirectives:
   index: 27
@@ -362,7 +350,7 @@
   template: "The extends clause must be before the with clause."
   tip: "Try moving the extends clause before the with clause."
   analyzerCode: ParserErrorCode.WITH_BEFORE_EXTENDS
-  script: "class B {} class A with B extends C {}"
+  script: "class B {} class C {} class A with B extends C {}"
 
 ImplementsBeforeExtends:
   index: 44
diff --git a/pkg/front_end/test/fasta/parser/type_info_test.dart b/pkg/front_end/test/fasta/parser/type_info_test.dart
index b100668..122a125 100644
--- a/pkg/front_end/test/fasta/parser/type_info_test.dart
+++ b/pkg/front_end/test/fasta/parser/type_info_test.dart
@@ -30,12 +30,10 @@
   });
 }
 
-ScannerResult scanString(String source,
-        {bool includeComments: false, Recover recover}) =>
+ScannerResult scanString(String source, {bool includeComments: false}) =>
     scanner.scanString(source,
         configuration: const ScannerConfiguration(enableTripleShift: true),
-        includeComments: includeComments,
-        recover: recover);
+        includeComments: includeComments);
 
 @reflectiveTest
 class NoTypeInfoTest {
diff --git a/pkg/front_end/test/scanner_fasta_test.dart b/pkg/front_end/test/scanner_fasta_test.dart
index 6af6e46..210e851 100644
--- a/pkg/front_end/test/scanner_fasta_test.dart
+++ b/pkg/front_end/test/scanner_fasta_test.dart
@@ -51,6 +51,29 @@
 
 @reflectiveTest
 class ScannerTest_Fasta_UTF8 extends ScannerTest_Fasta {
+  @override
+  Token scanWithListener(String source, ErrorListener listener,
+      {ScannerConfiguration configuration}) {
+    var bytes = utf8.encode(source).toList()..add(0);
+    var result =
+        scan(bytes, configuration: configuration, includeComments: true);
+    var token = result.tokens;
+
+    // Translate error tokens
+    if (result.hasErrors) {
+      while (token is ErrorToken) {
+        translateErrorToken(token,
+            (ScannerErrorCode errorCode, int offset, List<Object> arguments) {
+          listener.errors.add(new TestError(offset, errorCode, arguments));
+        });
+        token = token.next;
+      }
+    }
+
+    new Token.eof(-1)..setNext(token);
+    return token;
+  }
+
   test_invalid_utf8() {
     printBytes(List<int> bytes) {
       var hex = bytes.map((b) => '0x${b.toRadixString(16).toUpperCase()}');
@@ -85,8 +108,10 @@
 @reflectiveTest
 class ScannerTest_Fasta extends ScannerTestBase {
   @override
-  Token scanWithListener(String source, ErrorListener listener) {
-    var result = scanString(source, includeComments: true);
+  Token scanWithListener(String source, ErrorListener listener,
+      {ScannerConfiguration configuration}) {
+    var result =
+        scanString(source, configuration: configuration, includeComments: true);
     var token = result.tokens;
 
     // Translate error tokens
diff --git a/pkg/front_end/test/scanner_replacement_test.dart b/pkg/front_end/test/scanner_replacement_test.dart
index 25ad95f..b0a979a 100644
--- a/pkg/front_end/test/scanner_replacement_test.dart
+++ b/pkg/front_end/test/scanner_replacement_test.dart
@@ -2,10 +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 'dart:convert' show utf8;
-
-import 'package:front_end/src/fasta/scanner/recover.dart'
-    show defaultRecoveryStrategy;
 import 'package:front_end/src/fasta/scanner.dart' as fasta;
 import 'package:front_end/src/fasta/scanner/token.dart' as fasta;
 import 'package:front_end/src/fasta/scanner/error_token.dart' as fasta;
@@ -32,26 +28,18 @@
 @reflectiveTest
 class ScannerTest_Replacement extends ScannerTestBase {
   @override
-  analyzer.Token scanWithListener(String source, ErrorListener listener) {
+  analyzer.Token scanWithListener(String source, ErrorListener listener,
+      {fasta.ScannerConfiguration configuration}) {
     // Process the source similar to
     // pkg/analyzer/lib/src/dart/scanner/scanner.dart
     // to simulate replacing the analyzer scanner
 
-    fasta.ScannerResult result = fasta.scanString(source, includeComments: true,
-        recover: ((List<int> bytes, fasta.Token tokens, List<int> lineStarts) {
-      // perform recovery as a separate step
-      // so that the token stream can be validated before and after recovery
-      return tokens;
-    }));
+    fasta.ScannerResult result = fasta.scanString(source,
+        configuration: configuration, includeComments: true);
 
     fasta.Token tokens = result.tokens;
-    assertValidTokenStream(tokens);
+    assertValidTokenStream(tokens, errorsFirst: true);
     assertValidBeginTokens(tokens);
-    if (result.hasErrors) {
-      List<int> bytes = utf8.encode(source);
-      tokens = defaultRecoveryStrategy(bytes, tokens, result.lineStarts);
-      assertValidTokenStream(tokens, errorsFirst: true);
-    }
 
     // fasta pretends there is an additional line at EOF
     result.lineStarts.removeLast();
@@ -249,7 +237,7 @@
   /// that is in the stream.
   void assertValidBeginTokens(fasta.Token firstToken) {
     var openerStack = <analyzer.BeginToken>[];
-    analyzer.BeginToken lastClosedGroup;
+    var errorStack = <fasta.ErrorToken>[];
     fasta.Token token = firstToken;
     while (!token.isEof) {
       if (token is analyzer.BeginToken) {
@@ -257,17 +245,17 @@
           expect(token.endGroup, isNotNull, reason: token.lexeme);
         if (token.endGroup != null) openerStack.add(token);
       } else if (openerStack.isNotEmpty && openerStack.last.endGroup == token) {
-        lastClosedGroup = openerStack.removeLast();
-        expect(token.isSynthetic, token.next is fasta.UnmatchedToken,
-            reason: 'Expect synthetic closer then error token, '
-                'but found "$token" followed by "${token.next}"');
+        analyzer.BeginToken beginToken = openerStack.removeLast();
+        if (token.isSynthetic) {
+          fasta.ErrorToken errorToken = errorStack.removeAt(0);
+          expect(errorToken.begin, beginToken);
+        }
       } else if (token is fasta.UnmatchedToken) {
-        expect(lastClosedGroup?.endGroup?.next, same(token),
-            reason: 'Unexpected error token for group: $lastClosedGroup');
-        expect(token.begin, lastClosedGroup);
+        errorStack.add(token);
       }
       token = token.next;
     }
     expect(openerStack, isEmpty, reason: 'Missing closers');
+    expect(errorStack, isEmpty, reason: 'Extra error tokens');
   }
 }
diff --git a/pkg/front_end/test/scanner_test.dart b/pkg/front_end/test/scanner_test.dart
index 36b1477..932d67a 100644
--- a/pkg/front_end/test/scanner_test.dart
+++ b/pkg/front_end/test/scanner_test.dart
@@ -4,7 +4,7 @@
 
 import 'package:front_end/src/base/errors.dart';
 import 'package:front_end/src/fasta/scanner/abstract_scanner.dart'
-    show AbstractScanner;
+    show AbstractScanner, ScannerConfiguration;
 import 'package:front_end/src/scanner/errors.dart';
 import 'package:front_end/src/scanner/reader.dart';
 import 'package:front_end/src/scanner/token.dart';
@@ -79,7 +79,8 @@
 }
 
 abstract class ScannerTestBase {
-  Token scanWithListener(String source, ErrorListener listener);
+  Token scanWithListener(String source, ErrorListener listener,
+      {ScannerConfiguration configuration});
 
   void test_ampersand() {
     _assertToken(TokenType.AMPERSAND, "&");
@@ -442,6 +443,16 @@
     _assertKeywordToken("extends");
   }
 
+  void test_keyword_extension() {
+    _assertKeywordToken("extension",
+        configuration: ScannerConfiguration(enableExtensionMethods: true));
+  }
+
+  void test_keyword_extension_old() {
+    _assertNotKeywordToken("extension",
+        configuration: ScannerConfiguration(enableExtensionMethods: false));
+  }
+
   void test_keyword_factory() {
     _assertKeywordToken("factory");
   }
@@ -494,6 +505,16 @@
     _assertKeywordToken("is");
   }
 
+  void test_keyword_late() {
+    _assertKeywordToken("late",
+        configuration: ScannerConfiguration(enableNonNullable: true));
+  }
+
+  void test_keyword_late_old() {
+    _assertNotKeywordToken("late",
+        configuration: ScannerConfiguration(enableNonNullable: false));
+  }
+
   void test_keyword_library() {
     _assertKeywordToken("library");
   }
@@ -534,6 +555,16 @@
     _assertKeywordToken("patch");
   }
 
+  void test_keyword_required() {
+    _assertKeywordToken("required",
+        configuration: ScannerConfiguration(enableNonNullable: true));
+  }
+
+  void test_keyword_required_disabled() {
+    _assertNotKeywordToken("required",
+        configuration: ScannerConfiguration(enableNonNullable: false));
+  }
+
   void test_keyword_rethrow() {
     _assertKeywordToken("rethrow");
   }
@@ -1298,8 +1329,9 @@
    * Assert that when scanned the given [source] contains a single keyword token
    * with the same lexeme as the original source.
    */
-  void _assertKeywordToken(String source) {
-    Token token = _scan(source);
+  void _assertKeywordToken(String source,
+      {ScannerConfiguration configuration}) {
+    Token token = _scan(source, configuration: configuration);
     expect(token, isNotNull);
     expect(token.type.isKeyword, true);
     expect(token.offset, 0);
@@ -1308,7 +1340,7 @@
     Object value = token.value();
     expect(value is Keyword, isTrue);
     expect((value as Keyword).lexeme, source);
-    token = _scan(" $source ");
+    token = _scan(" $source ", configuration: configuration);
     expect(token, isNotNull);
     expect(token.type.isKeyword, true);
     expect(token.offset, 1);
@@ -1321,6 +1353,27 @@
   }
 
   /**
+   * Assert that when scanned the given [source] contains a single identifier token
+   * with the same lexeme as the original source.
+   */
+  void _assertNotKeywordToken(String source,
+      {ScannerConfiguration configuration}) {
+    Token token = _scan(source, configuration: configuration);
+    expect(token, isNotNull);
+    expect(token.type.isKeyword, false);
+    expect(token.offset, 0);
+    expect(token.length, source.length);
+    expect(token.lexeme, source);
+    token = _scan(" $source ", configuration: configuration);
+    expect(token, isNotNull);
+    expect(token.type.isKeyword, false);
+    expect(token.offset, 1);
+    expect(token.length, source.length);
+    expect(token.lexeme, source);
+    expect(token.next.type, TokenType.EOF);
+  }
+
+  /**
    * Assert that the token scanned from the given [source] has the
    * [expectedType].
    */
@@ -1399,9 +1452,11 @@
     expect(token.type, TokenType.EOF);
   }
 
-  Token _scan(String source, {bool ignoreErrors: false}) {
+  Token _scan(String source,
+      {ScannerConfiguration configuration, bool ignoreErrors: false}) {
     ErrorListener listener = new ErrorListener();
-    Token token = scanWithListener(source, listener);
+    Token token =
+        scanWithListener(source, listener, configuration: configuration);
     if (!ignoreErrors) {
       listener.assertNoErrors();
     }
diff --git a/pkg/front_end/test/token_test.dart b/pkg/front_end/test/token_test.dart
index fb9f1ae..fa62c06 100644
--- a/pkg/front_end/test/token_test.dart
+++ b/pkg/front_end/test/token_test.dart
@@ -91,6 +91,7 @@
       Keyword.DEFERRED,
       Keyword.DYNAMIC,
       Keyword.EXPORT,
+      Keyword.EXTENSION,
       Keyword.EXTERNAL,
       Keyword.FACTORY,
       Keyword.GET,
@@ -142,6 +143,7 @@
       Keyword.CLASS,
       Keyword.ENUM,
       Keyword.EXPORT,
+      //Keyword.EXTENSION, <-- when "extension methods" is enabled by default
       Keyword.IMPORT,
       Keyword.LIBRARY,
       Keyword.MIXIN,
diff --git a/pkg/front_end/testcases/duplicated_declarations.dart.legacy.expect b/pkg/front_end/testcases/duplicated_declarations.dart.legacy.expect
index 86ec30f..522465d 100644
--- a/pkg/front_end/testcases/duplicated_declarations.dart.legacy.expect
+++ b/pkg/front_end/testcases/duplicated_declarations.dart.legacy.expect
@@ -299,6 +299,13 @@
 // typedef Typedef = Object Function();
 //         ^^^^^^^
 //
+// pkg/front_end/testcases/duplicated_declarations.dart:65:19: Warning: 'C' isn't a type.
+// class Sub extends C {
+//                   ^
+// pkg/front_end/testcases/duplicated_declarations.dart:65:19: Context: This isn't a type.
+// class Sub extends C {
+//                   ^
+//
 // pkg/front_end/testcases/duplicated_declarations.dart:65:19: Error: 'C' isn't a type.
 // class Sub extends C {
 //                   ^
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 86ec30f..522465d 100644
--- a/pkg/front_end/testcases/duplicated_declarations.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/duplicated_declarations.dart.legacy.transformed.expect
@@ -299,6 +299,13 @@
 // typedef Typedef = Object Function();
 //         ^^^^^^^
 //
+// pkg/front_end/testcases/duplicated_declarations.dart:65:19: Warning: 'C' isn't a type.
+// class Sub extends C {
+//                   ^
+// pkg/front_end/testcases/duplicated_declarations.dart:65:19: Context: This isn't a type.
+// class Sub extends C {
+//                   ^
+//
 // pkg/front_end/testcases/duplicated_declarations.dart:65:19: Error: 'C' isn't a type.
 // class Sub extends C {
 //                   ^
diff --git a/pkg/front_end/testcases/duplicated_declarations.dart.outline.expect b/pkg/front_end/testcases/duplicated_declarations.dart.outline.expect
index 1933ac0..24178c0 100644
--- a/pkg/front_end/testcases/duplicated_declarations.dart.outline.expect
+++ b/pkg/front_end/testcases/duplicated_declarations.dart.outline.expect
@@ -299,6 +299,13 @@
 // typedef Typedef = Object Function();
 //         ^^^^^^^
 //
+// pkg/front_end/testcases/duplicated_declarations.dart:65:19: Warning: 'C' isn't a type.
+// class Sub extends C {
+//                   ^
+// pkg/front_end/testcases/duplicated_declarations.dart:65:19: Context: This isn't a type.
+// class Sub extends C {
+//                   ^
+//
 // pkg/front_end/testcases/duplicated_declarations.dart:65:19: Error: 'C' isn't a type.
 // class Sub extends C {
 //                   ^
diff --git a/pkg/front_end/testcases/duplicated_declarations.dart.strong.expect b/pkg/front_end/testcases/duplicated_declarations.dart.strong.expect
index 6e8d2d8..a34ac18 100644
--- a/pkg/front_end/testcases/duplicated_declarations.dart.strong.expect
+++ b/pkg/front_end/testcases/duplicated_declarations.dart.strong.expect
@@ -302,6 +302,13 @@
 // pkg/front_end/testcases/duplicated_declarations.dart:65:19: Error: 'C' isn't a type.
 // class Sub extends C {
 //                   ^
+// pkg/front_end/testcases/duplicated_declarations.dart:65:19: Context: This isn't a type.
+// class Sub extends C {
+//                   ^
+//
+// pkg/front_end/testcases/duplicated_declarations.dart:65:19: Error: 'C' isn't a type.
+// class Sub extends C {
+//                   ^
 //
 // pkg/front_end/testcases/duplicated_declarations.dart:34:3: Error: Can't use 'main' because it is declared more than once.
 //   main();
diff --git a/pkg/front_end/testcases/function_type_default_value.dart.legacy.expect b/pkg/front_end/testcases/function_type_default_value.dart.legacy.expect
index 17bf98f..5a6a508 100644
--- a/pkg/front_end/testcases/function_type_default_value.dart.legacy.expect
+++ b/pkg/front_end/testcases/function_type_default_value.dart.legacy.expect
@@ -10,6 +10,10 @@
 // void Function({obj: Object}) x;
 //                   ^
 //
+// pkg/front_end/testcases/function_type_default_value.dart:5:16: Warning: Type 'obj' not found.
+// void Function({obj: Object}) x;
+//                ^^^
+//
 // pkg/front_end/testcases/function_type_default_value.dart:5:16: Warning: 'obj' isn't a type.
 // void Function({obj: Object}) x;
 //                ^^^
diff --git a/pkg/front_end/testcases/function_type_default_value.dart.legacy.transformed.expect b/pkg/front_end/testcases/function_type_default_value.dart.legacy.transformed.expect
index 17bf98f..5a6a508 100644
--- a/pkg/front_end/testcases/function_type_default_value.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/function_type_default_value.dart.legacy.transformed.expect
@@ -10,6 +10,10 @@
 // void Function({obj: Object}) x;
 //                   ^
 //
+// pkg/front_end/testcases/function_type_default_value.dart:5:16: Warning: Type 'obj' not found.
+// void Function({obj: Object}) x;
+//                ^^^
+//
 // pkg/front_end/testcases/function_type_default_value.dart:5:16: Warning: 'obj' isn't a type.
 // void Function({obj: Object}) x;
 //                ^^^
diff --git a/pkg/front_end/testcases/function_type_default_value.dart.outline.expect b/pkg/front_end/testcases/function_type_default_value.dart.outline.expect
index ce8fac7..bff8898 100644
--- a/pkg/front_end/testcases/function_type_default_value.dart.outline.expect
+++ b/pkg/front_end/testcases/function_type_default_value.dart.outline.expect
@@ -10,6 +10,10 @@
 // void Function({obj: Object}) x;
 //                   ^
 //
+// pkg/front_end/testcases/function_type_default_value.dart:5:16: Warning: Type 'obj' not found.
+// void Function({obj: Object}) x;
+//                ^^^
+//
 import self as self;
 
 static field () → void x;
diff --git a/pkg/front_end/testcases/function_type_default_value.dart.strong.expect b/pkg/front_end/testcases/function_type_default_value.dart.strong.expect
index dd48e08..6f1c9a9 100644
--- a/pkg/front_end/testcases/function_type_default_value.dart.strong.expect
+++ b/pkg/front_end/testcases/function_type_default_value.dart.strong.expect
@@ -10,6 +10,10 @@
 // void Function({obj: Object}) x;
 //                   ^
 //
+// pkg/front_end/testcases/function_type_default_value.dart:5:16: Error: Type 'obj' not found.
+// void Function({obj: Object}) x;
+//                ^^^
+//
 // pkg/front_end/testcases/function_type_default_value.dart:5:16: Error: 'obj' isn't a type.
 // void Function({obj: Object}) x;
 //                ^^^
diff --git a/pkg/front_end/testcases/function_type_default_value.dart.strong.transformed.expect b/pkg/front_end/testcases/function_type_default_value.dart.strong.transformed.expect
index dd48e08..6f1c9a9 100644
--- a/pkg/front_end/testcases/function_type_default_value.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/function_type_default_value.dart.strong.transformed.expect
@@ -10,6 +10,10 @@
 // void Function({obj: Object}) x;
 //                   ^
 //
+// pkg/front_end/testcases/function_type_default_value.dart:5:16: Error: Type 'obj' not found.
+// void Function({obj: Object}) x;
+//                ^^^
+//
 // pkg/front_end/testcases/function_type_default_value.dart:5:16: Error: 'obj' isn't a type.
 // void Function({obj: Object}) x;
 //                ^^^
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_from_compiled.dart.strong.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_from_compiled.dart.strong.expect
index dbf94d5..ce101a2 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/non_simple_from_compiled.dart.strong.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_from_compiled.dart.strong.expect
@@ -7,12 +7,6 @@
 // class Hest<X extends LinkedListEntry> {}
 //            ^
 //
-// pkg/front_end/testcases/instantiate_to_bound/non_simple_from_compiled.dart:15:12: Error: Type argument 'LinkedListEntry<dynamic>' doesn't conform to the bound 'LinkedListEntry<E>' of the type variable 'E' on 'LinkedListEntry'.
-//  - 'LinkedListEntry' is from 'dart:collection'.
-// Try changing type arguments so that they conform to the bounds.
-// class Hest<X extends LinkedListEntry> {}
-//            ^
-//
 import self as self;
 import "dart:collection" as col;
 import "dart:core" as core;
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_from_compiled.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_from_compiled.dart.strong.transformed.expect
index dbf94d5..ce101a2 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/non_simple_from_compiled.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_from_compiled.dart.strong.transformed.expect
@@ -7,12 +7,6 @@
 // class Hest<X extends LinkedListEntry> {}
 //            ^
 //
-// pkg/front_end/testcases/instantiate_to_bound/non_simple_from_compiled.dart:15:12: Error: Type argument 'LinkedListEntry<dynamic>' doesn't conform to the bound 'LinkedListEntry<E>' of the type variable 'E' on 'LinkedListEntry'.
-//  - 'LinkedListEntry' is from 'dart:collection'.
-// Try changing type arguments so that they conform to the bounds.
-// class Hest<X extends LinkedListEntry> {}
-//            ^
-//
 import self as self;
 import "dart:collection" as col;
 import "dart:core" as core;
diff --git a/pkg/front_end/testcases/instantiate_to_bound/super_bounded_in_bound.dart b/pkg/front_end/testcases/instantiate_to_bound/super_bounded_in_bound.dart
new file mode 100644
index 0000000..8ecef66
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/super_bounded_in_bound.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class A<X extends Comparable<X>> {}
+
+class B<Y extends A<dynamic>> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/super_bounded_in_bound.dart.hierarchy.expect b/pkg/front_end/testcases/instantiate_to_bound/super_bounded_in_bound.dart.hierarchy.expect
new file mode 100644
index 0000000..523e0f4
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/super_bounded_in_bound.dart.hierarchy.expect
@@ -0,0 +1,53 @@
+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
+  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/instantiate_to_bound/super_bounded_in_bound.dart.legacy.expect b/pkg/front_end/testcases/instantiate_to_bound/super_bounded_in_bound.dart.legacy.expect
new file mode 100644
index 0000000..6b8efb5
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/super_bounded_in_bound.dart.legacy.expect
@@ -0,0 +1,15 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A<X extends core::Comparable<self::A::X> = dynamic> extends core::Object {
+  synthetic constructor •() → self::A<self::A::X>
+    : super core::Object::•()
+    ;
+}
+class B<Y extends self::A<dynamic> = dynamic> extends core::Object {
+  synthetic constructor •() → self::B<self::B::Y>
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/super_bounded_in_bound.dart.legacy.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/super_bounded_in_bound.dart.legacy.transformed.expect
new file mode 100644
index 0000000..6b8efb5
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/super_bounded_in_bound.dart.legacy.transformed.expect
@@ -0,0 +1,15 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A<X extends core::Comparable<self::A::X> = dynamic> extends core::Object {
+  synthetic constructor •() → self::A<self::A::X>
+    : super core::Object::•()
+    ;
+}
+class B<Y extends self::A<dynamic> = dynamic> extends core::Object {
+  synthetic constructor •() → self::B<self::B::Y>
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/super_bounded_in_bound.dart.outline.expect b/pkg/front_end/testcases/instantiate_to_bound/super_bounded_in_bound.dart.outline.expect
new file mode 100644
index 0000000..9a334ff
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/super_bounded_in_bound.dart.outline.expect
@@ -0,0 +1,14 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A<X extends core::Comparable<self::A::X> = dynamic> extends core::Object {
+  synthetic constructor •() → self::A<self::A::X>
+    ;
+}
+class B<Y extends self::A<dynamic> = dynamic> extends core::Object {
+  synthetic constructor •() → self::B<self::B::Y>
+    ;
+}
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/instantiate_to_bound/super_bounded_in_bound.dart.strong.expect b/pkg/front_end/testcases/instantiate_to_bound/super_bounded_in_bound.dart.strong.expect
new file mode 100644
index 0000000..88cbec9
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/super_bounded_in_bound.dart.strong.expect
@@ -0,0 +1,15 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A<X extends core::Comparable<self::A::X> = core::Comparable<dynamic>> extends core::Object {
+  synthetic constructor •() → self::A<self::A::X>
+    : super core::Object::•()
+    ;
+}
+class B<Y extends self::A<dynamic> = self::A<dynamic>> extends core::Object {
+  synthetic constructor •() → self::B<self::B::Y>
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/super_bounded_in_bound.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/super_bounded_in_bound.dart.strong.transformed.expect
new file mode 100644
index 0000000..88cbec9
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/super_bounded_in_bound.dart.strong.transformed.expect
@@ -0,0 +1,15 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A<X extends core::Comparable<self::A::X> = core::Comparable<dynamic>> extends core::Object {
+  synthetic constructor •() → self::A<self::A::X>
+    : super core::Object::•()
+    ;
+}
+class B<Y extends self::A<dynamic> = self::A<dynamic>> extends core::Object {
+  synthetic constructor •() → self::B<self::B::Y>
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/operator_method_not_found.dart.legacy.expect b/pkg/front_end/testcases/operator_method_not_found.dart.legacy.expect
index 0abf9ef..69ee9a4 100644
--- a/pkg/front_end/testcases/operator_method_not_found.dart.legacy.expect
+++ b/pkg/front_end/testcases/operator_method_not_found.dart.legacy.expect
@@ -2,6 +2,10 @@
 //
 // Problems in library:
 //
+// pkg/front_end/testcases/operator_method_not_found.dart:36:10: Warning: 'foo' isn't a type.
+//   print(<foo);
+//          ^^^
+//
 // pkg/front_end/testcases/operator_method_not_found.dart:36:10: Error: Expected '>' after this.
 //   print(<foo);
 //          ^^^
@@ -10,10 +14,6 @@
 //   print(<foo);
 //             ^
 //
-// pkg/front_end/testcases/operator_method_not_found.dart:36:10: Warning: 'foo' isn't a type.
-//   print(<foo);
-//          ^^^
-//
 // pkg/front_end/testcases/operator_method_not_found.dart:37:9: Error: Expected an identifier, but got '>'.
 //   print(>foo);
 //         ^
diff --git a/pkg/front_end/testcases/operator_method_not_found.dart.legacy.transformed.expect b/pkg/front_end/testcases/operator_method_not_found.dart.legacy.transformed.expect
index 0abf9ef..69ee9a4 100644
--- a/pkg/front_end/testcases/operator_method_not_found.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/operator_method_not_found.dart.legacy.transformed.expect
@@ -2,6 +2,10 @@
 //
 // Problems in library:
 //
+// pkg/front_end/testcases/operator_method_not_found.dart:36:10: Warning: 'foo' isn't a type.
+//   print(<foo);
+//          ^^^
+//
 // pkg/front_end/testcases/operator_method_not_found.dart:36:10: Error: Expected '>' after this.
 //   print(<foo);
 //          ^^^
@@ -10,10 +14,6 @@
 //   print(<foo);
 //             ^
 //
-// pkg/front_end/testcases/operator_method_not_found.dart:36:10: Warning: 'foo' isn't a type.
-//   print(<foo);
-//          ^^^
-//
 // pkg/front_end/testcases/operator_method_not_found.dart:37:9: Error: Expected an identifier, but got '>'.
 //   print(>foo);
 //         ^
diff --git a/pkg/front_end/testcases/operator_method_not_found.dart.strong.expect b/pkg/front_end/testcases/operator_method_not_found.dart.strong.expect
index ec89d36..5399098 100644
--- a/pkg/front_end/testcases/operator_method_not_found.dart.strong.expect
+++ b/pkg/front_end/testcases/operator_method_not_found.dart.strong.expect
@@ -2,6 +2,10 @@
 //
 // Problems in library:
 //
+// pkg/front_end/testcases/operator_method_not_found.dart:36:10: Error: 'foo' isn't a type.
+//   print(<foo);
+//          ^^^
+//
 // pkg/front_end/testcases/operator_method_not_found.dart:36:10: Error: Expected '>' after this.
 //   print(<foo);
 //          ^^^
@@ -10,10 +14,6 @@
 //   print(<foo);
 //             ^
 //
-// pkg/front_end/testcases/operator_method_not_found.dart:36:10: Error: 'foo' isn't a type.
-//   print(<foo);
-//          ^^^
-//
 // pkg/front_end/testcases/operator_method_not_found.dart:37:9: Error: Expected an identifier, but got '>'.
 //   print(>foo);
 //         ^
diff --git a/pkg/front_end/testcases/operator_method_not_found.dart.strong.transformed.expect b/pkg/front_end/testcases/operator_method_not_found.dart.strong.transformed.expect
index ec89d36..5399098 100644
--- a/pkg/front_end/testcases/operator_method_not_found.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/operator_method_not_found.dart.strong.transformed.expect
@@ -2,6 +2,10 @@
 //
 // Problems in library:
 //
+// pkg/front_end/testcases/operator_method_not_found.dart:36:10: Error: 'foo' isn't a type.
+//   print(<foo);
+//          ^^^
+//
 // pkg/front_end/testcases/operator_method_not_found.dart:36:10: Error: Expected '>' after this.
 //   print(<foo);
 //          ^^^
@@ -10,10 +14,6 @@
 //   print(<foo);
 //             ^
 //
-// pkg/front_end/testcases/operator_method_not_found.dart:36:10: Error: 'foo' isn't a type.
-//   print(<foo);
-//          ^^^
-//
 // pkg/front_end/testcases/operator_method_not_found.dart:37:9: Error: Expected an identifier, but got '>'.
 //   print(>foo);
 //         ^
diff --git a/pkg/front_end/testcases/qualified.dart.legacy.expect b/pkg/front_end/testcases/qualified.dart.legacy.expect
index bd70509..6afde2e 100644
--- a/pkg/front_end/testcases/qualified.dart.legacy.expect
+++ b/pkg/front_end/testcases/qualified.dart.legacy.expect
@@ -9,6 +9,10 @@
 // class Bad extends lib.Missing {
 //       ^^^
 //
+// pkg/front_end/testcases/qualified.dart:11:19: Warning: Type 'lib.Missing' not found.
+// class Bad extends lib.Missing {
+//                   ^^^^^^^^^^^
+//
 // pkg/front_end/testcases/qualified.dart:12:3: Warning: Type 'lib.Missing' not found.
 //   lib.Missing method() {}
 //   ^^^^^^^^^^^
diff --git a/pkg/front_end/testcases/qualified.dart.legacy.transformed.expect b/pkg/front_end/testcases/qualified.dart.legacy.transformed.expect
index df06d18..4da117d4c6 100644
--- a/pkg/front_end/testcases/qualified.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/qualified.dart.legacy.transformed.expect
@@ -9,6 +9,10 @@
 // class Bad extends lib.Missing {
 //       ^^^
 //
+// pkg/front_end/testcases/qualified.dart:11:19: Warning: Type 'lib.Missing' not found.
+// class Bad extends lib.Missing {
+//                   ^^^^^^^^^^^
+//
 // pkg/front_end/testcases/qualified.dart:12:3: Warning: Type 'lib.Missing' not found.
 //   lib.Missing method() {}
 //   ^^^^^^^^^^^
diff --git a/pkg/front_end/testcases/qualified.dart.outline.expect b/pkg/front_end/testcases/qualified.dart.outline.expect
index 0fca5f9..6df7d32 100644
--- a/pkg/front_end/testcases/qualified.dart.outline.expect
+++ b/pkg/front_end/testcases/qualified.dart.outline.expect
@@ -9,6 +9,10 @@
 // class Bad extends lib.Missing {
 //       ^^^
 //
+// pkg/front_end/testcases/qualified.dart:11:19: Warning: Type 'lib.Missing' not found.
+// class Bad extends lib.Missing {
+//                   ^^^^^^^^^^^
+//
 // pkg/front_end/testcases/qualified.dart:12:3: Warning: Type 'lib.Missing' not found.
 //   lib.Missing method() {}
 //   ^^^^^^^^^^^
diff --git a/pkg/front_end/testcases/qualified.dart.strong.expect b/pkg/front_end/testcases/qualified.dart.strong.expect
index 9bc943f..c145d18 100644
--- a/pkg/front_end/testcases/qualified.dart.strong.expect
+++ b/pkg/front_end/testcases/qualified.dart.strong.expect
@@ -9,14 +9,14 @@
 // class Bad extends lib.Missing {
 //       ^^^
 //
-// pkg/front_end/testcases/qualified.dart:12:3: Error: Type 'lib.Missing' not found.
-//   lib.Missing method() {}
-//   ^^^^^^^^^^^
-//
 // pkg/front_end/testcases/qualified.dart:11:19: Error: Type 'lib.Missing' not found.
 // class Bad extends lib.Missing {
 //                   ^^^^^^^^^^^
 //
+// pkg/front_end/testcases/qualified.dart:12:3: Error: Type 'lib.Missing' not found.
+//   lib.Missing method() {}
+//   ^^^^^^^^^^^
+//
 // pkg/front_end/testcases/qualified.dart:18:7: Error: The type 'lib.VoidFunction' can't be used as supertype.
 // class IllegalSupertype extends lib.VoidFunction {}
 //       ^
diff --git a/pkg/front_end/testcases/qualified.dart.strong.transformed.expect b/pkg/front_end/testcases/qualified.dart.strong.transformed.expect
index 197c0d8..5c3bf8c 100644
--- a/pkg/front_end/testcases/qualified.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/qualified.dart.strong.transformed.expect
@@ -9,14 +9,14 @@
 // class Bad extends lib.Missing {
 //       ^^^
 //
-// pkg/front_end/testcases/qualified.dart:12:3: Error: Type 'lib.Missing' not found.
-//   lib.Missing method() {}
-//   ^^^^^^^^^^^
-//
 // pkg/front_end/testcases/qualified.dart:11:19: Error: Type 'lib.Missing' not found.
 // class Bad extends lib.Missing {
 //                   ^^^^^^^^^^^
 //
+// pkg/front_end/testcases/qualified.dart:12:3: Error: Type 'lib.Missing' not found.
+//   lib.Missing method() {}
+//   ^^^^^^^^^^^
+//
 // pkg/front_end/testcases/qualified.dart:18:7: Error: The type 'lib.VoidFunction' can't be used as supertype.
 // class IllegalSupertype extends lib.VoidFunction {}
 //       ^
diff --git a/pkg/front_end/testcases/rasta/class_hierarchy.dart.outline.expect b/pkg/front_end/testcases/rasta/class_hierarchy.dart.outline.expect
index a6ec9b4..184037de 100644
--- a/pkg/front_end/testcases/rasta/class_hierarchy.dart.outline.expect
+++ b/pkg/front_end/testcases/rasta/class_hierarchy.dart.outline.expect
@@ -2,6 +2,18 @@
 //
 // Problems in library:
 //
+// pkg/front_end/testcases/rasta/class_hierarchy.dart:5:17: Warning: Type 'Missing' not found.
+// class A extends Missing {}
+//                 ^^^^^^^
+//
+// pkg/front_end/testcases/rasta/class_hierarchy.dart:7:20: Warning: Type 'Missing' not found.
+// class B implements Missing {}
+//                    ^^^^^^^
+//
+// pkg/front_end/testcases/rasta/class_hierarchy.dart:9:23: Warning: Type 'Missing' not found.
+// class C = Object with Missing;
+//                       ^^^^^^^
+//
 // pkg/front_end/testcases/rasta/class_hierarchy.dart:9:7: Error: The type 'Missing' can't be mixed in.
 // class C = Object with Missing;
 //       ^
diff --git a/pkg/front_end/testcases/rasta/class_hierarchy.dart.strong.expect b/pkg/front_end/testcases/rasta/class_hierarchy.dart.strong.expect
index d874733..06d8f86 100644
--- a/pkg/front_end/testcases/rasta/class_hierarchy.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/class_hierarchy.dart.strong.expect
@@ -2,10 +2,6 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/rasta/class_hierarchy.dart:9:7: Error: The type 'Missing' can't be mixed in.
-// class C = Object with Missing;
-//       ^
-//
 // pkg/front_end/testcases/rasta/class_hierarchy.dart:5:17: Error: Type 'Missing' not found.
 // class A extends Missing {}
 //                 ^^^^^^^
@@ -18,6 +14,10 @@
 // class C = Object with Missing;
 //                       ^^^^^^^
 //
+// pkg/front_end/testcases/rasta/class_hierarchy.dart:9:7: Error: The type 'Missing' can't be mixed in.
+// class C = Object with Missing;
+//       ^
+//
 // pkg/front_end/testcases/rasta/class_hierarchy.dart:12:17: Error: Couldn't find constructor 'Missing'.
 //   factory D() = Missing;
 //                 ^
diff --git a/pkg/front_end/testcases/rasta/class_hierarchy.dart.strong.transformed.expect b/pkg/front_end/testcases/rasta/class_hierarchy.dart.strong.transformed.expect
index 94f01e5..9184493 100644
--- a/pkg/front_end/testcases/rasta/class_hierarchy.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/rasta/class_hierarchy.dart.strong.transformed.expect
@@ -2,10 +2,6 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/rasta/class_hierarchy.dart:9:7: Error: The type 'Missing' can't be mixed in.
-// class C = Object with Missing;
-//       ^
-//
 // pkg/front_end/testcases/rasta/class_hierarchy.dart:5:17: Error: Type 'Missing' not found.
 // class A extends Missing {}
 //                 ^^^^^^^
@@ -18,6 +14,10 @@
 // class C = Object with Missing;
 //                       ^^^^^^^
 //
+// pkg/front_end/testcases/rasta/class_hierarchy.dart:9:7: Error: The type 'Missing' can't be mixed in.
+// class C = Object with Missing;
+//       ^
+//
 // pkg/front_end/testcases/rasta/class_hierarchy.dart:12:17: Error: Couldn't find constructor 'Missing'.
 //   factory D() = Missing;
 //                 ^
diff --git a/pkg/front_end/testcases/regress/issue_31188.dart.legacy.expect b/pkg/front_end/testcases/regress/issue_31188.dart.legacy.expect
index ee42a18..8220450 100644
--- a/pkg/front_end/testcases/regress/issue_31188.dart.legacy.expect
+++ b/pkg/front_end/testcases/regress/issue_31188.dart.legacy.expect
@@ -14,14 +14,14 @@
 // type T = Map<A, B>
 // ^^^^
 //
-// pkg/front_end/testcases/regress/issue_31188.dart:7:14: Warning: Getter not found: 'A'.
-// type T = Map<A, B>
-//              ^
-//
 // pkg/front_end/testcases/regress/issue_31188.dart:7:1: Warning: 'type' isn't a type.
 // type T = Map<A, B>
 // ^^^^
 //
+// pkg/front_end/testcases/regress/issue_31188.dart:7:14: Warning: Getter not found: 'A'.
+// type T = Map<A, B>
+//              ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_31188.dart.legacy.transformed.expect b/pkg/front_end/testcases/regress/issue_31188.dart.legacy.transformed.expect
index ee42a18..8220450 100644
--- a/pkg/front_end/testcases/regress/issue_31188.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_31188.dart.legacy.transformed.expect
@@ -14,14 +14,14 @@
 // type T = Map<A, B>
 // ^^^^
 //
-// pkg/front_end/testcases/regress/issue_31188.dart:7:14: Warning: Getter not found: 'A'.
-// type T = Map<A, B>
-//              ^
-//
 // pkg/front_end/testcases/regress/issue_31188.dart:7:1: Warning: 'type' isn't a type.
 // type T = Map<A, B>
 // ^^^^
 //
+// pkg/front_end/testcases/regress/issue_31188.dart:7:14: Warning: Getter not found: 'A'.
+// type T = Map<A, B>
+//              ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_31188.dart.strong.expect b/pkg/front_end/testcases/regress/issue_31188.dart.strong.expect
index 104418a..c0f1dea 100644
--- a/pkg/front_end/testcases/regress/issue_31188.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_31188.dart.strong.expect
@@ -14,6 +14,10 @@
 // type T = Map<A, B>
 // ^^^^
 //
+// pkg/front_end/testcases/regress/issue_31188.dart:7:1: Error: 'type' isn't a type.
+// type T = Map<A, B>
+// ^^^^
+//
 // pkg/front_end/testcases/regress/issue_31188.dart:7:14: Error: Getter not found: 'A'.
 // type T = Map<A, B>
 //              ^
@@ -24,10 +28,6 @@
 // type T = Map<A, B>
 //             ^
 //
-// pkg/front_end/testcases/regress/issue_31188.dart:7:1: Error: 'type' isn't a type.
-// type T = Map<A, B>
-// ^^^^
-//
 import self as self;
 
 static field invalid-type T = invalid-expression "pkg/front_end/testcases/regress/issue_31188.dart:7:13: Error: The method '<' isn't defined for the class 'Type'.
diff --git a/pkg/front_end/testcases/regress/issue_31188.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_31188.dart.strong.transformed.expect
index 104418a..c0f1dea 100644
--- a/pkg/front_end/testcases/regress/issue_31188.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_31188.dart.strong.transformed.expect
@@ -14,6 +14,10 @@
 // type T = Map<A, B>
 // ^^^^
 //
+// pkg/front_end/testcases/regress/issue_31188.dart:7:1: Error: 'type' isn't a type.
+// type T = Map<A, B>
+// ^^^^
+//
 // pkg/front_end/testcases/regress/issue_31188.dart:7:14: Error: Getter not found: 'A'.
 // type T = Map<A, B>
 //              ^
@@ -24,10 +28,6 @@
 // type T = Map<A, B>
 //             ^
 //
-// pkg/front_end/testcases/regress/issue_31188.dart:7:1: Error: 'type' isn't a type.
-// type T = Map<A, B>
-// ^^^^
-//
 import self as self;
 
 static field invalid-type T = invalid-expression "pkg/front_end/testcases/regress/issue_31188.dart:7:13: Error: The method '<' isn't defined for the class 'Type'.
diff --git a/pkg/front_end/testcases/regress/issue_31190.dart.legacy.expect b/pkg/front_end/testcases/regress/issue_31190.dart.legacy.expect
index 22dd31b..7bfc382 100644
--- a/pkg/front_end/testcases/regress/issue_31190.dart.legacy.expect
+++ b/pkg/front_end/testcases/regress/issue_31190.dart.legacy.expect
@@ -7,6 +7,10 @@
 //   T<U> v;
 //   ^
 //
+// pkg/front_end/testcases/regress/issue_31190.dart:6:5: Warning: Type 'U' not found.
+//   T<U> v;
+//     ^
+//
 // pkg/front_end/testcases/regress/issue_31190.dart:6:5: Warning: 'U' isn't a type.
 //   T<U> v;
 //     ^
diff --git a/pkg/front_end/testcases/regress/issue_31190.dart.legacy.transformed.expect b/pkg/front_end/testcases/regress/issue_31190.dart.legacy.transformed.expect
index 22dd31b..7bfc382 100644
--- a/pkg/front_end/testcases/regress/issue_31190.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_31190.dart.legacy.transformed.expect
@@ -7,6 +7,10 @@
 //   T<U> v;
 //   ^
 //
+// pkg/front_end/testcases/regress/issue_31190.dart:6:5: Warning: Type 'U' not found.
+//   T<U> v;
+//     ^
+//
 // pkg/front_end/testcases/regress/issue_31190.dart:6:5: Warning: 'U' isn't a type.
 //   T<U> v;
 //     ^
diff --git a/pkg/front_end/testcases/regress/issue_31190.dart.outline.expect b/pkg/front_end/testcases/regress/issue_31190.dart.outline.expect
index 1d72ade..5820107 100644
--- a/pkg/front_end/testcases/regress/issue_31190.dart.outline.expect
+++ b/pkg/front_end/testcases/regress/issue_31190.dart.outline.expect
@@ -7,6 +7,10 @@
 //   T<U> v;
 //   ^
 //
+// pkg/front_end/testcases/regress/issue_31190.dart:6:5: Warning: Type 'U' not found.
+//   T<U> v;
+//     ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_31190.dart.strong.expect b/pkg/front_end/testcases/regress/issue_31190.dart.strong.expect
index 20196d3..3ccd713 100644
--- a/pkg/front_end/testcases/regress/issue_31190.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_31190.dart.strong.expect
@@ -7,6 +7,10 @@
 //   T<U> v;
 //   ^
 //
+// pkg/front_end/testcases/regress/issue_31190.dart:6:5: Error: Type 'U' not found.
+//   T<U> v;
+//     ^
+//
 // pkg/front_end/testcases/regress/issue_31190.dart:6:5: Error: 'U' isn't a type.
 //   T<U> v;
 //     ^
diff --git a/pkg/front_end/testcases/regress/issue_31190.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_31190.dart.strong.transformed.expect
index 20196d3..3ccd713 100644
--- a/pkg/front_end/testcases/regress/issue_31190.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_31190.dart.strong.transformed.expect
@@ -7,6 +7,10 @@
 //   T<U> v;
 //   ^
 //
+// pkg/front_end/testcases/regress/issue_31190.dart:6:5: Error: Type 'U' not found.
+//   T<U> v;
+//     ^
+//
 // pkg/front_end/testcases/regress/issue_31190.dart:6:5: Error: 'U' isn't a type.
 //   T<U> v;
 //     ^
diff --git a/pkg/front_end/testcases/regress/issue_34498.dart.legacy.expect b/pkg/front_end/testcases/regress/issue_34498.dart.legacy.expect
index 6efe51f..0922a4f 100644
--- a/pkg/front_end/testcases/regress/issue_34498.dart.legacy.expect
+++ b/pkg/front_end/testcases/regress/issue_34498.dart.legacy.expect
@@ -13,15 +13,15 @@
 //   foo foo() {}
 //       ^^^
 //
-// pkg/front_end/testcases/regress/issue_34498.dart:12:3: Warning: Type 'Missing' not found.
-//   Missing bar() {}
-//   ^^^^^^^
-//
 // pkg/front_end/testcases/regress/issue_34498.dart:20:3: Warning: Can't use type arguments with type variable 'T'.
 // Try removing the type arguments.
 //   T<String> foo() {}
 //   ^
 //
+// pkg/front_end/testcases/regress/issue_34498.dart:12:3: Warning: Type 'Missing' not found.
+//   Missing bar() {}
+//   ^^^^^^^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_34498.dart.legacy.transformed.expect b/pkg/front_end/testcases/regress/issue_34498.dart.legacy.transformed.expect
index 6efe51f..0922a4f 100644
--- a/pkg/front_end/testcases/regress/issue_34498.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_34498.dart.legacy.transformed.expect
@@ -13,15 +13,15 @@
 //   foo foo() {}
 //       ^^^
 //
-// pkg/front_end/testcases/regress/issue_34498.dart:12:3: Warning: Type 'Missing' not found.
-//   Missing bar() {}
-//   ^^^^^^^
-//
 // pkg/front_end/testcases/regress/issue_34498.dart:20:3: Warning: Can't use type arguments with type variable 'T'.
 // Try removing the type arguments.
 //   T<String> foo() {}
 //   ^
 //
+// pkg/front_end/testcases/regress/issue_34498.dart:12:3: Warning: Type 'Missing' not found.
+//   Missing bar() {}
+//   ^^^^^^^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_34498.dart.outline.expect b/pkg/front_end/testcases/regress/issue_34498.dart.outline.expect
index 23a4800..9a8a1f8 100644
--- a/pkg/front_end/testcases/regress/issue_34498.dart.outline.expect
+++ b/pkg/front_end/testcases/regress/issue_34498.dart.outline.expect
@@ -13,15 +13,15 @@
 //   foo foo() {}
 //       ^^^
 //
-// pkg/front_end/testcases/regress/issue_34498.dart:12:3: Warning: Type 'Missing' not found.
-//   Missing bar() {}
-//   ^^^^^^^
-//
 // pkg/front_end/testcases/regress/issue_34498.dart:20:3: Warning: Can't use type arguments with type variable 'T'.
 // Try removing the type arguments.
 //   T<String> foo() {}
 //   ^
 //
+// pkg/front_end/testcases/regress/issue_34498.dart:12:3: Warning: Type 'Missing' not found.
+//   Missing bar() {}
+//   ^^^^^^^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_34498.dart.strong.expect b/pkg/front_end/testcases/regress/issue_34498.dart.strong.expect
index f90b74b..a72249c 100644
--- a/pkg/front_end/testcases/regress/issue_34498.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_34498.dart.strong.expect
@@ -13,15 +13,15 @@
 //   foo foo() {}
 //       ^^^
 //
-// pkg/front_end/testcases/regress/issue_34498.dart:12:3: Error: Type 'Missing' not found.
-//   Missing bar() {}
-//   ^^^^^^^
-//
 // pkg/front_end/testcases/regress/issue_34498.dart:20:3: Error: Can't use type arguments with type variable 'T'.
 // Try removing the type arguments.
 //   T<String> foo() {}
 //   ^
 //
+// pkg/front_end/testcases/regress/issue_34498.dart:12:3: Error: Type 'Missing' not found.
+//   Missing bar() {}
+//   ^^^^^^^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_34498.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_34498.dart.strong.transformed.expect
index f90b74b..a72249c 100644
--- a/pkg/front_end/testcases/regress/issue_34498.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_34498.dart.strong.transformed.expect
@@ -13,15 +13,15 @@
 //   foo foo() {}
 //       ^^^
 //
-// pkg/front_end/testcases/regress/issue_34498.dart:12:3: Error: Type 'Missing' not found.
-//   Missing bar() {}
-//   ^^^^^^^
-//
 // pkg/front_end/testcases/regress/issue_34498.dart:20:3: Error: Can't use type arguments with type variable 'T'.
 // Try removing the type arguments.
 //   T<String> foo() {}
 //   ^
 //
+// pkg/front_end/testcases/regress/issue_34498.dart:12:3: Error: Type 'Missing' not found.
+//   Missing bar() {}
+//   ^^^^^^^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_34850.dart.strong.expect b/pkg/front_end/testcases/regress/issue_34850.dart.strong.expect
index f3100e5..f79536d 100644
--- a/pkg/front_end/testcases/regress/issue_34850.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_34850.dart.strong.expect
@@ -27,6 +27,10 @@
 // Future<List<>> f3() async {
 //             ^^
 //
+// pkg/front_end/testcases/regress/issue_34850.dart:5:2: Error: Type 'foo' not found.
+// <foo<
+//  ^^^
+//
 // pkg/front_end/testcases/regress/issue_34850.dart:5:2: Error: Expected 0 type arguments.
 // <foo<
 //  ^
@@ -35,6 +39,13 @@
 // foo
 // ^^^
 //
+// pkg/front_end/testcases/regress/issue_34850.dart:14:1: Error: 'Future' isn't a type.
+// Future<List<>> f3() async {
+// ^^^^^^
+// pkg/front_end/testcases/regress/issue_34850.dart:12:1: Context: This isn't a type.
+// Future<List<int>> f2() async => null;
+// ^^^^^^
+//
 // pkg/front_end/testcases/regress/issue_34850.dart:14:1: Error: Expected 0 type arguments.
 // Future<List<>> f3() async {
 // ^
diff --git a/pkg/front_end/testcases/regress/issue_34850.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_34850.dart.strong.transformed.expect
index 22df880..b0cda7b 100644
--- a/pkg/front_end/testcases/regress/issue_34850.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_34850.dart.strong.transformed.expect
@@ -27,6 +27,10 @@
 // Future<List<>> f3() async {
 //             ^^
 //
+// pkg/front_end/testcases/regress/issue_34850.dart:5:2: Error: Type 'foo' not found.
+// <foo<
+//  ^^^
+//
 // pkg/front_end/testcases/regress/issue_34850.dart:5:2: Error: Expected 0 type arguments.
 // <foo<
 //  ^
@@ -35,6 +39,13 @@
 // foo
 // ^^^
 //
+// pkg/front_end/testcases/regress/issue_34850.dart:14:1: Error: 'Future' isn't a type.
+// Future<List<>> f3() async {
+// ^^^^^^
+// pkg/front_end/testcases/regress/issue_34850.dart:12:1: Context: This isn't a type.
+// Future<List<int>> f2() async => null;
+// ^^^^^^
+//
 // pkg/front_end/testcases/regress/issue_34850.dart:14:1: Error: Expected 0 type arguments.
 // Future<List<>> f3() async {
 // ^
diff --git a/pkg/front_end/testcases/text_serialization.status b/pkg/front_end/testcases/text_serialization.status
index 25584dc..0347606 100644
--- a/pkg/front_end/testcases/text_serialization.status
+++ b/pkg/front_end/testcases/text_serialization.status
@@ -660,6 +660,7 @@
 instantiate_to_bound/non_simple_variables_from_same: TextSerializationFailure # Was: Pass
 instantiate_to_bound/omitted_bound: TextSerializationFailure # Was: Pass
 instantiate_to_bound/raw_in_bound: TextSerializationFailure # Was: Pass
+instantiate_to_bound/super_bounded_in_bound: TextSerializationFailure
 instantiate_to_bound/super_bounded_type: TextSerializationFailure # Was: Pass
 instantiate_to_bound/supertypes: TextSerializationFailure # Was: Pass
 instantiate_to_bound/typedef_instantiated_in_outline: TextSerializationFailure # Was: Pass
@@ -922,8 +923,8 @@
 regress/issue_36400: TextSerializationFailure
 regress/issue_36647: TextSerializationFailure
 regress/issue_36647_2: TextSerializationFailure
-regress/issue_36793: TextSerializationFailure
 regress/issue_36669: TextSerializationFailure
+regress/issue_36793: 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/js_ast/lib/src/builder.dart b/pkg/js_ast/lib/src/builder.dart
index 635549b..bf9e94a 100644
--- a/pkg/js_ast/lib/src/builder.dart
+++ b/pkg/js_ast/lib/src/builder.dart
@@ -1029,15 +1029,15 @@
     AsyncModifier asyncModifier;
     if (acceptString('async')) {
       if (acceptString('*')) {
-        asyncModifier = const AsyncModifier.asyncStar();
+        asyncModifier = AsyncModifier.asyncStar;
       } else {
-        asyncModifier = const AsyncModifier.async();
+        asyncModifier = AsyncModifier.async;
       }
     } else if (acceptString('sync')) {
       if (!acceptString('*')) error("Only sync* is valid - sync is implied");
-      asyncModifier = const AsyncModifier.syncStar();
+      asyncModifier = AsyncModifier.syncStar;
     } else {
-      asyncModifier = const AsyncModifier.sync();
+      asyncModifier = AsyncModifier.sync;
     }
     expectCategory(LBRACE);
     Block block = parseBlock();
diff --git a/pkg/js_ast/lib/src/nodes.dart b/pkg/js_ast/lib/src/nodes.dart
index 0bec49b..d2970d4 100644
--- a/pkg/js_ast/lib/src/nodes.dart
+++ b/pkg/js_ast/lib/src/nodes.dart
@@ -981,7 +981,7 @@
 /// In particular, there is no guarantee that implementations of [compareTo]
 /// will implement some form of lexicographic ordering like [String.compareTo].
 abstract class Name extends Literal
-    implements Declaration, Parameter, Comparable {
+    implements Declaration, Parameter, Comparable<Name> {
   T accept<T>(NodeVisitor<T> visitor) => visitor.visitName(this);
 
   R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) =>
@@ -1448,7 +1448,7 @@
   final Block body;
   final AsyncModifier asyncModifier;
 
-  Fun(this.params, this.body, {this.asyncModifier: const AsyncModifier.sync()});
+  Fun(this.params, this.body, {this.asyncModifier: AsyncModifier.sync});
 
   T accept<T>(NodeVisitor<T> visitor) => visitor.visitFun(this);
 
@@ -1471,27 +1471,26 @@
 }
 
 class AsyncModifier {
+  final int index;
   final bool isAsync;
   final bool isYielding;
   final String description;
 
-  const AsyncModifier.sync()
-      : isAsync = false,
-        isYielding = false,
-        description = "sync";
-  const AsyncModifier.async()
-      : isAsync = true,
-        isYielding = false,
-        description = "async";
-  const AsyncModifier.asyncStar()
-      : isAsync = true,
-        isYielding = true,
-        description = "async*";
-  const AsyncModifier.syncStar()
-      : isAsync = false,
-        isYielding = true,
-        description = "sync*";
-  toString() => description;
+  const AsyncModifier(this.index, this.description,
+      {this.isAsync, this.isYielding});
+
+  static const AsyncModifier sync =
+      const AsyncModifier(0, "sync", isAsync: false, isYielding: false);
+  static const AsyncModifier async =
+      const AsyncModifier(1, "async", isAsync: true, isYielding: false);
+  static const AsyncModifier asyncStar =
+      const AsyncModifier(2, "async*", isAsync: true, isYielding: true);
+  static const AsyncModifier syncStar =
+      const AsyncModifier(3, "sync*", isAsync: false, isYielding: true);
+
+  static const List<AsyncModifier> values = [sync, async, asyncStar, syncStar];
+
+  String toString() => description;
 }
 
 class PropertyAccess extends Expression {
@@ -1750,10 +1749,11 @@
 }
 
 class Property extends Node {
-  final Literal name;
+  final Expression name;
   final Expression value;
 
-  Property(this.name, this.value);
+  Property(this.name, this.value)
+      : assert(name is Literal || name is DeferredExpression);
 
   T accept<T>(NodeVisitor<T> visitor) => visitor.visitProperty(this);
 
@@ -1987,3 +1987,9 @@
 
   void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) {}
 }
+
+/// Returns the value of [node] if it is a [DeferredExpression]. Otherwise
+/// returns the [node] itself.
+Node undefer(Node node) {
+  return node is DeferredExpression ? undefer(node.value) : node;
+}
diff --git a/pkg/js_ast/lib/src/printer.dart b/pkg/js_ast/lib/src/printer.dart
index 9ff26a6..399ab56 100644
--- a/pkg/js_ast/lib/src/printer.dart
+++ b/pkg/js_ast/lib/src/printer.dart
@@ -12,7 +12,7 @@
   final bool preferSemicolonToNewlineInMinifiedOutput;
   final Renamer renamerForNames;
 
-  JavaScriptPrintingOptions(
+  const JavaScriptPrintingOptions(
       {this.shouldCompressOutput: false,
       this.minifyLocalVariables: false,
       this.preferSemicolonToNewlineInMinifiedOutput: false,
@@ -223,6 +223,9 @@
 
   void startNode(Node node) {
     currentNode = new EnterExitNode(currentNode, node);
+    if (node is DeferredExpression) {
+      startNode(node.value);
+    }
   }
 
   void enterNode() {
@@ -230,6 +233,9 @@
   }
 
   void endNode(Node node) {
+    if (node is DeferredExpression) {
+      endNode(node.value);
+    }
     assert(currentNode.node == node);
     currentNode = currentNode.exitNode(context, _charCount);
   }
@@ -614,17 +620,17 @@
     }
     out(")");
     switch (fun.asyncModifier) {
-      case const AsyncModifier.sync():
+      case AsyncModifier.sync:
         break;
-      case const AsyncModifier.async():
+      case AsyncModifier.async:
         out(' ', isWhitespace: true);
         out('async');
         break;
-      case const AsyncModifier.syncStar():
+      case AsyncModifier.syncStar:
         out(' ', isWhitespace: true);
         out('sync*');
         break;
-      case const AsyncModifier.asyncStar():
+      case AsyncModifier.asyncStar:
         out(' ', isWhitespace: true);
         out('async*');
         break;
@@ -715,7 +721,7 @@
 
   static bool _isSmallInitialization(Node node) {
     if (node is VariableInitialization) {
-      Node value = node.value;
+      Node value = undefer(node.value);
       if (value == null) return true;
       if (value is This) return true;
       if (value is LiteralNull) return true;
@@ -723,17 +729,79 @@
       if (value is LiteralString && value.value.length <= 8) return true;
       if (value is ObjectInitializer && value.properties.isEmpty) return true;
       if (value is ArrayInitializer && value.elements.isEmpty) return true;
+      if (value is Name && value.name.length <= 8) return true;
     }
     return false;
   }
 
+  void _outputIncDec(String op, Expression variable, [Expression alias]) {
+    if (op == '+') {
+      if (lastCharCode == charCodes.$PLUS) out(" ", isWhitespace: true);
+      out('++');
+    } else {
+      if (lastCharCode == charCodes.$MINUS) out(" ", isWhitespace: true);
+      out('--');
+    }
+    if (alias != null) startNode(alias);
+    visitNestedExpression(variable, UNARY,
+        newInForInit: inForInit, newAtStatementBegin: false);
+    if (alias != null) endNode(alias);
+  }
+
   @override
   visitAssignment(Assignment assignment) {
+    /// To print assignments like `a = a + 1` and `a = a + b` compactly as
+    /// `++a` and `a += b` in the face of [DeferredExpression]s we detect the
+    /// pattern of the undeferred assignment.
+    String op = assignment.op;
+    Node leftHandSide = undefer(assignment.leftHandSide);
+    Node rightHandSide = undefer(assignment.value);
+    if ((op == '+' || op == '-') &&
+        leftHandSide is VariableUse &&
+        rightHandSide is LiteralNumber &&
+        rightHandSide.value == "1") {
+      // Output 'a += 1' as '++a' and 'a -= 1' as '--a'.
+      _outputIncDec(op, assignment.leftHandSide);
+      return;
+    } else if (leftHandSide is VariableUse && rightHandSide is Binary) {
+      Node rLeft = undefer(rightHandSide.left);
+      Node rRight = undefer(rightHandSide.right);
+      String op = rightHandSide.op;
+      if (op == '+' ||
+          op == '-' ||
+          op == '/' ||
+          op == '*' ||
+          op == '%' ||
+          op == '^' ||
+          op == '&' ||
+          op == '|') {
+        if (rLeft is VariableUse && rLeft.name == leftHandSide.name) {
+          // Output 'a = a + 1' as '++a' and 'a = a - 1' as '--a'.
+          if ((op == '+' || op == '-') &&
+              rRight is LiteralNumber &&
+              rRight.value == "1") {
+            _outputIncDec(op, assignment.leftHandSide, rightHandSide.left);
+            return;
+          }
+          // Output 'a = a + b' as 'a += b'.
+          startNode(rightHandSide.left);
+          visitNestedExpression(assignment.leftHandSide, CALL,
+              newInForInit: inForInit, newAtStatementBegin: atStatementBegin);
+          endNode(rightHandSide.left);
+          spaceOut();
+          out(op);
+          out("=");
+          spaceOut();
+          visitNestedExpression(rRight, ASSIGNMENT,
+              newInForInit: inForInit, newAtStatementBegin: false);
+          return;
+        }
+      }
+    }
     visitNestedExpression(assignment.leftHandSide, CALL,
         newInForInit: inForInit, newAtStatementBegin: atStatementBegin);
     if (assignment.value != null) {
       spaceOut();
-      String op = assignment.op;
       if (op != null) out(op);
       out("=");
       spaceOut();
@@ -972,34 +1040,33 @@
   void visitAccess(PropertyAccess access) {
     visitNestedExpression(access.receiver, CALL,
         newInForInit: inForInit, newAtStatementBegin: atStatementBegin);
-    Node selector = access.selector;
+    Node selector = undefer(access.selector);
     if (selector is LiteralString) {
-      LiteralString selectorString = selector;
-      String fieldWithQuotes = selectorString.value;
+      String fieldWithQuotes = selector.value;
       if (isValidJavaScriptId(fieldWithQuotes)) {
         if (access.receiver is LiteralNumber &&
             lastCharCode != charCodes.$CLOSE_PAREN) {
           out(" ", isWhitespace: true);
         }
         out(".");
-        startNode(selector);
+        startNode(access.selector);
         out(fieldWithQuotes.substring(1, fieldWithQuotes.length - 1));
-        endNode(selector);
+        endNode(access.selector);
         return;
       }
     } else if (selector is Name) {
-      if (access.receiver is LiteralNumber &&
-          lastCharCode != charCodes.$CLOSE_PAREN) {
+      Node receiver = undefer(access.receiver);
+      if (receiver is LiteralNumber && lastCharCode != charCodes.$CLOSE_PAREN) {
         out(" ", isWhitespace: true);
       }
       out(".");
-      startNode(selector);
+      startNode(access.selector);
       selector.accept(this);
-      endNode(selector);
+      endNode(access.selector);
       return;
     }
     out("[");
-    visitNestedExpression(selector, EXPRESSION,
+    visitNestedExpression(access.selector, EXPRESSION,
         newInForInit: false, newAtStatementBegin: false);
     out("]");
   }
@@ -1156,18 +1223,18 @@
   @override
   void visitProperty(Property node) {
     startNode(node.name);
-    if (node.name is LiteralString) {
-      LiteralString nameString = node.name;
-      String name = nameString.value;
-      if (isValidJavaScriptId(name)) {
-        out(name.substring(1, name.length - 1));
+    Node name = undefer(node.name);
+    if (name is LiteralString) {
+      String text = name.value;
+      if (isValidJavaScriptId(text)) {
+        out(text.substring(1, text.length - 1));
       } else {
-        out(name);
+        out(text);
       }
-    } else if (node.name is Name) {
+    } else if (name is Name) {
       node.name.accept(this);
     } else {
-      assert(node.name is LiteralNumber);
+      assert(name is LiteralNumber);
       LiteralNumber nameNumber = node.name;
       out(nameNumber.value);
     }
diff --git a/pkg/js_ast/lib/src/template.dart b/pkg/js_ast/lib/src/template.dart
index 0503e9f..a7dcf48 100644
--- a/pkg/js_ast/lib/src/template.dart
+++ b/pkg/js_ast/lib/src/template.dart
@@ -236,7 +236,7 @@
     var nameOrPosition = node.nameOrPosition;
     return (arguments) {
       var value = arguments[nameOrPosition];
-      if (value is Literal) return value;
+      if (value is Literal || value is DeferredExpression) return value;
       error('Interpolated value #$nameOrPosition is not a Literal: $value');
     };
   }
diff --git a/pkg/js_ast/test/deferred_expression_test.dart b/pkg/js_ast/test/deferred_expression_test.dart
new file mode 100644
index 0000000..397aaaa
--- /dev/null
+++ b/pkg/js_ast/test/deferred_expression_test.dart
@@ -0,0 +1,160 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:expect/expect.dart';
+import 'package:js_ast/js_ast.dart';
+
+main() {
+  Map<Expression, DeferredExpression> map = {};
+  VariableUse variableUse = new VariableUse('variable');
+  DeferredExpression deferred =
+      map[variableUse] = new _DeferredExpression(variableUse);
+  VariableUse variableUseAlias = new VariableUse('variable');
+  map[variableUseAlias] = new _DeferredExpression(variableUseAlias);
+
+  map[deferred] = new _DeferredExpression(deferred);
+  Literal literal = new LiteralString('"literal"');
+  map[literal] = new _DeferredExpression(literal);
+
+  test(map, '#', [variableUse], 'variable');
+  test(map, '#', [deferred], 'variable');
+  test(map, '{#: #}', [literal, variableUse], '{literal: variable}');
+  test(map, '{#: #}', [literal, deferred], '{literal: variable}');
+  test(map, '#.#', [variableUse, literal], 'variable.literal');
+  test(map, '#.#', [deferred, literal], 'variable.literal');
+  test(map, '# = # + 1', [variableUse, variableUseAlias], '++variable');
+  test(map, '# = # + 1', [deferred, variableUseAlias], '++variable');
+  test(map, '# = # - 1', [variableUse, variableUseAlias], '--variable');
+  test(map, '# = # - 1', [deferred, variableUseAlias], '--variable');
+  test(map, '# = # + 2', [variableUse, variableUseAlias], 'variable += 2');
+  test(map, '# = # + 2', [deferred, variableUseAlias], 'variable += 2');
+}
+
+void test(Map<Expression, DeferredExpression> map, String template,
+    List<Expression> arguments, String expectedOutput) {
+  Expression directExpression =
+      js.expressionTemplateFor(template).instantiate(arguments);
+  _Context directContext = new _Context();
+  Printer directPrinter =
+      new Printer(const JavaScriptPrintingOptions(), directContext);
+  directPrinter.visit(directExpression);
+  Expect.equals(expectedOutput, directContext.text);
+
+  Expression deferredExpression = js
+      .expressionTemplateFor(template)
+      .instantiate(arguments.map((e) => map[e]).toList());
+  _Context deferredContext = new _Context();
+  Printer deferredPrinter =
+      new Printer(const JavaScriptPrintingOptions(), deferredContext);
+  deferredPrinter.visit(deferredExpression);
+  Expect.equals(expectedOutput, deferredContext.text);
+
+  for (Expression argument in arguments) {
+    DeferredExpression deferred = map[argument];
+    Expect.isTrue(
+        directContext.enterPositions.containsKey(argument),
+        "Argument ${DebugPrint(argument)} not found in direct enter positions: "
+        "${directContext.enterPositions.keys}");
+    Expect.isTrue(
+        deferredContext.enterPositions.containsKey(argument),
+        "Argument ${DebugPrint(argument)} not found in "
+        "deferred enter positions: "
+        "${deferredContext.enterPositions.keys}");
+    Expect.isTrue(
+        deferredContext.enterPositions.containsKey(deferred),
+        "Argument ${DebugPrint(deferred)} not found in "
+        "deferred enter positions: "
+        "${deferredContext.enterPositions.keys}");
+    Expect.equals(directContext.enterPositions[argument],
+        deferredContext.enterPositions[argument]);
+    Expect.equals(directContext.enterPositions[argument],
+        deferredContext.enterPositions[deferred]);
+
+    Expect.isTrue(
+        directContext.exitPositions.containsKey(argument),
+        "Argument ${DebugPrint(argument)} not found in direct enter positions: "
+        "${directContext.exitPositions.keys}");
+    Expect.isTrue(
+        deferredContext.exitPositions.containsKey(argument),
+        "Argument ${DebugPrint(argument)} not found in "
+        "deferred enter positions: "
+        "${deferredContext.exitPositions.keys}");
+    Expect.isTrue(
+        deferredContext.exitPositions.containsKey(deferred),
+        "Argument ${DebugPrint(deferred)} not found in "
+        "deferred enter positions: "
+        "${deferredContext.exitPositions.keys}");
+    Expect.equals(directContext.exitPositions[argument],
+        deferredContext.exitPositions[argument]);
+    Expect.equals(directContext.exitPositions[argument],
+        deferredContext.exitPositions[deferred]);
+  }
+}
+
+class _DeferredExpression extends DeferredExpression {
+  final Expression value;
+
+  _DeferredExpression(this.value);
+
+  @override
+  int get precedenceLevel => value.precedenceLevel;
+}
+
+class _Context implements JavaScriptPrintingContext {
+  StringBuffer sb = new StringBuffer();
+  List<String> errors = [];
+  Map<Node, int> enterPositions = {};
+  Map<Node, _Position> exitPositions = {};
+
+  @override
+  void emit(String string) {
+    sb.write(string);
+  }
+
+  @override
+  void enterNode(Node node, int startPosition) {
+    enterPositions[node] = startPosition;
+  }
+
+  @override
+  void exitNode(
+      Node node, int startPosition, int endPosition, int closingPosition) {
+    exitPositions[node] =
+        new _Position(startPosition, endPosition, closingPosition);
+    Expect.equals(enterPositions[node], startPosition);
+  }
+
+  @override
+  void error(String message) {
+    errors.add(message);
+  }
+
+  String get text => sb.toString();
+}
+
+class _Position {
+  final int startPosition;
+  final int endPosition;
+  final int closingPosition;
+
+  _Position(this.startPosition, this.endPosition, this.closingPosition);
+
+  int get hashCode =>
+      13 * startPosition.hashCode +
+      17 * endPosition.hashCode +
+      19 * closingPosition.hashCode;
+
+  bool operator ==(Object other) {
+    if (identical(this, other)) return true;
+    return other is _Position &&
+        startPosition == other.startPosition &&
+        endPosition == other.endPosition &&
+        closingPosition == other.closingPosition;
+  }
+
+  String toString() {
+    return '_Position(start=$startPosition,'
+        'end=$endPosition,closing=$closingPosition)';
+  }
+}
diff --git a/pkg/kernel/lib/ast.dart b/pkg/kernel/lib/ast.dart
index 5d366a5..30a5f5c 100644
--- a/pkg/kernel/lib/ast.dart
+++ b/pkg/kernel/lib/ast.dart
@@ -3215,9 +3215,9 @@
 ///
 /// If [lists] is empty then an empty list is returned.
 ///
-/// These arise from spread and control-flow elements in const list literals
-/// containing unevaluated subexpressions. They only ever occur within
-/// unevaluated constants in constant expressions.
+/// These arise from spread and control-flow elements in const list literals.
+/// They are only present before constant evaluation, or within unevaluated
+/// constants in constant expressions.
 class ListConcatenation extends Expression {
   DartType typeArgument;
   final List<Expression> lists;
@@ -3248,9 +3248,9 @@
 ///
 /// If [sets] is empty then an empty set is returned.
 ///
-/// These arise from spread and control-flow elements in const set literals
-/// containing unevaluated subexpressions. They only ever occur within
-/// unevaluated constants in constant expressions.
+/// These arise from spread and control-flow elements in const set literals.
+/// They are only present before constant evaluation, or within unevaluated
+/// constants in constant expressions.
 ///
 /// Duplicated values in or across the sets will result in a compile-time error
 /// during constant evaluation.
@@ -3284,9 +3284,9 @@
 ///
 /// If [maps] is empty then an empty map is returned.
 ///
-/// These arise from spread and control-flow elements in const map literals
-/// containing unevaluated subexpressions. They only ever occur within
-/// unevaluated constants in constant expressions.
+/// These arise from spread and control-flow elements in const map literals.
+/// They are only present before constant evaluation, or within unevaluated
+/// constants in constant expressions.
 ///
 /// Duplicated keys in or across the maps will result in a compile-time error
 /// during constant evaluation.
diff --git a/pkg/kernel/lib/binary/ast_to_binary.dart b/pkg/kernel/lib/binary/ast_to_binary.dart
index 4b3434c..0292314 100644
--- a/pkg/kernel/lib/binary/ast_to_binary.dart
+++ b/pkg/kernel/lib/binary/ast_to_binary.dart
@@ -37,6 +37,7 @@
   BufferedSink _constantsSink;
   BufferedSink _sink;
   bool includeSources;
+  bool includeOffsets;
 
   List<int> libraryOffsets;
   List<int> classOffsets;
@@ -57,7 +58,9 @@
   /// The BinaryPrinter will use its own buffer, so the [sink] does not need
   /// one.
   BinaryPrinter(Sink<List<int>> sink,
-      {StringIndexer stringIndexer, this.includeSources = true})
+      {StringIndexer stringIndexer,
+      this.includeSources = true,
+      this.includeOffsets = true})
       : _mainSink = new BufferedSink(sink),
         _metadataSink = new BufferedSink(new BytesSink()),
         _constantsBytesSink = new BytesSink(),
@@ -875,7 +878,11 @@
     // TODO(jensj): Delta-encoding.
     // File offset ranges from -1 and up,
     // but is here saved as unsigned (thus the +1)
-    writeUInt30(offset + 1);
+    if (!includeOffsets) {
+      writeUInt30(0);
+    } else {
+      writeUInt30(offset + 1);
+    }
   }
 
   void writeClassReference(Class class_) {
diff --git a/pkg/kernel/lib/binary/limited_ast_to_binary.dart b/pkg/kernel/lib/binary/limited_ast_to_binary.dart
index 0cef7c7..104cfe6 100644
--- a/pkg/kernel/lib/binary/limited_ast_to_binary.dart
+++ b/pkg/kernel/lib/binary/limited_ast_to_binary.dart
@@ -23,8 +23,11 @@
   final bool excludeUriToSource;
 
   LimitedBinaryPrinter(
-      Sink<List<int>> sink, this.predicate, this.excludeUriToSource)
-      : super(sink, includeSources: !excludeUriToSource);
+      Sink<List<int>> sink, this.predicate, this.excludeUriToSource,
+      {bool includeOffsets = true})
+      : super(sink,
+            includeSources: !excludeUriToSource,
+            includeOffsets: includeOffsets);
 
   @override
   void computeCanonicalNames(Component component) {
diff --git a/pkg/kernel/lib/class_hierarchy.dart b/pkg/kernel/lib/class_hierarchy.dart
index 51f0730..474f907 100644
--- a/pkg/kernel/lib/class_hierarchy.dart
+++ b/pkg/kernel/lib/class_hierarchy.dart
@@ -810,9 +810,23 @@
       _buildInterfaceMembers(class_, info, setters: false);
     }
 
+    assert(sanityCheckAlsoKnowsParentAndLibrary());
+
     return this;
   }
 
+  bool sanityCheckAlsoKnowsParentAndLibrary() {
+    for (Class c in _infoFor.keys) {
+      if (!knownLibraries.contains(c.enclosingLibrary)) {
+        throw new StateError("Didn't know library of $c (from ${c.fileUri})");
+      }
+      if (c.supertype != null && _infoFor[c.supertype.classNode] == null) {
+        throw new StateError("Didn't know parent of $c (from ${c.fileUri})");
+      }
+    }
+    return true;
+  }
+
   @override
   Supertype asInstantiationOf(Supertype type, Class superclass) {
     // This is similar to getTypeAsInstanceOf, except that it assumes that
diff --git a/pkg/kernel/lib/target/targets.dart b/pkg/kernel/lib/target/targets.dart
index 47521ca..274942a 100644
--- a/pkg/kernel/lib/target/targets.dart
+++ b/pkg/kernel/lib/target/targets.dart
@@ -11,8 +11,9 @@
 
 class TargetFlags {
   final bool legacyMode;
+  final bool trackWidgetCreation;
 
-  TargetFlags({this.legacyMode: false});
+  TargetFlags({this.legacyMode = false, this.trackWidgetCreation = false});
 }
 
 typedef Target _TargetBuilder(TargetFlags flags);
@@ -115,6 +116,15 @@
   /// slowing down compilation.
   void performOutlineTransformations(Component component) {}
 
+  /// Perform target-specific transformations on the given libraries that must
+  /// run before constant evaluation.
+  void performPreConstantEvaluationTransformations(
+      Component component,
+      CoreTypes coreTypes,
+      List<Library> libraries,
+      DiagnosticReporter diagnosticReporter,
+      {void logger(String msg)}) {}
+
   /// Perform target-specific modular transformations on the given libraries.
   void performModularTransformationsOnLibraries(
       Component component,
diff --git a/pkg/dev_compiler/lib/src/flutter/track_widget_constructor_locations.dart b/pkg/kernel/lib/transformations/track_widget_constructor_locations.dart
similarity index 83%
rename from pkg/dev_compiler/lib/src/flutter/track_widget_constructor_locations.dart
rename to pkg/kernel/lib/transformations/track_widget_constructor_locations.dart
index a667613..d227409 100644
--- a/pkg/dev_compiler/lib/src/flutter/track_widget_constructor_locations.dart
+++ b/pkg/kernel/lib/transformations/track_widget_constructor_locations.dart
@@ -1,27 +1,13 @@
-// Copyright 2013 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
+// 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.
 
-// TODO(jmesserly): this file was copied from:
-// https://github.com/flutter/engine/blob/4b01d795feec3ba8231a397a4ec2759954d8216e/flutter_kernel_transformers/lib/track_widget_constructor_locations.dart
-//
-// Longer term, this transform should be injected by Flutter when they building
-// the Flutter-specific `dartdevc` script.
-//
-// The following modifications were made:
-// - remove "package:vm" dependency (only used for one interface)
-// - optionally pass in the class hierarchy that DDC already has available.
-library track_widget_constructor_locations;
+library kernel.transformations.track_widget_constructor_locations;
 
-// The kernel/src import below that requires lint `ignore_for_file`
-// is a temporary state of things until kernel team builds better api that would
-// replace api used below. This api was made private in an effort to discourage
-// further use.
-// ignore_for_file: implementation_imports
-import 'package:kernel/ast.dart';
-import 'package:kernel/class_hierarchy.dart';
 import 'package:meta/meta.dart';
 
+import '../ast.dart';
+
 // Parameter name used to track were widget constructor calls were made from.
 //
 // The parameter name contains a randomly generate hex string to avoid collision
@@ -126,8 +112,6 @@
 /// transformed to have a named parameter with the name specified by
 /// `_locationParameterName`.
 class _WidgetCallSiteTransformer extends Transformer {
-  final ClassHierarchy _hierarchy;
-
   /// The [Widget] class defined in the `package:flutter` library.
   ///
   /// Used to perform instanceof checks to determine whether Dart constructor
@@ -143,12 +127,15 @@
   /// actual constructor call within the factory.
   Procedure _currentFactory;
 
+  WidgetCreatorTracker _tracker;
+
   _WidgetCallSiteTransformer(
-    this._hierarchy, {
-    @required Class widgetClass,
-    @required Class locationClass,
-  })  : _widgetClass = widgetClass,
-        _locationClass = locationClass;
+      {@required Class widgetClass,
+      @required Class locationClass,
+      @required WidgetCreatorTracker tracker})
+      : _widgetClass = widgetClass,
+        _locationClass = locationClass,
+        _tracker = tracker;
 
   /// Builds a call to the const constructor of the [DebugLocation]
   /// object specifying the location where a constructor call was made and
@@ -200,9 +187,7 @@
   }
 
   bool _isSubclassOfWidget(Class clazz) {
-    // TODO(jacobr): use hierarchy.isSubclassOf once we are using the
-    // non-deprecated ClassHierarchy constructor.
-    return _hierarchy.isSubclassOf(clazz, _widgetClass);
+    return _tracker._isSubclassOf(clazz, _widgetClass);
   }
 
   @override
@@ -249,10 +234,8 @@
       Class constructedClass) {
     // For factory constructors we need to use the location specified as an
     // argument to the factory constructor rather than the location
-    // TODO(jacobr): use hierarchy.isSubclassOf once we are using the
-    // non-deprecated ClassHierarchy constructor.
     if (_currentFactory != null &&
-        _hierarchy.isSubclassOf(
+        _tracker._isSubclassOf(
             constructedClass, _currentFactory.enclosingClass)) {
       final VariableDeclaration creationLocationParameter = _getNamedParameter(
         _currentFactory.function,
@@ -309,14 +292,7 @@
   /// available.
   Class _hasCreationLocationClass;
 
-  /// The [ClassHierarchy] that should be used after applying this transformer.
-  /// If any class was updated, in general we need to create a new
-  /// [ClassHierarchy] instance, with new dispatch targets; or at least let
-  /// the existing instance know that some of its dispatch tables are not
-  /// valid anymore.
-  ClassHierarchy hierarchy;
-
-  WidgetCreatorTracker([this.hierarchy]);
+  WidgetCreatorTracker();
 
   void _resolveFlutterClasses(Iterable<Library> libraries) {
     // If the Widget or Debug location classes have been updated we need to get
@@ -438,51 +414,24 @@
     clazz.constructors.forEach(handleConstructor);
   }
 
-  Component _computeFullProgram(Component deltaProgram) {
-    final Set<Library> libraries = new Set<Library>();
-    final List<Library> workList = <Library>[];
-    for (Library library in deltaProgram.libraries) {
-      workList.add(library);
-    }
-    while (workList.isNotEmpty) {
-      final Library library = workList.removeLast();
-      for (LibraryDependency dependency in library.dependencies) {
-        if (libraries.add(dependency.targetLibrary)) {
-          workList.add(dependency.targetLibrary);
-        }
-      }
-    }
-    return new Component()..libraries.addAll(libraries);
-  }
-
-  /// Transform the given [module].
-  void transform(Component module) {
-    final List<Library> libraries = module.libraries;
-
+  /// Transform the given [libraries].
+  void transform(Component module, List<Library> libraries) {
     if (libraries.isEmpty) {
       return;
     }
 
-    _resolveFlutterClasses(libraries);
+    _resolveFlutterClasses(module.libraries);
 
     if (_widgetClass == null) {
       // This application doesn't actually use the package:flutter library.
       return;
     }
 
-    // TODO(jacobr): once there is a working incremental ClassHierarchy
-    // constructor switch to using it instead of building a ClassHierarchy off
-    // the full program.
-    hierarchy ??= new ClassHierarchy(
-      _computeFullProgram(module),
-      onAmbiguousSupertypes: (Class cls, Supertype a, Supertype b) {},
-    );
-
     final Set<Class> transformedClasses = new Set<Class>.identity();
     final Set<Library> librariesToTransform = new Set<Library>.identity()
-      ..addAll(module.libraries);
+      ..addAll(libraries);
 
-    for (Library library in module.libraries) {
+    for (Library library in libraries) {
       if (library.isExternal) {
         continue;
       }
@@ -498,12 +447,11 @@
     // Transform call sites to pass the location parameter.
     final _WidgetCallSiteTransformer callsiteTransformer =
         new _WidgetCallSiteTransformer(
-      hierarchy,
-      widgetClass: _widgetClass,
-      locationClass: _locationClass,
-    );
+            widgetClass: _widgetClass,
+            locationClass: _locationClass,
+            tracker: this);
 
-    for (Library library in module.libraries) {
+    for (Library library in libraries) {
       if (library.isExternal) {
         continue;
       }
@@ -511,13 +459,17 @@
     }
   }
 
-  bool _isSubclassOfWidget(Class clazz) {
-    if (clazz == null) {
-      return false;
+  bool _isSubclassOfWidget(Class clazz) => _isSubclassOf(clazz, _widgetClass);
+
+  bool _isSubclassOf(Class a, Class b) {
+    // TODO(askesc): Cache results.
+    // TODO(askesc): Test for subtype rather than subclass.
+    Class current = a;
+    while (current != null) {
+      if (current == b) return true;
+      current = current.superclass;
     }
-    // TODO(jacobr): use hierarchy.isSubclassOf once we are using the
-    // non-deprecated ClassHierarchy constructor.
-    return hierarchy.isSubclassOf(clazz, _widgetClass);
+    return false;
   }
 
   void _transformWidgetConstructors(Set<Library> librariesToBeTransformed,
diff --git a/pkg/modular_test/lib/src/dependency_parser.dart b/pkg/modular_test/lib/src/dependency_parser.dart
new file mode 100644
index 0000000..51f2460
--- /dev/null
+++ b/pkg/modular_test/lib/src/dependency_parser.dart
@@ -0,0 +1,74 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// This library defines how to read module dependencies from a Yaml
+/// specification. We expect to find specifications written in this format:
+///
+///    dependencies:
+///      b: a
+///      main: [b, expect]
+///
+/// Where:
+///   - Each name corresponds to a module.
+///   - Module names correlate to either a file, a folder, or a package.
+///   - A map entry contains all the dependencies of a module, if any.
+///   - If a module has a single dependency, it can be written as a single
+///     value.
+///
+/// The logic in this library mostly treats these names as strings, separately
+/// `loader.dart` is responsible for validating and attaching this dependency
+/// information to a set of module definitions.
+import 'package:yaml/yaml.dart';
+
+/// Parses [contents] containing a module dependencies specification written in
+/// yaml, and returns a normalized dependency map.
+///
+/// Note: some values in the map may not have a corresponding key. That may be
+/// the case for modules that have no dependencies and modules that are not
+/// specified in [contents] (e.g. modules that are supported by default).
+Map<String, List<String>> parseDependencyMap(String contents) {
+  var spec = loadYaml(contents);
+  if (spec is! YamlMap) {
+    return _invalidSpecification("spec is not a map");
+  }
+  var dependencies = spec['dependencies'];
+  if (dependencies == null) {
+    return _invalidSpecification("no dependencies section");
+  }
+  if (dependencies is! YamlMap) {
+    return _invalidSpecification("dependencies is not a map");
+  }
+
+  Map<String, List<String>> normalizedMap = {};
+  dependencies.forEach((key, value) {
+    if (key is! String) {
+      _invalidSpecification("key: '$key' is not a string");
+    }
+    normalizedMap[key] = [];
+    if (value is String) {
+      normalizedMap[key].add(value);
+    } else if (value is List) {
+      value.forEach((entry) {
+        if (entry is! String) {
+          _invalidSpecification("entry: '$entry' is not a string");
+        }
+        normalizedMap[key].add(entry);
+      });
+    } else {
+      _invalidSpecification(
+          "entry: '$value' is not a string or a list of strings");
+    }
+  });
+  return normalizedMap;
+}
+
+_invalidSpecification(String message) {
+  throw new InvalidSpecificationError(message);
+}
+
+class InvalidSpecificationError extends Error {
+  final String message;
+  InvalidSpecificationError(this.message);
+  String toString() => "Invalid specification: $message";
+}
diff --git a/pkg/modular_test/lib/src/find_sdk_root.dart b/pkg/modular_test/lib/src/find_sdk_root.dart
new file mode 100644
index 0000000..2b36550
--- /dev/null
+++ b/pkg/modular_test/lib/src/find_sdk_root.dart
@@ -0,0 +1,28 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+/// Helper method to locate the root of the SDK repository.
+///
+/// The `modular_test` package is only intended to be used within the SDK at
+/// this time. We need the ability to find the sdk root in order to locate the
+/// default set of packages that are available to all modular tests.
+Future<Uri> findRoot() async {
+  Uri current = Platform.script;
+  while (true) {
+    var segments = current.pathSegments;
+    var index = segments.lastIndexOf('sdk');
+    if (index == -1) {
+      print("error: cannot find the root of the Dart SDK");
+      exitCode = 1;
+      return null;
+    }
+    current = current.resolve("../" * (segments.length - index - 1));
+    if (await File.fromUri(current.resolve("sdk/DEPS")).exists()) {
+      break;
+    }
+  }
+  return current.resolve("sdk/");
+}
diff --git a/pkg/modular_test/lib/src/io_pipeline.dart b/pkg/modular_test/lib/src/io_pipeline.dart
index acc6144..ed77f2d 100644
--- a/pkg/modular_test/lib/src/io_pipeline.dart
+++ b/pkg/modular_test/lib/src/io_pipeline.dart
@@ -34,7 +34,7 @@
   Map<DataId, Uri> get tmpFoldersForTesting => _tmpFolders;
   bool saveFoldersForTesting;
 
-  IOPipeline(List<ModularStep> steps, {this.saveFoldersForTesting: false})
+  IOPipeline(List<IOModularStep> steps, {this.saveFoldersForTesting: false})
       : super(steps);
 
   @override
@@ -53,39 +53,47 @@
   @override
   Future<void> runStep(IOModularStep step, Module module,
       Map<Module, Set<DataId>> visibleData) async {
-    var folder =
-        await Directory.systemTemp.createTemp('modular_test_${step.resultId}-');
-    _tmpFolders[step.resultId] ??= (await Directory.systemTemp
-            .createTemp('modular_test_${step.resultId}_res-'))
-        .uri;
+    // Since data ids are unique throughout the pipeline, we use the first
+    // result data id as a hint for the name of the temporary folder of a step.
+    var stepFolder;
+    for (var dataId in step.resultData) {
+      stepFolder ??=
+          await Directory.systemTemp.createTemp('modular_test_${dataId}-');
+      _tmpFolders[dataId] ??=
+          (await Directory.systemTemp.createTemp('modular_test_${dataId}_res-'))
+              .uri;
+    }
     for (var module in visibleData.keys) {
       for (var dataId in visibleData[module]) {
         var filename = "${module.name}.${dataId.name}";
         var assetUri = _tmpFolders[dataId].resolve(filename);
         await File.fromUri(assetUri)
-            .copy(folder.uri.resolve(filename).toFilePath());
+            .copy(stepFolder.uri.resolve(filename).toFilePath());
       }
     }
     if (step.needsSources) {
       for (var uri in module.sources) {
         var originalUri = module.rootUri.resolveUri(uri);
-        await File.fromUri(originalUri)
-            .copy(folder.uri.resolveUri(uri).toFilePath());
+        var copyUri = stepFolder.uri.resolveUri(uri);
+        await File.fromUri(copyUri).create(recursive: true);
+        await File.fromUri(originalUri).copy(copyUri.toFilePath());
       }
     }
 
-    await step.execute(module, folder.uri,
+    await step.execute(module, stepFolder.uri,
         (Module m, DataId id) => Uri.parse("${m.name}.${id.name}"));
 
-    var outputFile = File.fromUri(
-        folder.uri.resolve("${module.name}.${step.resultId.name}"));
-    if (!await outputFile.exists()) {
-      throw StateError(
-          "Step '${step.runtimeType}' didn't produce an output file");
+    for (var dataId in step.resultData) {
+      var outputFile =
+          File.fromUri(stepFolder.uri.resolve("${module.name}.${dataId.name}"));
+      if (!await outputFile.exists()) {
+        throw StateError(
+            "Step '${step.runtimeType}' didn't produce an output file");
+      }
+      await outputFile.copy(_tmpFolders[dataId]
+          .resolve("${module.name}.${dataId.name}")
+          .toFilePath());
     }
-    await outputFile.copy(_tmpFolders[step.resultId]
-        .resolve("${module.name}.${step.resultId.name}")
-        .toFilePath());
-    await folder.delete(recursive: true);
+    await stepFolder.delete(recursive: true);
   }
 }
diff --git a/pkg/modular_test/lib/src/loader.dart b/pkg/modular_test/lib/src/loader.dart
new file mode 100644
index 0000000..ce00e49
--- /dev/null
+++ b/pkg/modular_test/lib/src/loader.dart
@@ -0,0 +1,246 @@
+// 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.
+
+/// This library defines how `modular_test` converts the contents of a folder
+/// into a modular test. At this time, the logic in this library assumes this is
+/// only used within the Dart SDK repo.
+///
+/// A modular test folder contains:
+///   * individual .dart files, each file is considered a module. A
+///   `main.dart` file is required as the entry point of the test.
+///   * subfolders: each considered a module with multiple files
+///   * (optional) a .packages file:
+///       * if this is not specified, the test will use [defaultPackagesInput]
+///       instead.
+///       * if specified, it will be extended with the definitions in
+///       [defaultPackagesInput]. The list of packages provided is expected to
+///       be disjoint with those in [defaultPackagesInput].
+///   * a modules.yaml file: a specification of dependencies between modules.
+///     The format is described in `dependencies_parser.dart`.
+import 'dart:io';
+import 'dart:convert';
+import 'suite.dart';
+import 'dependency_parser.dart';
+import 'find_sdk_root.dart';
+
+import 'package:package_config/packages_file.dart' as package_config;
+
+/// Returns the [ModularTest] associated with a folder under [uri].
+///
+/// After scanning the contents of the folder, this method creates a
+/// [ModularTest] that contains only modules that are reachable from the main
+/// module.  This method runs several validations including that modules don't
+/// have conflicting names, that the default packages are always visible, and
+/// that modules do not contain cycles.
+Future<ModularTest> loadTest(Uri uri) async {
+  var folder = Directory.fromUri(uri);
+  var testUri = folder.uri; // normalized in case the trailing '/' was missing.
+  Uri root = await findRoot();
+  Map<String, Uri> defaultPackages =
+      package_config.parse(_defaultPackagesInput, root);
+  Map<String, Module> modules = {};
+  String spec;
+  Module mainModule;
+  Map<String, Uri> packages = {};
+  await for (var entry in folder.list(recursive: false)) {
+    var entryUri = entry.uri;
+    if (entry is File) {
+      var fileName = entryUri.path.substring(testUri.path.length);
+      if (fileName.endsWith('.dart')) {
+        var moduleName = fileName.substring(0, fileName.indexOf('.dart'));
+        if (defaultPackages.containsKey(moduleName)) {
+          return _invalidTest("The file '$fileName' defines a module called "
+              "'$moduleName' which conflicts with a package by the same name "
+              "that is provided by default.");
+        }
+        if (modules.containsKey(moduleName)) {
+          return _moduleConflict(fileName, modules[moduleName], testUri);
+        }
+        var relativeUri = Uri.parse(fileName);
+        var isMain = moduleName == 'main';
+        var module = Module(moduleName, [], testUri, [relativeUri],
+            mainSource: isMain ? relativeUri : null,
+            isMain: isMain,
+            packageBase: Uri.parse('.'));
+        if (isMain) mainModule = module;
+        modules[moduleName] = module;
+      } else if (fileName == '.packages') {
+        List<int> packagesBytes = await entry.readAsBytes();
+        packages = package_config.parse(packagesBytes, entryUri);
+      } else if (fileName == 'modules.yaml') {
+        spec = await entry.readAsString();
+      }
+    } else {
+      assert(entry is Directory);
+      var path = entryUri.path;
+      var moduleName = path.substring(testUri.path.length, path.length - 1);
+      if (defaultPackages.containsKey(moduleName)) {
+        return _invalidTest("The folder '$moduleName' defines a module "
+            "which conflicts with a package by the same name "
+            "that is provided by default.");
+      }
+      if (modules.containsKey(moduleName)) {
+        return _moduleConflict(moduleName, modules[moduleName], testUri);
+      }
+      var sources = await _listModuleSources(entryUri);
+      modules[moduleName] = Module(moduleName, [], testUri, sources,
+          packageBase: Uri.parse('$moduleName/'));
+    }
+  }
+  if (spec == null) {
+    return _invalidTest("modules.yaml file is missing");
+  }
+  if (mainModule == null) {
+    return _invalidTest("main module is missing");
+  }
+
+  _addDefaultPackageEntries(packages, defaultPackages);
+  await _addModulePerPackage(packages, modules);
+  _attachDependencies(parseDependencyMap(spec), modules);
+  _attachDependencies(parseDependencyMap(_defaultPackagesSpec), modules);
+  _detectCyclesAndRemoveUnreachable(modules, mainModule);
+  var sortedModules = modules.values.toList()
+    ..sort((a, b) => a.name.compareTo(b.name));
+  return new ModularTest(sortedModules, mainModule);
+}
+
+/// Returns all source files recursively found in a folder as relative URIs.
+Future<List<Uri>> _listModuleSources(Uri root) async {
+  List<Uri> sources = [];
+  Directory folder = Directory.fromUri(root);
+  int baseUriPrefixLength = folder.parent.uri.path.length;
+  await for (var file in folder.list(recursive: true)) {
+    var path = file.uri.path;
+    if (path.endsWith('.dart')) {
+      sources.add(Uri.parse(path.substring(baseUriPrefixLength)));
+    }
+  }
+  return sources..sort((a, b) => a.path.compareTo(b.path));
+}
+
+/// Add links between modules based on the provided dependency map.
+void _attachDependencies(
+    Map<String, List<String>> dependencies, Map<String, Module> modules) {
+  dependencies.forEach((name, moduleDependencies) {
+    var module = modules[name];
+    if (module == null) {
+      _invalidTest(
+          "declared dependencies for a non existing module named '$name'");
+    }
+    if (module.dependencies.isNotEmpty) {
+      _invalidTest("Module dependencies have already been declared on $name.");
+    }
+    moduleDependencies.forEach((dependencyName) {
+      var moduleDependency = modules[dependencyName];
+      if (moduleDependency == null) {
+        _invalidTest("'$name' declares a dependency on a non existing module "
+            "named '$dependencyName'");
+      }
+      module.dependencies.add(moduleDependency);
+    });
+  });
+}
+
+void _addDefaultPackageEntries(
+    Map<String, Uri> packages, Map<String, Uri> defaultPackages) {
+  for (var name in defaultPackages.keys) {
+    var existing = packages[name];
+    if (existing != null && existing != defaultPackages[name]) {
+      _invalidTest(
+          ".packages file defines an conflicting entry for package '$name'.");
+    }
+    packages[name] = defaultPackages[name];
+  }
+}
+
+/// Create a module for each package dependency.
+Future<void> _addModulePerPackage(
+    Map<String, Uri> packages, Map<String, Module> modules) async {
+  for (var packageName in packages.keys) {
+    var module = modules[packageName];
+    if (module != null) {
+      module.isPackage = true;
+    } else {
+      var packageLibUri = packages[packageName];
+      var rootUri = Directory.fromUri(packageLibUri).parent.uri;
+      var sources = await _listModuleSources(packageLibUri);
+      // TODO(sigmund): validate that we don't use a different alias for a
+      // module that is part of the test (package name and module name should
+      // match).
+      modules[packageName] = Module(packageName, [], rootUri, sources,
+          isPackage: true, packageBase: Uri.parse('lib/'));
+    }
+  }
+}
+
+/// Trim the set of modules, and detect cycles while we are at it.
+_detectCyclesAndRemoveUnreachable(Map<String, Module> modules, Module main) {
+  Set<Module> visiting = {};
+  Set<Module> visited = {};
+
+  helper(Module current) {
+    if (!visiting.add(current)) {
+      _invalidTest("module '${current.name}' has a dependency cycle.");
+    }
+    if (visited.add(current)) {
+      current.dependencies.forEach(helper);
+    }
+    visiting.remove(current);
+  }
+
+  helper(main);
+  Set<String> toKeep = visited.map((m) => m.name).toSet();
+  List<String> toRemove =
+      modules.keys.where((name) => !toKeep.contains(name)).toList();
+  toRemove.forEach(modules.remove);
+}
+
+/// Default entries for a .packages file with paths relative to the SDK root.
+List<int> _defaultPackagesInput = utf8.encode('''
+expect:pkg/expect/lib
+async_helper:pkg/async_helper/lib
+meta:pkg/meta/lib
+collection:third_party/pkg/collection/lib
+''');
+
+/// Specifies the dependencies of all packages in [_defaultPackagesInput]. This
+/// string needs to be updated if dependencies between those packages changes
+/// (which is rare).
+// TODO(sigmund): consider either computing this from the pubspec files or the
+// import graph, or adding tests that validate this is always up to date.
+String _defaultPackagesSpec = '''
+dependencies:
+  expect: meta
+  meta: []
+  async_helper: []
+  collection: []
+''';
+
+/// Report an conflict error.
+_moduleConflict(String name, Module existing, Uri root) {
+  var isFile = name.endsWith('.dart');
+  var entryType = isFile ? 'file' : 'folder';
+
+  var existingIsFile =
+      existing.packageBase.path == './' && existing.sources.length == 1;
+  var existingEntryType = existingIsFile ? 'file' : 'folder';
+
+  var existingName = existingIsFile
+      ? existing.sources.single.pathSegments.last
+      : existing.name;
+
+  return _invalidTest("The $entryType '$name' defines a module "
+      "which conflicts with the module defined by the $existingEntryType "
+      "'$existingName'.");
+}
+
+_invalidTest(String message) {
+  throw new InvalidTestError(message);
+}
+
+class InvalidTestError extends Error {
+  final String message;
+  InvalidTestError(this.message);
+  String toString() => "Invalid test: $message";
+}
diff --git a/pkg/modular_test/lib/src/memory_pipeline.dart b/pkg/modular_test/lib/src/memory_pipeline.dart
index 4f1740a..9ad5c43 100644
--- a/pkg/modular_test/lib/src/memory_pipeline.dart
+++ b/pkg/modular_test/lib/src/memory_pipeline.dart
@@ -13,8 +13,8 @@
 typedef SourceProvider = String Function(Uri);
 
 abstract class MemoryModularStep extends ModularStep {
-  Future<Object> execute(Module module, SourceProvider sourceProvider,
-      ModuleDataProvider dataProvider);
+  Future<Map<DataId, Object>> execute(Module module,
+      SourceProvider sourceProvider, ModuleDataProvider dataProvider);
 }
 
 class MemoryPipeline extends Pipeline<MemoryModularStep> {
@@ -27,7 +27,7 @@
   /// A copy of [_result] at the time the pipeline last finished running.
   Map<Module, Map<DataId, Object>> resultsForTesting;
 
-  MemoryPipeline(this._sources, List<ModularStep> steps) : super(steps);
+  MemoryPipeline(this._sources, List<MemoryModularStep> steps) : super(steps);
 
   @override
   Future<void> run(ModularTest test) async {
@@ -55,8 +55,12 @@
         inputSources[uri] = _sources[uri];
       });
     }
-    Object result = await step.execute(module, (Uri uri) => inputSources[uri],
+    Map<DataId, Object> result = await step.execute(
+        module,
+        (Uri uri) => inputSources[uri],
         (Module m, DataId id) => inputData[m][id]);
-    (_results[module] ??= {})[step.resultId] = result;
+    for (var dataId in step.resultData) {
+      (_results[module] ??= {})[dataId] = result[dataId];
+    }
   }
 }
diff --git a/pkg/modular_test/lib/src/pipeline.dart b/pkg/modular_test/lib/src/pipeline.dart
index 4bb3e89..64e08a7 100644
--- a/pkg/modular_test/lib/src/pipeline.dart
+++ b/pkg/modular_test/lib/src/pipeline.dart
@@ -25,25 +25,29 @@
   /// This can be data produced on a previous stage of the pipeline
   /// or produced by this same step when it was run on a dependency.
   ///
-  /// If this list includes [resultId], then the modular-step has to be run on
-  /// dependencies before it is run on a module. Otherwise, it could be run in
-  /// parallel.
+  /// If this list includes any data from [resultData], then the modular-step
+  /// has to be run on dependencies before it is run on a module. Otherwise, it
+  /// could be run in parallel.
   final List<DataId> dependencyDataNeeded;
 
   /// Data that this step needs to read about the module itself.
   ///
   /// This is meant to be data produced in earlier stages of the modular
-  /// pipeline. It is an error to include [resultId] in this list.
+  /// pipeline. It is an error to include any id from [resultData] in this list.
   final List<DataId> moduleDataNeeded;
 
   /// Data that this step produces.
-  final DataId resultId;
+  final List<DataId> resultData;
+
+  /// Whether this step is only executed on the main module.
+  final bool onlyOnMain;
 
   ModularStep(
       {this.needsSources: true,
       this.dependencyDataNeeded: const [],
       this.moduleDataNeeded: const [],
-      this.resultId});
+      this.resultData,
+      this.onlyOnMain: false});
 }
 
 /// An object to uniquely identify modular data produced by a modular step.
@@ -70,30 +74,35 @@
     // or by the same step on a dependency.
     Map<DataId, S> previousKinds = {};
     for (var step in steps) {
-      var resultKind = step.resultId;
-      if (previousKinds.containsKey(resultKind)) {
-        _validationError("Cannot produce the same data on two modular steps."
-            " '$resultKind' was previously produced by "
-            "'${previousKinds[resultKind].runtimeType}' but "
-            "'${step.runtimeType}' also produces the same data.");
+      if (step.resultData == null || step.resultData.isEmpty) {
+        _validationError(
+            "'${step.runtimeType}' needs to declare what data it produces.");
       }
-      previousKinds[resultKind] = step;
-      for (var dataId in step.dependencyDataNeeded) {
-        if (!previousKinds.containsKey(dataId)) {
-          _validationError(
-              "Step '${step.runtimeType}' needs data '${dataId}', but the data"
-              " is not produced by this or a preceding step.");
+      for (var resultKind in step.resultData) {
+        if (previousKinds.containsKey(resultKind)) {
+          _validationError("Cannot produce the same data on two modular steps."
+              " '$resultKind' was previously produced by "
+              "'${previousKinds[resultKind].runtimeType}' but "
+              "'${step.runtimeType}' also produces the same data.");
         }
-      }
-      for (var dataId in step.moduleDataNeeded) {
-        if (!previousKinds.containsKey(dataId)) {
-          _validationError(
-              "Step '${step.runtimeType}' needs data '${dataId}', but the data"
-              " is not produced by a preceding step.");
+        previousKinds[resultKind] = step;
+        for (var dataId in step.dependencyDataNeeded) {
+          if (!previousKinds.containsKey(dataId)) {
+            _validationError(
+                "Step '${step.runtimeType}' needs data '${dataId}', but the "
+                "data is not produced by this or a preceding step.");
+          }
         }
-        if (dataId == resultKind) {
-          _validationError(
-              "Circular dependency on '$dataId' in step '${step.runtimeType}'");
+        for (var dataId in step.moduleDataNeeded) {
+          if (!previousKinds.containsKey(dataId)) {
+            _validationError(
+                "Step '${step.runtimeType}' needs data '${dataId}', but the "
+                "data is not produced by a preceding step.");
+          }
+          if (dataId == resultKind) {
+            _validationError("Circular dependency on '$dataId' "
+                "in step '${step.runtimeType}'");
+          }
         }
       }
     }
@@ -105,26 +114,30 @@
     // TODO(sigmund): validate that [ModularTest] has no cycles.
     Map<Module, Set<DataId>> computedData = {};
     for (var step in steps) {
-      await _recursiveRun(step, test.mainModule, computedData, {});
+      await _recursiveRun(step, test.mainModule, computedData, {}, {});
     }
   }
 
-  Future<void> _recursiveRun(S step, Module module,
-      Map<Module, Set<DataId>> computedData, Set<Module> seen) async {
+  Future<void> _recursiveRun(
+      S step,
+      Module module,
+      Map<Module, Set<DataId>> computedData,
+      Set<Module> seen,
+      Set<Module> parentDependencies) async {
     if (!seen.add(module)) return;
+    parentDependencies.add(module);
+    Set<Module> transitiveDependencies = {};
     for (var dependency in module.dependencies) {
-      await _recursiveRun(step, dependency, computedData, seen);
+      await _recursiveRun(
+          step, dependency, computedData, seen, transitiveDependencies);
     }
+    parentDependencies.addAll(transitiveDependencies);
+
+    if (step.onlyOnMain && !module.isMain) return;
     // Include only requested data from transitive dependencies.
     Map<Module, Set<DataId>> visibleData = {};
 
-    // TODO(sigmund): consider excluding parent modules here. In particular,
-    // [seen] not only contains transitive dependencies, but also this module
-    // and parent modules. Technically we haven't computed any data for those,
-    // so we shouldn't be including any entries for parent modules in
-    // [visibleData].
-    seen.forEach((dep) {
-      if (dep == module) return;
+    transitiveDependencies.forEach((dep) {
       visibleData[dep] = {};
       for (var dataId in step.dependencyDataNeeded) {
         if (computedData[dep].contains(dataId)) {
@@ -139,7 +152,7 @@
       }
     }
     await runStep(step, module, visibleData);
-    (computedData[module] ??= {}).add(step.resultId);
+    (computedData[module] ??= {}).addAll(step.resultData);
   }
 
   Future<void> runStep(
diff --git a/pkg/modular_test/lib/src/suite.dart b/pkg/modular_test/lib/src/suite.dart
index bba158e..506349b 100644
--- a/pkg/modular_test/lib/src/suite.dart
+++ b/pkg/modular_test/lib/src/suite.dart
@@ -15,6 +15,8 @@
 
   ModularTest(this.modules, this.mainModule)
       : assert(mainModule != null && modules.length > 0);
+
+  String debugString() => modules.map((m) => m.debugString()).join('\n');
 }
 
 /// A single module in a modular test.
@@ -37,15 +39,51 @@
   /// [Uri] from [rootUri].
   final Uri mainSource;
 
+  /// Whether this module is also available as a package import, where the
+  /// package name matches the module name.
+  bool isPackage;
+
+  /// When [isPackage], the base where all package URIs are resolved against.
+  /// Stored as a relative [Uri] from [rootUri].
+  final Uri packageBase;
+
+  /// Whether this is the main entry module of a test.
+  bool isMain;
+
   Module(this.name, this.dependencies, this.rootUri, this.sources,
-      this.mainSource) {
+      {this.mainSource,
+      this.isPackage: false,
+      this.isMain: false,
+      this.packageBase}) {
     if (!_validModuleName.hasMatch(name)) {
-      throw "invalid module name: $name";
+      throw ArgumentError("invalid module name: $name");
     }
   }
 
   @override
   String toString() => '[module $name]';
+
+  String debugString() {
+    var buffer = new StringBuffer();
+    buffer.write('   ');
+    buffer.write(name);
+    buffer.write(': ');
+    buffer.write(isPackage ? 'package' : '(not package)');
+    buffer.write(', deps: {${dependencies.map((d) => d.name).join(", ")}}');
+    buffer.write(', sources: {${sources.map((u) => "$u").join(', ')}}');
+    return '$buffer';
+  }
 }
 
 final RegExp _validModuleName = new RegExp(r'^[a-zA-Z_][a-zA-Z0-9_]*$');
+
+/// Helper to compute transitive dependencies from [module].
+Set<Module> computeTransitiveDependencies(Module module) {
+  Set<Module> deps = {};
+  helper(Module m) {
+    if (deps.add(m)) m.dependencies.forEach(helper);
+  }
+
+  module.dependencies.forEach(helper);
+  return deps;
+}
diff --git a/pkg/modular_test/pubspec.yaml b/pkg/modular_test/pubspec.yaml
index 94f26d8..39f65c8 100644
--- a/pkg/modular_test/pubspec.yaml
+++ b/pkg/modular_test/pubspec.yaml
@@ -8,7 +8,9 @@
   sdk: ">=2.2.1 <3.0.0"
 
 dependencies:
+  package_config: ^1.0.5
   yaml: ^2.1.15
 
 dev_dependencies:
+  args: any
   test: any
diff --git a/pkg/modular_test/test/dependency_parser_test.dart b/pkg/modular_test/test/dependency_parser_test.dart
new file mode 100644
index 0000000..f536282
--- /dev/null
+++ b/pkg/modular_test/test/dependency_parser_test.dart
@@ -0,0 +1,64 @@
+// 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/test.dart';
+import 'package:modular_test/src/dependency_parser.dart';
+
+main() {
+  test('require dependencies section', () {
+    expect(() => parseDependencyMap(""),
+        throwsA(TypeMatcher<InvalidSpecificationError>()));
+  });
+
+  test('dependencies is a map', () {
+    expect(() => parseDependencyMap("dependencies: []"),
+        throwsA(TypeMatcher<InvalidSpecificationError>()));
+  });
+
+  test('dependencies can be a string or list of strings', () {
+    parseDependencyMap('''
+          dependencies:
+            a: b
+          ''');
+
+    parseDependencyMap('''
+          dependencies:
+            a: [b, c]
+          ''');
+
+    expect(() => parseDependencyMap('''
+          dependencies:
+            a: 1
+          '''), throwsA(TypeMatcher<InvalidSpecificationError>()));
+
+    expect(() => parseDependencyMap('''
+          dependencies:
+            a: true
+          '''), throwsA(TypeMatcher<InvalidSpecificationError>()));
+
+    expect(() => parseDependencyMap('''
+          dependencies:
+            a: [false]
+          '''), throwsA(TypeMatcher<InvalidSpecificationError>()));
+
+    expect(() => parseDependencyMap('''
+          dependencies:
+            a:
+               c: d
+          '''), throwsA(TypeMatcher<InvalidSpecificationError>()));
+  });
+
+  test('result map is normalized', () {
+    expect(
+        parseDependencyMap('''
+          dependencies:
+            a: [b, c]
+            b: d
+            '''),
+        equals({
+          'a': ['b', 'c'],
+          'b': ['d'],
+        }));
+  });
+}
diff --git a/pkg/modular_test/test/find_sdk_root1_test.dart b/pkg/modular_test/test/find_sdk_root1_test.dart
new file mode 100644
index 0000000..2a5ac51
--- /dev/null
+++ b/pkg/modular_test/test/find_sdk_root1_test.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:expect/expect.dart';
+import 'package:async_helper/async_helper.dart';
+import 'package:modular_test/src/find_sdk_root.dart';
+
+main() {
+  asyncTest(() async {
+    Expect.equals(Platform.script.resolve("../../../"), await findRoot());
+  });
+}
diff --git a/pkg/modular_test/test/io_pipeline_test.dart b/pkg/modular_test/test/io_pipeline_test.dart
index bc80082..dd3d01f 100644
--- a/pkg/modular_test/test/io_pipeline_test.dart
+++ b/pkg/modular_test/test/io_pipeline_test.dart
@@ -64,10 +64,28 @@
       LinkStep(action, inputId, depId, resultId, requestDependenciesData);
 
   @override
+  IOModularStep createMainOnlyStep(
+          {String Function(String, List<String>) action,
+          DataId inputId,
+          DataId depId,
+          DataId resultId,
+          bool requestDependenciesData: true}) =>
+      MainOnlyStep(action, inputId, depId, resultId, requestDependenciesData);
+
+  @override
+  IOModularStep createTwoOutputStep(
+          {String Function(String) action1,
+          String Function(String) action2,
+          DataId inputId,
+          DataId result1Id,
+          DataId result2Id}) =>
+      TwoOutputStep(action1, action2, inputId, result1Id, result2Id);
+
+  @override
   String getResult(covariant IOPipeline pipeline, Module m, DataId dataId) {
     var folderUri = pipeline.tmpFoldersForTesting[dataId];
-    return File.fromUri(folderUri.resolve("${m.name}.${dataId.name}"))
-        .readAsStringSync();
+    var file = File.fromUri(folderUri.resolve("${m.name}.${dataId.name}"));
+    return file.existsSync() ? file.readAsStringSync() : null;
   }
 
   @override
@@ -86,6 +104,8 @@
   final bool needsSources;
   List<DataId> get dependencyDataNeeded => const [];
   List<DataId> get moduleDataNeeded => const [];
+  List<DataId> get resultData => [resultId];
+  bool get onlyOnMain => false;
 
   SourceOnlyStep(this.action, this.resultId, this.needsSources);
 
@@ -109,8 +129,10 @@
   bool get needsSources => false;
   List<DataId> get dependencyDataNeeded => const [];
   final List<DataId> moduleDataNeeded;
+  List<DataId> get resultData => [resultId];
   final DataId resultId;
   final DataId inputId;
+  bool get onlyOnMain => false;
 
   ModuleDataStep(this.action, this.inputId, this.resultId, bool requestInput)
       : moduleDataNeeded = requestInput ? [inputId] : [];
@@ -126,14 +148,46 @@
   }
 }
 
+class TwoOutputStep implements IOModularStep {
+  final String Function(String) action1;
+  final String Function(String) action2;
+  bool get needsSources => false;
+  List<DataId> get dependencyDataNeeded => const [];
+  List<DataId> get moduleDataNeeded => [inputId];
+  List<DataId> get resultData => [result1Id, result2Id];
+  final DataId result1Id;
+  final DataId result2Id;
+  final DataId inputId;
+  bool get onlyOnMain => false;
+
+  TwoOutputStep(
+      this.action1, this.action2, this.inputId, this.result1Id, this.result2Id);
+
+  @override
+  Future<void> execute(
+      Module module, Uri root, ModuleDataToRelativeUri toUri) async {
+    var inputData = await _readHelper(module, root, inputId, toUri);
+    var result1 =
+        inputData == null ? "data for $module was null" : action1(inputData);
+    var result2 =
+        inputData == null ? "data for $module was null" : action2(inputData);
+    await File.fromUri(root.resolveUri(toUri(module, result1Id)))
+        .writeAsString(result1);
+    await File.fromUri(root.resolveUri(toUri(module, result2Id)))
+        .writeAsString(result2);
+  }
+}
+
 class LinkStep implements IOModularStep {
   bool get needsSources => false;
   final List<DataId> dependencyDataNeeded;
   List<DataId> get moduleDataNeeded => [inputId];
+  List<DataId> get resultData => [resultId];
   final String Function(String, List<String>) action;
   final DataId inputId;
   final DataId depId;
   final DataId resultId;
+  bool get onlyOnMain => false;
 
   LinkStep(this.action, this.inputId, this.depId, this.resultId,
       bool requestDependencies)
@@ -153,6 +207,35 @@
   }
 }
 
+class MainOnlyStep implements IOModularStep {
+  bool get needsSources => false;
+  final List<DataId> dependencyDataNeeded;
+  List<DataId> get moduleDataNeeded => [inputId];
+  List<DataId> get resultData => [resultId];
+  final String Function(String, List<String>) action;
+  final DataId inputId;
+  final DataId depId;
+  final DataId resultId;
+  bool get onlyOnMain => true;
+
+  MainOnlyStep(this.action, this.inputId, this.depId, this.resultId,
+      bool requestDependencies)
+      : dependencyDataNeeded = requestDependencies ? [depId] : [];
+
+  @override
+  Future<void> execute(
+      Module module, Uri root, ModuleDataToRelativeUri toUri) async {
+    List<String> depsData = [];
+    for (var dependency in computeTransitiveDependencies(module)) {
+      var depData = await _readHelper(dependency, root, depId, toUri);
+      depsData.add(depData);
+    }
+    var inputData = await _readHelper(module, root, inputId, toUri);
+    await File.fromUri(root.resolveUri(toUri(module, resultId)))
+        .writeAsString(action(inputData, depsData));
+  }
+}
+
 Future<String> _readHelper(Module module, Uri root, DataId dataId,
     ModuleDataToRelativeUri toUri) async {
   var file = File.fromUri(root.resolveUri(toUri(module, dataId)));
diff --git a/pkg/modular_test/test/loader/conflict_file_folder_error/expectation.txt b/pkg/modular_test/test/loader/conflict_file_folder_error/expectation.txt
new file mode 100644
index 0000000..4a83176
--- /dev/null
+++ b/pkg/modular_test/test/loader/conflict_file_folder_error/expectation.txt
@@ -0,0 +1,3 @@
+# This expectation file is generated by loader_test.dart
+
+Invalid test: The file 'm1.dart' defines a module which conflicts with the module defined by the folder 'm1'.
\ No newline at end of file
diff --git a/pkg/modular_test/test/loader/conflict_file_folder_error/m1.dart b/pkg/modular_test/test/loader/conflict_file_folder_error/m1.dart
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/pkg/modular_test/test/loader/conflict_file_folder_error/m1.dart
@@ -0,0 +1 @@
+
diff --git a/pkg/modular_test/test/loader/conflict_file_folder_error/m1/b.dart b/pkg/modular_test/test/loader/conflict_file_folder_error/m1/b.dart
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/pkg/modular_test/test/loader/conflict_file_folder_error/m1/b.dart
@@ -0,0 +1 @@
+
diff --git a/pkg/modular_test/test/loader/conflict_file_folder_error/modules.yaml b/pkg/modular_test/test/loader/conflict_file_folder_error/modules.yaml
new file mode 100644
index 0000000..c093387
--- /dev/null
+++ b/pkg/modular_test/test/loader/conflict_file_folder_error/modules.yaml
@@ -0,0 +1 @@
+dependencies: {}
diff --git a/pkg/modular_test/test/loader/conflict_file_package_error/expect.dart b/pkg/modular_test/test/loader/conflict_file_package_error/expect.dart
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/pkg/modular_test/test/loader/conflict_file_package_error/expect.dart
@@ -0,0 +1 @@
+
diff --git a/pkg/modular_test/test/loader/conflict_file_package_error/expectation.txt b/pkg/modular_test/test/loader/conflict_file_package_error/expectation.txt
new file mode 100644
index 0000000..cabe77c
--- /dev/null
+++ b/pkg/modular_test/test/loader/conflict_file_package_error/expectation.txt
@@ -0,0 +1,3 @@
+# This expectation file is generated by loader_test.dart
+
+Invalid test: The file 'expect.dart' defines a module called 'expect' which conflicts with a package by the same name that is provided by default.
\ No newline at end of file
diff --git a/pkg/modular_test/test/loader/conflict_file_package_error/modules.yaml b/pkg/modular_test/test/loader/conflict_file_package_error/modules.yaml
new file mode 100644
index 0000000..c093387
--- /dev/null
+++ b/pkg/modular_test/test/loader/conflict_file_package_error/modules.yaml
@@ -0,0 +1 @@
+dependencies: {}
diff --git a/pkg/modular_test/test/loader/conflict_folder_package_error/expect/a.dart b/pkg/modular_test/test/loader/conflict_folder_package_error/expect/a.dart
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/pkg/modular_test/test/loader/conflict_folder_package_error/expect/a.dart
@@ -0,0 +1 @@
+
diff --git a/pkg/modular_test/test/loader/conflict_folder_package_error/expectation.txt b/pkg/modular_test/test/loader/conflict_folder_package_error/expectation.txt
new file mode 100644
index 0000000..5118fc0
--- /dev/null
+++ b/pkg/modular_test/test/loader/conflict_folder_package_error/expectation.txt
@@ -0,0 +1,3 @@
+# This expectation file is generated by loader_test.dart
+
+Invalid test: The folder 'expect' defines a module which conflicts with a package by the same name that is provided by default.
\ No newline at end of file
diff --git a/pkg/modular_test/test/loader/conflict_folder_package_error/modules.yaml b/pkg/modular_test/test/loader/conflict_folder_package_error/modules.yaml
new file mode 100644
index 0000000..c093387
--- /dev/null
+++ b/pkg/modular_test/test/loader/conflict_folder_package_error/modules.yaml
@@ -0,0 +1 @@
+dependencies: {}
diff --git a/pkg/modular_test/test/loader/cycle_error/a.dart b/pkg/modular_test/test/loader/cycle_error/a.dart
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/pkg/modular_test/test/loader/cycle_error/a.dart
@@ -0,0 +1 @@
+
diff --git a/pkg/modular_test/test/loader/cycle_error/b.dart b/pkg/modular_test/test/loader/cycle_error/b.dart
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/pkg/modular_test/test/loader/cycle_error/b.dart
@@ -0,0 +1 @@
+
diff --git a/pkg/modular_test/test/loader/cycle_error/c.dart b/pkg/modular_test/test/loader/cycle_error/c.dart
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/pkg/modular_test/test/loader/cycle_error/c.dart
@@ -0,0 +1 @@
+
diff --git a/pkg/modular_test/test/loader/cycle_error/expectation.txt b/pkg/modular_test/test/loader/cycle_error/expectation.txt
new file mode 100644
index 0000000..3825548
--- /dev/null
+++ b/pkg/modular_test/test/loader/cycle_error/expectation.txt
@@ -0,0 +1,3 @@
+# This expectation file is generated by loader_test.dart
+
+Invalid test: module 'b' has a dependency cycle.
\ No newline at end of file
diff --git a/pkg/modular_test/test/loader/cycle_error/main.dart b/pkg/modular_test/test/loader/cycle_error/main.dart
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/pkg/modular_test/test/loader/cycle_error/main.dart
@@ -0,0 +1 @@
+
diff --git a/pkg/modular_test/test/loader/cycle_error/modules.yaml b/pkg/modular_test/test/loader/cycle_error/modules.yaml
new file mode 100644
index 0000000..b07465b
--- /dev/null
+++ b/pkg/modular_test/test/loader/cycle_error/modules.yaml
@@ -0,0 +1,5 @@
+dependencies:
+  a: b
+  b: c
+  c: a
+  main: b
diff --git a/pkg/modular_test/test/loader/dag/a.dart b/pkg/modular_test/test/loader/dag/a.dart
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/pkg/modular_test/test/loader/dag/a.dart
@@ -0,0 +1 @@
+
diff --git a/pkg/modular_test/test/loader/dag/b.dart b/pkg/modular_test/test/loader/dag/b.dart
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/pkg/modular_test/test/loader/dag/b.dart
@@ -0,0 +1 @@
+
diff --git a/pkg/modular_test/test/loader/dag/c.dart b/pkg/modular_test/test/loader/dag/c.dart
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/pkg/modular_test/test/loader/dag/c.dart
@@ -0,0 +1 @@
+
diff --git a/pkg/modular_test/test/loader/dag/d/d.dart b/pkg/modular_test/test/loader/dag/d/d.dart
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/pkg/modular_test/test/loader/dag/d/d.dart
@@ -0,0 +1 @@
+
diff --git a/pkg/modular_test/test/loader/dag/d/e.dart b/pkg/modular_test/test/loader/dag/d/e.dart
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/pkg/modular_test/test/loader/dag/d/e.dart
@@ -0,0 +1 @@
+
diff --git a/pkg/modular_test/test/loader/dag/expectation.txt b/pkg/modular_test/test/loader/dag/expectation.txt
new file mode 100644
index 0000000..885c41f
--- /dev/null
+++ b/pkg/modular_test/test/loader/dag/expectation.txt
@@ -0,0 +1,28 @@
+# This expectation file is generated by loader_test.dart
+
+a
+  is package? no
+  dependencies: b, c
+  a.dart
+
+b
+  is package? no
+  dependencies: d
+  b.dart
+
+c
+  is package? no
+  (no dependencies)
+  c.dart
+
+d
+  is package? no
+  (no dependencies)
+  d/d.dart
+  d/e.dart
+
+main
+  **main module**
+  is package? no
+  dependencies: a, b
+  main.dart
diff --git a/pkg/modular_test/test/loader/dag/main.dart b/pkg/modular_test/test/loader/dag/main.dart
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/pkg/modular_test/test/loader/dag/main.dart
@@ -0,0 +1 @@
+
diff --git a/pkg/modular_test/test/loader/dag/modules.yaml b/pkg/modular_test/test/loader/dag/modules.yaml
new file mode 100644
index 0000000..0a775d2
--- /dev/null
+++ b/pkg/modular_test/test/loader/dag/modules.yaml
@@ -0,0 +1,4 @@
+dependencies:
+  a: [b, c]
+  b: d
+  main: [a, b]
diff --git a/pkg/modular_test/test/loader/dag_with_packages/.packages b/pkg/modular_test/test/loader/dag_with_packages/.packages
new file mode 100644
index 0000000..5f1a721
--- /dev/null
+++ b/pkg/modular_test/test/loader/dag_with_packages/.packages
@@ -0,0 +1,2 @@
+a:a/
+c:c/
diff --git a/pkg/modular_test/test/loader/dag_with_packages/a.dart b/pkg/modular_test/test/loader/dag_with_packages/a.dart
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/pkg/modular_test/test/loader/dag_with_packages/a.dart
@@ -0,0 +1 @@
+
diff --git a/pkg/modular_test/test/loader/dag_with_packages/b.dart b/pkg/modular_test/test/loader/dag_with_packages/b.dart
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/pkg/modular_test/test/loader/dag_with_packages/b.dart
@@ -0,0 +1 @@
+
diff --git a/pkg/modular_test/test/loader/dag_with_packages/c.dart b/pkg/modular_test/test/loader/dag_with_packages/c.dart
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/pkg/modular_test/test/loader/dag_with_packages/c.dart
@@ -0,0 +1 @@
+
diff --git a/pkg/modular_test/test/loader/dag_with_packages/d/d.dart b/pkg/modular_test/test/loader/dag_with_packages/d/d.dart
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/pkg/modular_test/test/loader/dag_with_packages/d/d.dart
@@ -0,0 +1 @@
+
diff --git a/pkg/modular_test/test/loader/dag_with_packages/d/e.dart b/pkg/modular_test/test/loader/dag_with_packages/d/e.dart
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/pkg/modular_test/test/loader/dag_with_packages/d/e.dart
@@ -0,0 +1 @@
+
diff --git a/pkg/modular_test/test/loader/dag_with_packages/expectation.txt b/pkg/modular_test/test/loader/dag_with_packages/expectation.txt
new file mode 100644
index 0000000..df35ba5
--- /dev/null
+++ b/pkg/modular_test/test/loader/dag_with_packages/expectation.txt
@@ -0,0 +1,28 @@
+# This expectation file is generated by loader_test.dart
+
+a
+  is package? yes
+  dependencies: b, c
+  a.dart
+
+b
+  is package? no
+  dependencies: d
+  b.dart
+
+c
+  is package? yes
+  (no dependencies)
+  c.dart
+
+d
+  is package? no
+  (no dependencies)
+  d/d.dart
+  d/e.dart
+
+main
+  **main module**
+  is package? no
+  dependencies: a, b
+  main.dart
diff --git a/pkg/modular_test/test/loader/dag_with_packages/main.dart b/pkg/modular_test/test/loader/dag_with_packages/main.dart
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/pkg/modular_test/test/loader/dag_with_packages/main.dart
@@ -0,0 +1 @@
+
diff --git a/pkg/modular_test/test/loader/dag_with_packages/modules.yaml b/pkg/modular_test/test/loader/dag_with_packages/modules.yaml
new file mode 100644
index 0000000..0a775d2
--- /dev/null
+++ b/pkg/modular_test/test/loader/dag_with_packages/modules.yaml
@@ -0,0 +1,4 @@
+dependencies:
+  a: [b, c]
+  b: d
+  main: [a, b]
diff --git a/pkg/modular_test/test/loader/default_package_dependency_error/expectation.txt b/pkg/modular_test/test/loader/default_package_dependency_error/expectation.txt
new file mode 100644
index 0000000..cf449f3
--- /dev/null
+++ b/pkg/modular_test/test/loader/default_package_dependency_error/expectation.txt
@@ -0,0 +1,20 @@
+# This expectation file is generated by loader_test.dart
+
+expect
+  is package? yes
+  dependencies: meta
+  lib/expect.dart
+  lib/matchers_lite.dart
+  lib/minitest.dart
+
+main
+  **main module**
+  is package? no
+  dependencies: expect
+  main.dart
+
+meta
+  is package? yes
+  (no dependencies)
+  lib/dart2js.dart
+  lib/meta.dart
diff --git a/pkg/modular_test/test/loader/default_package_dependency_error/main.dart b/pkg/modular_test/test/loader/default_package_dependency_error/main.dart
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/pkg/modular_test/test/loader/default_package_dependency_error/main.dart
@@ -0,0 +1 @@
+
diff --git a/pkg/modular_test/test/loader/default_package_dependency_error/modules.yaml b/pkg/modular_test/test/loader/default_package_dependency_error/modules.yaml
new file mode 100644
index 0000000..a5864d3
--- /dev/null
+++ b/pkg/modular_test/test/loader/default_package_dependency_error/modules.yaml
@@ -0,0 +1,3 @@
+dependencies:
+  main:
+    - expect
diff --git a/pkg/modular_test/test/loader/invalid_module_name_error/bad.name.dart b/pkg/modular_test/test/loader/invalid_module_name_error/bad.name.dart
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/pkg/modular_test/test/loader/invalid_module_name_error/bad.name.dart
@@ -0,0 +1 @@
+
diff --git a/pkg/modular_test/test/loader/invalid_module_name_error/expectation.txt b/pkg/modular_test/test/loader/invalid_module_name_error/expectation.txt
new file mode 100644
index 0000000..631afff
--- /dev/null
+++ b/pkg/modular_test/test/loader/invalid_module_name_error/expectation.txt
@@ -0,0 +1,3 @@
+# This expectation file is generated by loader_test.dart
+
+Invalid argument(s): invalid module name: bad.name
\ No newline at end of file
diff --git a/pkg/modular_test/test/loader/invalid_module_name_error/modules.yaml b/pkg/modular_test/test/loader/invalid_module_name_error/modules.yaml
new file mode 100644
index 0000000..c093387
--- /dev/null
+++ b/pkg/modular_test/test/loader/invalid_module_name_error/modules.yaml
@@ -0,0 +1 @@
+dependencies: {}
diff --git a/pkg/modular_test/test/loader/invalid_packages_error/.packages b/pkg/modular_test/test/loader/invalid_packages_error/.packages
new file mode 100644
index 0000000..d8892ce
--- /dev/null
+++ b/pkg/modular_test/test/loader/invalid_packages_error/.packages
@@ -0,0 +1 @@
+expect:.
diff --git a/pkg/modular_test/test/loader/invalid_packages_error/expectation.txt b/pkg/modular_test/test/loader/invalid_packages_error/expectation.txt
new file mode 100644
index 0000000..6931c77
--- /dev/null
+++ b/pkg/modular_test/test/loader/invalid_packages_error/expectation.txt
@@ -0,0 +1,3 @@
+# This expectation file is generated by loader_test.dart
+
+Invalid test: .packages file defines an conflicting entry for package 'expect'.
\ No newline at end of file
diff --git a/pkg/modular_test/test/loader/invalid_packages_error/main.dart b/pkg/modular_test/test/loader/invalid_packages_error/main.dart
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/pkg/modular_test/test/loader/invalid_packages_error/main.dart
@@ -0,0 +1 @@
+
diff --git a/pkg/modular_test/test/loader/invalid_packages_error/modules.yaml b/pkg/modular_test/test/loader/invalid_packages_error/modules.yaml
new file mode 100644
index 0000000..a5864d3
--- /dev/null
+++ b/pkg/modular_test/test/loader/invalid_packages_error/modules.yaml
@@ -0,0 +1,3 @@
+dependencies:
+  main:
+    - expect
diff --git a/pkg/modular_test/test/loader/loader_test.dart b/pkg/modular_test/test/loader/loader_test.dart
new file mode 100644
index 0000000..4f5f59c
--- /dev/null
+++ b/pkg/modular_test/test/loader/loader_test.dart
@@ -0,0 +1,130 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// Tests that the logic to load, parse, and validate modular tests.
+import 'dart:io';
+import 'package:async_helper/async_helper.dart';
+import 'package:expect/expect.dart';
+import 'package:modular_test/src/loader.dart';
+import 'package:modular_test/src/suite.dart';
+
+import 'package:args/args.dart';
+
+main(List<String> args) {
+  var options = _Options.parse(args);
+  asyncTest(() async {
+    var baseUri = Platform.script.resolve('./');
+    var baseDir = Directory.fromUri(baseUri);
+    await for (var entry in baseDir.list(recursive: false)) {
+      if (entry is Directory) {
+        await _runTest(entry.uri, baseUri, options);
+      }
+    }
+  });
+}
+
+Future<void> _runTest(Uri uri, Uri baseDir, _Options options) async {
+  var dirName = uri.path.substring(baseDir.path.length);
+  if (options.filter != null && !dirName.contains(options.filter)) {
+    if (options.showSkipped) print("skipped: $dirName");
+    return;
+  }
+
+  print("testing: $dirName");
+  String result;
+  String header =
+      "# This expectation file is generated by loader_test.dart\n\n";
+  try {
+    ModularTest test = await loadTest(uri);
+    result = '$header${_dumpAsText(test)}';
+  } on Error catch (e) {
+    result = '$header$e';
+  }
+
+  var file = File.fromUri(uri.resolve('expectation.txt'));
+  if (!options.updateExpectations) {
+    Expect.isTrue(await file.exists(), "expectation.txt file is missing");
+    var expectation = await file.readAsString();
+    if (expectation != result) {
+      print("expectation.txt doesn't match the result of the test. "
+          "To update it, run:\n"
+          "   ${Platform.executable} ${Platform.script} "
+          "--update --show-update --filter $dirName");
+    }
+    Expect.equals(expectation, result);
+    print("  expectation matches result.");
+  } else if (await file.exists() && (await file.readAsString() == result)) {
+    print("  expectation matches result and was up to date.");
+  } else {
+    await file.writeAsString(result);
+    print("  updated ${file.uri}");
+    if (options.showResultOnUpdate) {
+      print('  new expectation is:\x1b[32m\n$result\x1b[0m');
+    }
+  }
+}
+
+String _dumpAsText(ModularTest test) {
+  var buffer = new StringBuffer();
+  bool isFirst = true;
+  for (var module in test.modules) {
+    if (isFirst) {
+      isFirst = false;
+    } else {
+      buffer.write('\n');
+    }
+    buffer.write(module.name);
+    if (module.isMain) {
+      Expect.equals(test.mainModule, module);
+      buffer.write('\n  **main module**');
+    }
+    buffer.write('\n  is package? ${module.isPackage ? 'yes' : 'no'}');
+    if (module.dependencies.isEmpty) {
+      buffer.write('\n  (no dependencies)');
+    } else {
+      buffer.write('\n  dependencies: '
+          '${module.dependencies.map((d) => d.name).join(", ")}');
+    }
+
+    if (module.sources.isEmpty) {
+      buffer.write('\n  (no sources)');
+    } else {
+      module.sources.forEach((uri) {
+        buffer.write('\n  $uri');
+      });
+    }
+
+    buffer.write('\n');
+  }
+  return '$buffer';
+}
+
+class _Options {
+  bool updateExpectations = false;
+  bool showResultOnUpdate = false;
+  bool showSkipped = false;
+  String filter = null;
+
+  static _Options parse(List<String> args) {
+    var parser = new ArgParser()
+      ..addFlag('update',
+          abbr: 'u',
+          defaultsTo: false,
+          help: "update expectation files if the result don't match")
+      ..addFlag('show-update',
+          defaultsTo: false,
+          help: "print the result when updating expectation files")
+      ..addFlag('show-skipped',
+          defaultsTo: false,
+          help: "print the name of the tests skipped by the filtering option")
+      ..addOption('filter',
+          help: "only run tests containing this filter as a substring");
+    ArgResults argResults = parser.parse(args);
+    return _Options()
+      ..updateExpectations = argResults['update']
+      ..showResultOnUpdate = argResults['show-update']
+      ..showSkipped = argResults['show-skipped']
+      ..filter = argResults['filter'];
+  }
+}
diff --git a/pkg/modular_test/test/loader/missing_dependency_module_error/expectation.txt b/pkg/modular_test/test/loader/missing_dependency_module_error/expectation.txt
new file mode 100644
index 0000000..7fc8c8b
--- /dev/null
+++ b/pkg/modular_test/test/loader/missing_dependency_module_error/expectation.txt
@@ -0,0 +1,3 @@
+# This expectation file is generated by loader_test.dart
+
+Invalid test: 'main' declares a dependency on a non existing module named 'foo'
\ No newline at end of file
diff --git a/pkg/modular_test/test/loader/missing_dependency_module_error/main.dart b/pkg/modular_test/test/loader/missing_dependency_module_error/main.dart
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/pkg/modular_test/test/loader/missing_dependency_module_error/main.dart
@@ -0,0 +1 @@
+
diff --git a/pkg/modular_test/test/loader/missing_dependency_module_error/modules.yaml b/pkg/modular_test/test/loader/missing_dependency_module_error/modules.yaml
new file mode 100644
index 0000000..ffd0987
--- /dev/null
+++ b/pkg/modular_test/test/loader/missing_dependency_module_error/modules.yaml
@@ -0,0 +1,3 @@
+dependencies:
+  main:
+    - foo
diff --git a/pkg/modular_test/test/loader/missing_module_error/expectation.txt b/pkg/modular_test/test/loader/missing_module_error/expectation.txt
new file mode 100644
index 0000000..6551c46
--- /dev/null
+++ b/pkg/modular_test/test/loader/missing_module_error/expectation.txt
@@ -0,0 +1,3 @@
+# This expectation file is generated by loader_test.dart
+
+Invalid test: declared dependencies for a non existing module named 'foo'
\ No newline at end of file
diff --git a/pkg/modular_test/test/loader/missing_module_error/main.dart b/pkg/modular_test/test/loader/missing_module_error/main.dart
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/pkg/modular_test/test/loader/missing_module_error/main.dart
@@ -0,0 +1 @@
+
diff --git a/pkg/modular_test/test/loader/missing_module_error/modules.yaml b/pkg/modular_test/test/loader/missing_module_error/modules.yaml
new file mode 100644
index 0000000..87e50e1
--- /dev/null
+++ b/pkg/modular_test/test/loader/missing_module_error/modules.yaml
@@ -0,0 +1,3 @@
+dependencies:
+  foo:
+    - expect
diff --git a/pkg/modular_test/test/loader/missing_yaml_error/a.dart b/pkg/modular_test/test/loader/missing_yaml_error/a.dart
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/pkg/modular_test/test/loader/missing_yaml_error/a.dart
@@ -0,0 +1 @@
+
diff --git a/pkg/modular_test/test/loader/missing_yaml_error/expectation.txt b/pkg/modular_test/test/loader/missing_yaml_error/expectation.txt
new file mode 100644
index 0000000..9dd6322
--- /dev/null
+++ b/pkg/modular_test/test/loader/missing_yaml_error/expectation.txt
@@ -0,0 +1,3 @@
+# This expectation file is generated by loader_test.dart
+
+Invalid test: modules.yaml file is missing
\ No newline at end of file
diff --git a/pkg/modular_test/test/loader/no_dependencies/expectation.txt b/pkg/modular_test/test/loader/no_dependencies/expectation.txt
new file mode 100644
index 0000000..f19449b
--- /dev/null
+++ b/pkg/modular_test/test/loader/no_dependencies/expectation.txt
@@ -0,0 +1,7 @@
+# This expectation file is generated by loader_test.dart
+
+main
+  **main module**
+  is package? no
+  (no dependencies)
+  main.dart
diff --git a/pkg/modular_test/test/loader/no_dependencies/main.dart b/pkg/modular_test/test/loader/no_dependencies/main.dart
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/pkg/modular_test/test/loader/no_dependencies/main.dart
@@ -0,0 +1 @@
+
diff --git a/pkg/modular_test/test/loader/no_dependencies/modules.yaml b/pkg/modular_test/test/loader/no_dependencies/modules.yaml
new file mode 100644
index 0000000..c093387
--- /dev/null
+++ b/pkg/modular_test/test/loader/no_dependencies/modules.yaml
@@ -0,0 +1 @@
+dependencies: {}
diff --git a/pkg/modular_test/test/loader/no_main_error/a.dart b/pkg/modular_test/test/loader/no_main_error/a.dart
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/pkg/modular_test/test/loader/no_main_error/a.dart
@@ -0,0 +1 @@
+
diff --git a/pkg/modular_test/test/loader/no_main_error/expectation.txt b/pkg/modular_test/test/loader/no_main_error/expectation.txt
new file mode 100644
index 0000000..78e9711
--- /dev/null
+++ b/pkg/modular_test/test/loader/no_main_error/expectation.txt
@@ -0,0 +1,3 @@
+# This expectation file is generated by loader_test.dart
+
+Invalid test: main module is missing
\ No newline at end of file
diff --git a/pkg/modular_test/test/loader/no_main_error/modules.yaml b/pkg/modular_test/test/loader/no_main_error/modules.yaml
new file mode 100644
index 0000000..c093387
--- /dev/null
+++ b/pkg/modular_test/test/loader/no_main_error/modules.yaml
@@ -0,0 +1 @@
+dependencies: {}
diff --git a/pkg/modular_test/test/loader/readme.md b/pkg/modular_test/test/loader/readme.md
new file mode 100644
index 0000000..a3da9fa
--- /dev/null
+++ b/pkg/modular_test/test/loader/readme.md
@@ -0,0 +1,18 @@
+The `loader_test` folder contains a folder per test.
+
+Each test is focusing on part of the features of how tests folders are
+recognized and turned into a modular test specification by our libraries.  Note
+that all `.dart` source files in these tests are empty because we ignore their
+contents.
+
+Each folder contains a file named `expectation.txt` which shows a plain text
+summary of what we expect to extract or report from the test:
+
+ * for invalid inputs it shows the error mesage produced by the modular\_test
+   loader logic
+
+ * for valid inputs it shows the test layout, highlighting what each module
+   contents and dependencies are.
+
+In the future, modular tests will be written in the style of the non-error test
+cases.
diff --git a/pkg/modular_test/test/loader/tree/a.dart b/pkg/modular_test/test/loader/tree/a.dart
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/pkg/modular_test/test/loader/tree/a.dart
@@ -0,0 +1 @@
+
diff --git a/pkg/modular_test/test/loader/tree/b.dart b/pkg/modular_test/test/loader/tree/b.dart
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/pkg/modular_test/test/loader/tree/b.dart
@@ -0,0 +1 @@
+
diff --git a/pkg/modular_test/test/loader/tree/c.dart b/pkg/modular_test/test/loader/tree/c.dart
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/pkg/modular_test/test/loader/tree/c.dart
@@ -0,0 +1 @@
+
diff --git a/pkg/modular_test/test/loader/tree/d/d.dart b/pkg/modular_test/test/loader/tree/d/d.dart
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/pkg/modular_test/test/loader/tree/d/d.dart
@@ -0,0 +1 @@
+
diff --git a/pkg/modular_test/test/loader/tree/d/e.dart b/pkg/modular_test/test/loader/tree/d/e.dart
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/pkg/modular_test/test/loader/tree/d/e.dart
@@ -0,0 +1 @@
+
diff --git a/pkg/modular_test/test/loader/tree/expectation.txt b/pkg/modular_test/test/loader/tree/expectation.txt
new file mode 100644
index 0000000..f438e22
--- /dev/null
+++ b/pkg/modular_test/test/loader/tree/expectation.txt
@@ -0,0 +1,28 @@
+# This expectation file is generated by loader_test.dart
+
+a
+  is package? no
+  dependencies: b, c
+  a.dart
+
+b
+  is package? no
+  dependencies: d
+  b.dart
+
+c
+  is package? no
+  (no dependencies)
+  c.dart
+
+d
+  is package? no
+  (no dependencies)
+  d/d.dart
+  d/e.dart
+
+main
+  **main module**
+  is package? no
+  dependencies: a
+  main.dart
diff --git a/pkg/modular_test/test/loader/tree/main.dart b/pkg/modular_test/test/loader/tree/main.dart
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/pkg/modular_test/test/loader/tree/main.dart
@@ -0,0 +1 @@
+
diff --git a/pkg/modular_test/test/loader/tree/modules.yaml b/pkg/modular_test/test/loader/tree/modules.yaml
new file mode 100644
index 0000000..b1254c0
--- /dev/null
+++ b/pkg/modular_test/test/loader/tree/modules.yaml
@@ -0,0 +1,4 @@
+dependencies:
+  a: [b, c]
+  b: d
+  main: a
diff --git a/pkg/modular_test/test/loader/valid_packages/.packages b/pkg/modular_test/test/loader/valid_packages/.packages
new file mode 100644
index 0000000..d8e718b
--- /dev/null
+++ b/pkg/modular_test/test/loader/valid_packages/.packages
@@ -0,0 +1 @@
+js:../../../../js/lib
diff --git a/pkg/modular_test/test/loader/valid_packages/expectation.txt b/pkg/modular_test/test/loader/valid_packages/expectation.txt
new file mode 100644
index 0000000..dab4163
--- /dev/null
+++ b/pkg/modular_test/test/loader/valid_packages/expectation.txt
@@ -0,0 +1,27 @@
+# This expectation file is generated by loader_test.dart
+
+expect
+  is package? yes
+  dependencies: meta
+  lib/expect.dart
+  lib/matchers_lite.dart
+  lib/minitest.dart
+
+js
+  is package? yes
+  (no dependencies)
+  lib/js.dart
+  lib/js_util.dart
+  lib/src/varargs.dart
+
+main
+  **main module**
+  is package? no
+  dependencies: js, expect
+  main.dart
+
+meta
+  is package? yes
+  (no dependencies)
+  lib/dart2js.dart
+  lib/meta.dart
diff --git a/pkg/modular_test/test/loader/valid_packages/main.dart b/pkg/modular_test/test/loader/valid_packages/main.dart
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/pkg/modular_test/test/loader/valid_packages/main.dart
@@ -0,0 +1 @@
+
diff --git a/pkg/modular_test/test/loader/valid_packages/modules.yaml b/pkg/modular_test/test/loader/valid_packages/modules.yaml
new file mode 100644
index 0000000..2ad9483
--- /dev/null
+++ b/pkg/modular_test/test/loader/valid_packages/modules.yaml
@@ -0,0 +1,4 @@
+dependencies:
+  main:
+    - js
+    - expect
diff --git a/pkg/modular_test/test/memory_pipeline_test.dart b/pkg/modular_test/test/memory_pipeline_test.dart
index 2e35a940..ba406e1 100644
--- a/pkg/modular_test/test/memory_pipeline_test.dart
+++ b/pkg/modular_test/test/memory_pipeline_test.dart
@@ -51,6 +51,24 @@
       LinkStep(action, inputId, depId, resultId, requestDependenciesData);
 
   @override
+  MemoryModularStep createMainOnlyStep(
+          {String Function(String, List<String>) action,
+          DataId inputId,
+          DataId depId,
+          DataId resultId,
+          bool requestDependenciesData: true}) =>
+      MainOnlyStep(action, inputId, depId, resultId, requestDependenciesData);
+
+  @override
+  MemoryModularStep createTwoOutputStep(
+          {String Function(String) action1,
+          String Function(String) action2,
+          DataId inputId,
+          DataId result1Id,
+          DataId result2Id}) =>
+      TwoOutputStep(action1, action2, inputId, result1Id, result2Id);
+
+  @override
   String getResult(covariant MemoryPipeline pipeline, Module m, DataId dataId) {
     return pipeline.resultsForTesting[m][dataId];
   }
@@ -64,16 +82,18 @@
   final bool needsSources;
   List<DataId> get dependencyDataNeeded => const [];
   List<DataId> get moduleDataNeeded => const [];
+  List<DataId> get resultData => [resultId];
+  bool get onlyOnMain => false;
 
   SourceOnlyStep(this.action, this.resultId, this.needsSources);
 
-  Future<Object> execute(Module module, SourceProvider sourceProvider,
-      ModuleDataProvider dataProvider) {
+  Future<Map<DataId, Object>> execute(Module module,
+      SourceProvider sourceProvider, ModuleDataProvider dataProvider) {
     Map<Uri, String> sources = {};
     for (var uri in module.sources) {
       sources[uri] = sourceProvider(module.rootUri.resolveUri(uri));
     }
-    return Future.value(action(sources));
+    return Future.value({resultId: action(sources)});
   }
 }
 
@@ -82,17 +102,48 @@
   bool get needsSources => false;
   List<DataId> get dependencyDataNeeded => const [];
   final List<DataId> moduleDataNeeded;
+  List<DataId> get resultData => [resultId];
   final DataId resultId;
   final DataId inputId;
+  bool get onlyOnMain => false;
 
   ModuleDataStep(this.action, this.inputId, this.resultId, bool requestInput)
       : moduleDataNeeded = requestInput ? [inputId] : [];
 
-  Future<Object> execute(Module module, SourceProvider sourceProvider,
-      ModuleDataProvider dataProvider) {
+  Future<Map<DataId, Object>> execute(Module module,
+      SourceProvider sourceProvider, ModuleDataProvider dataProvider) {
     var inputData = dataProvider(module, inputId) as String;
-    if (inputData == null) return Future.value("data for $module was null");
-    return Future.value(action(inputData));
+    if (inputData == null)
+      return Future.value({resultId: "data for $module was null"});
+    return Future.value({resultId: action(inputData)});
+  }
+}
+
+class TwoOutputStep implements MemoryModularStep {
+  final String Function(String) action1;
+  final String Function(String) action2;
+  bool get needsSources => false;
+  List<DataId> get dependencyDataNeeded => const [];
+  List<DataId> get moduleDataNeeded => [inputId];
+  List<DataId> get resultData => [result1Id, result2Id];
+  final DataId result1Id;
+  final DataId result2Id;
+  final DataId inputId;
+  bool get onlyOnMain => false;
+
+  TwoOutputStep(
+      this.action1, this.action2, this.inputId, this.result1Id, this.result2Id);
+
+  Future<Map<DataId, Object>> execute(Module module,
+      SourceProvider sourceProvider, ModuleDataProvider dataProvider) {
+    var inputData = dataProvider(module, inputId) as String;
+    if (inputData == null)
+      return Future.value({
+        result1Id: "data for $module was null",
+        result2Id: "data for $module was null",
+      });
+    return Future.value(
+        {result1Id: action1(inputData), result2Id: action2(inputData)});
   }
 }
 
@@ -104,17 +155,44 @@
   final DataId inputId;
   final DataId depId;
   final DataId resultId;
+  List<DataId> get resultData => [resultId];
+  bool get onlyOnMain => false;
 
   LinkStep(this.action, this.inputId, this.depId, this.resultId,
       bool requestDependencies)
       : dependencyDataNeeded = requestDependencies ? [depId] : [];
 
-  Future<Object> execute(Module module, SourceProvider sourceProvider,
-      ModuleDataProvider dataProvider) {
+  Future<Map<DataId, Object>> execute(Module module,
+      SourceProvider sourceProvider, ModuleDataProvider dataProvider) {
     List<String> depsData = module.dependencies
         .map((d) => dataProvider(d, depId) as String)
         .toList();
     var inputData = dataProvider(module, inputId) as String;
-    return Future.value(action(inputData, depsData));
+    return Future.value({resultId: action(inputData, depsData)});
+  }
+}
+
+class MainOnlyStep implements MemoryModularStep {
+  bool get needsSources => false;
+  final List<DataId> dependencyDataNeeded;
+  List<DataId> get moduleDataNeeded => [inputId];
+  final String Function(String, List<String>) action;
+  final DataId inputId;
+  final DataId depId;
+  final DataId resultId;
+  List<DataId> get resultData => [resultId];
+  bool get onlyOnMain => true;
+
+  MainOnlyStep(this.action, this.inputId, this.depId, this.resultId,
+      bool requestDependencies)
+      : dependencyDataNeeded = requestDependencies ? [depId] : [];
+
+  Future<Map<DataId, Object>> execute(Module module,
+      SourceProvider sourceProvider, ModuleDataProvider dataProvider) {
+    List<String> depsData = computeTransitiveDependencies(module)
+        .map((d) => dataProvider(d, depId) as String)
+        .toList();
+    var inputData = dataProvider(module, inputId) as String;
+    return Future.value({resultId: action(inputData, depsData)});
   }
 }
diff --git a/pkg/modular_test/test/pipeline_common.dart b/pkg/modular_test/test/pipeline_common.dart
index a01da5c..b09e611 100644
--- a/pkg/modular_test/test/pipeline_common.dart
+++ b/pkg/modular_test/test/pipeline_common.dart
@@ -57,6 +57,28 @@
       DataId resultId,
       bool requestDependenciesData: true});
 
+  /// Create a step that applies [action] only on the main module [inputId] data
+  /// and the the [depId] data of transitive dependencies and finally emits a
+  /// result with the given [resultId].
+  ///
+  /// [depId] may be the same as [inputId] but not [resultId] since this action
+  /// is only applied on the main module.
+  S createMainOnlyStep(
+      {String Function(String, List<String>) action,
+      DataId inputId,
+      DataId depId,
+      DataId resultId,
+      bool requestDependenciesData: true});
+
+  /// Create a step that applies [action1] and [action2] on the module [inputId]
+  /// data, and emits two results with the given [result1Id] and [result2Id].
+  S createTwoOutputStep(
+      {String Function(String) action1,
+      String Function(String) action2,
+      DataId inputId,
+      DataId result1Id,
+      DataId result2Id});
+
   /// Return the result data produced by a modular step.
   String getResult(Pipeline<S> pipeline, Module m, DataId dataId);
 
@@ -72,22 +94,26 @@
     testStrategy.testRootUri.resolve("a2.dart"): 'A2',
     testStrategy.testRootUri.resolve("b/b1.dart"): 'B1',
     testStrategy.testRootUri.resolve("b/b2.dart"): 'B2',
+    testStrategy.testRootUri.resolve("c.dart"): 'C0',
   };
 
   var m1 = Module("a", const [], testStrategy.testRootUri,
-      [Uri.parse("a1.dart"), Uri.parse("a2.dart")], null);
-  var m2 = Module("b", [m1], testStrategy.testRootUri.resolve('b/'),
-      [Uri.parse("b1.dart"), Uri.parse("b2.dart")], null);
+      [Uri.parse("a1.dart"), Uri.parse("a2.dart")]);
+  var m2 = Module("b", [m1], testStrategy.testRootUri,
+      [Uri.parse("b/b1.dart"), Uri.parse("b/b2.dart")]);
+  var m3 = Module("c", [m2], testStrategy.testRootUri, [Uri.parse("c.dart")],
+      isMain: true);
 
   var singleModuleInput = ModularTest([m1], m1);
-  var multipleModulesInput = ModularTest([m1, m2], m2);
+  var twoModuleInput = ModularTest([m1, m2], m2);
+  var threeModuleInput = ModularTest([m1, m2, m3], m3);
 
   test('can read source data if requested', () async {
     var concatStep =
         testStrategy.createSourceOnlyStep(action: _concat, resultId: _concatId);
     var pipeline = await testStrategy.createPipeline(sources, <S>[concatStep]);
     await pipeline.run(singleModuleInput);
-    expect(testStrategy.getResult(pipeline, m1, concatStep.resultId),
+    expect(testStrategy.getResult(pipeline, m1, _concatId),
         "a1.dart: A1\na2.dart: A2\n");
     await testStrategy.cleanup(pipeline);
   });
@@ -97,7 +123,7 @@
         action: _concat, resultId: _concatId, requestSources: false);
     var pipeline = await testStrategy.createPipeline(sources, <S>[concatStep]);
     await pipeline.run(singleModuleInput);
-    expect(testStrategy.getResult(pipeline, m1, concatStep.resultId),
+    expect(testStrategy.getResult(pipeline, m1, _concatId),
         "a1.dart: null\na2.dart: null\n");
     await testStrategy.cleanup(pipeline);
   });
@@ -106,11 +132,11 @@
     var concatStep =
         testStrategy.createSourceOnlyStep(action: _concat, resultId: _concatId);
     var pipeline = await testStrategy.createPipeline(sources, <S>[concatStep]);
-    await pipeline.run(multipleModulesInput);
-    expect(testStrategy.getResult(pipeline, m1, concatStep.resultId),
+    await pipeline.run(twoModuleInput);
+    expect(testStrategy.getResult(pipeline, m1, _concatId),
         "a1.dart: A1\na2.dart: A2\n");
-    expect(testStrategy.getResult(pipeline, m2, concatStep.resultId),
-        "b1.dart: B1\nb2.dart: B2\n");
+    expect(testStrategy.getResult(pipeline, m2, _concatId),
+        "b/b1.dart: B1\nb/b2.dart: B2\n");
     await testStrategy.cleanup(pipeline);
   });
 
@@ -121,11 +147,11 @@
         action: _lowercase, inputId: _concatId, resultId: _lowercaseId);
     var pipeline = await testStrategy
         .createPipeline(sources, <S>[concatStep, lowercaseStep]);
-    await pipeline.run(multipleModulesInput);
-    expect(testStrategy.getResult(pipeline, m1, lowercaseStep.resultId),
+    await pipeline.run(twoModuleInput);
+    expect(testStrategy.getResult(pipeline, m1, _lowercaseId),
         "a1.dart: a1\na2.dart: a2\n");
-    expect(testStrategy.getResult(pipeline, m2, lowercaseStep.resultId),
-        "b1.dart: b1\nb2.dart: b2\n");
+    expect(testStrategy.getResult(pipeline, m2, _lowercaseId),
+        "b/b1.dart: b1\nb/b2.dart: b2\n");
     await testStrategy.cleanup(pipeline);
   });
 
@@ -139,14 +165,33 @@
         requestModuleData: false);
     var pipeline = await testStrategy
         .createPipeline(sources, <S>[concatStep, lowercaseStep]);
-    await pipeline.run(multipleModulesInput);
-    expect(testStrategy.getResult(pipeline, m1, lowercaseStep.resultId),
+    await pipeline.run(twoModuleInput);
+    expect(testStrategy.getResult(pipeline, m1, _lowercaseId),
         "data for [module a] was null");
-    expect(testStrategy.getResult(pipeline, m2, lowercaseStep.resultId),
+    expect(testStrategy.getResult(pipeline, m2, _lowercaseId),
         "data for [module b] was null");
     await testStrategy.cleanup(pipeline);
   });
 
+  test('all outputs of a step are created together', () async {
+    var concatStep =
+        testStrategy.createSourceOnlyStep(action: _concat, resultId: _concatId);
+    var twoOutputStep = testStrategy.createTwoOutputStep(
+        action1: _lowercase,
+        action2: _uppercase,
+        inputId: _concatId,
+        result1Id: _lowercaseId,
+        result2Id: _uppercaseId);
+    var pipeline = await testStrategy
+        .createPipeline(sources, <S>[concatStep, twoOutputStep]);
+    await pipeline.run(twoModuleInput);
+    expect(testStrategy.getResult(pipeline, m2, _lowercaseId),
+        "b/b1.dart: b1\nb/b2.dart: b2\n");
+    expect(testStrategy.getResult(pipeline, m2, _uppercaseId),
+        "B/B1.DART: B1\nB/B2.DART: B2\n");
+    await testStrategy.cleanup(pipeline);
+  });
+
   test('can read same-step results of dependencies if requested', () async {
     var concatStep =
         testStrategy.createSourceOnlyStep(action: _concat, resultId: _concatId);
@@ -159,11 +204,10 @@
         resultId: _joinId);
     var pipeline = await testStrategy.createPipeline(
         sources, <S>[concatStep, lowercaseStep, replaceJoinStep]);
-    await pipeline.run(multipleModulesInput);
-    expect(testStrategy.getResult(pipeline, m1, replaceJoinStep.resultId),
-        "a1 a1\na2 a2\n");
-    expect(testStrategy.getResult(pipeline, m2, replaceJoinStep.resultId),
-        "a1 a1\na2 a2\n\nb1 b1\nb2 b2\n");
+    await pipeline.run(twoModuleInput);
+    expect(testStrategy.getResult(pipeline, m1, _joinId), "a1 a1\na2 a2\n");
+    expect(testStrategy.getResult(pipeline, m2, _joinId),
+        "a1 a1\na2 a2\n\nb/b1 b1\nb/b2 b2\n");
     await testStrategy.cleanup(pipeline);
   });
 
@@ -181,11 +225,10 @@
         requestDependenciesData: false);
     var pipeline = await testStrategy.createPipeline(
         sources, <S>[concatStep, lowercaseStep, replaceJoinStep]);
-    await pipeline.run(multipleModulesInput);
-    expect(testStrategy.getResult(pipeline, m1, replaceJoinStep.resultId),
-        "a1 a1\na2 a2\n");
-    expect(testStrategy.getResult(pipeline, m2, replaceJoinStep.resultId),
-        "null\nb1 b1\nb2 b2\n");
+    await pipeline.run(twoModuleInput);
+    expect(testStrategy.getResult(pipeline, m1, _joinId), "a1 a1\na2 a2\n");
+    expect(testStrategy.getResult(pipeline, m2, _joinId),
+        "null\nb/b1 b1\nb/b2 b2\n");
     await testStrategy.cleanup(pipeline);
   });
 
@@ -201,11 +244,10 @@
         resultId: _joinId);
     var pipeline = await testStrategy.createPipeline(
         sources, <S>[concatStep, lowercaseStep, replaceJoinStep]);
-    await pipeline.run(multipleModulesInput);
-    expect(testStrategy.getResult(pipeline, m1, replaceJoinStep.resultId),
-        "a1 a1\na2 a2\n");
-    expect(testStrategy.getResult(pipeline, m2, replaceJoinStep.resultId),
-        "a1.dart: a1\na2.dart: a2\n\nb1 b1\nb2 b2\n");
+    await pipeline.run(twoModuleInput);
+    expect(testStrategy.getResult(pipeline, m1, _joinId), "a1 a1\na2 a2\n");
+    expect(testStrategy.getResult(pipeline, m2, _joinId),
+        "a1.dart: a1\na2.dart: a2\n\nb/b1 b1\nb/b2 b2\n");
     await testStrategy.cleanup(pipeline);
   });
 
@@ -223,17 +265,56 @@
         requestDependenciesData: false);
     var pipeline = await testStrategy.createPipeline(
         sources, <S>[concatStep, lowercaseStep, replaceJoinStep]);
-    await pipeline.run(multipleModulesInput);
-    expect(testStrategy.getResult(pipeline, m1, replaceJoinStep.resultId),
-        "a1 a1\na2 a2\n");
-    expect(testStrategy.getResult(pipeline, m2, replaceJoinStep.resultId),
-        "null\nb1 b1\nb2 b2\n");
+    await pipeline.run(twoModuleInput);
+    expect(testStrategy.getResult(pipeline, m1, _joinId), "a1 a1\na2 a2\n");
+    expect(testStrategy.getResult(pipeline, m2, _joinId),
+        "null\nb/b1 b1\nb/b2 b2\n");
+    await testStrategy.cleanup(pipeline);
+  });
+
+  test('only main applies to main module', () async {
+    var concatStep =
+        testStrategy.createSourceOnlyStep(action: _concat, resultId: _concatId);
+    var lowercaseStep = testStrategy.createModuleDataStep(
+        action: _lowercase, inputId: _concatId, resultId: _lowercaseId);
+    var replaceJoinStep = testStrategy.createMainOnlyStep(
+        action: _replaceAndJoin,
+        inputId: _lowercaseId,
+        depId: _lowercaseId,
+        resultId: _joinId,
+        requestDependenciesData: true);
+    var pipeline = await testStrategy.createPipeline(
+        sources, <S>[concatStep, lowercaseStep, replaceJoinStep]);
+    await pipeline.run(threeModuleInput);
+    expect(testStrategy.getResult(pipeline, m1, _joinId), null);
+    expect(testStrategy.getResult(pipeline, m3, _joinId),
+        "b/b1.dart: b1\nb/b2.dart: b2\n\na1.dart: a1\na2.dart: a2\n\nc c0\n");
+    await testStrategy.cleanup(pipeline);
+  });
+
+  test('only main also needs to request transitive dependencies', () async {
+    var concatStep =
+        testStrategy.createSourceOnlyStep(action: _concat, resultId: _concatId);
+    var lowercaseStep = testStrategy.createModuleDataStep(
+        action: _lowercase, inputId: _concatId, resultId: _lowercaseId);
+    var replaceJoinStep = testStrategy.createMainOnlyStep(
+        action: _replaceAndJoin,
+        inputId: _lowercaseId,
+        depId: _lowercaseId,
+        resultId: _joinId,
+        requestDependenciesData: false);
+    var pipeline = await testStrategy.createPipeline(
+        sources, <S>[concatStep, lowercaseStep, replaceJoinStep]);
+    await pipeline.run(threeModuleInput);
+    expect(testStrategy.getResult(pipeline, m1, _joinId), null);
+    expect(testStrategy.getResult(pipeline, m3, _joinId), "null\nnull\nc c0\n");
     await testStrategy.cleanup(pipeline);
   });
 }
 
 DataId _concatId = const DataId("concat");
 DataId _lowercaseId = const DataId("lowercase");
+DataId _uppercaseId = const DataId("uppercase");
 DataId _joinId = const DataId("join");
 
 String _concat(Map<Uri, String> sources) {
@@ -245,6 +326,7 @@
 }
 
 String _lowercase(String contents) => contents.toLowerCase();
+String _uppercase(String contents) => contents.toUpperCase();
 
 String _replaceAndJoin(String moduleData, List<String> depContents) {
   var buffer = new StringBuffer();
diff --git a/pkg/modular_test/test/src/find_sdk_root2_test.dart b/pkg/modular_test/test/src/find_sdk_root2_test.dart
new file mode 100644
index 0000000..0bfbeb6
--- /dev/null
+++ b/pkg/modular_test/test/src/find_sdk_root2_test.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:expect/expect.dart';
+import 'package:async_helper/async_helper.dart';
+import 'package:modular_test/src/find_sdk_root.dart';
+
+main() {
+  asyncTest(() async {
+    Expect.equals(Platform.script.resolve("../../../../"), await findRoot());
+  });
+}
diff --git a/pkg/modular_test/test/validate_test.dart b/pkg/modular_test/test/validate_test.dart
index 152271a..8394dfe 100644
--- a/pkg/modular_test/test/validate_test.dart
+++ b/pkg/modular_test/test/validate_test.dart
@@ -18,12 +18,12 @@
     var id3 = DataId("data_c");
     validateSteps([
       ModularStep(
-          needsSources: true, dependencyDataNeeded: [id1], resultId: id1),
-      ModularStep(moduleDataNeeded: [id1], resultId: id2),
+          needsSources: true, dependencyDataNeeded: [id1], resultData: [id1]),
+      ModularStep(moduleDataNeeded: [id1], resultData: [id2]),
       ModularStep(
           moduleDataNeeded: [id2],
           dependencyDataNeeded: [id1, id3],
-          resultId: id3),
+          resultData: [id3]),
     ]);
   });
 
@@ -31,23 +31,31 @@
     var id1 = DataId("data_a");
     expect(
         () => validateSteps([
-              ModularStep(moduleDataNeeded: [id1], resultId: id1),
+              ModularStep(moduleDataNeeded: [id1], resultData: [id1]),
             ]),
         throwsA(TypeMatcher<InvalidPipelineError>()));
   });
 
+  test('some results must be declared', () {
+    expect(() => validateSteps([ModularStep()]),
+        throwsA(TypeMatcher<InvalidPipelineError>()));
+    expect(() => validateSteps([ModularStep(resultData: [])]),
+        throwsA(TypeMatcher<InvalidPipelineError>()));
+  });
+
   test('out of order dependencies are not allowed', () {
     var id1 = DataId("data_a");
     var id2 = DataId("data_b");
     validateSteps([
-      ModularStep(resultId: id1), // id1 must be produced before it is consumed.
-      ModularStep(dependencyDataNeeded: [id1], resultId: id2),
+      // id1 must be produced before it is consumed.
+      ModularStep(resultData: [id1]),
+      ModularStep(dependencyDataNeeded: [id1], resultData: [id2]),
     ]);
 
     expect(
         () => validateSteps([
-              ModularStep(dependencyDataNeeded: [id1], resultId: id2),
-              ModularStep(resultId: id1),
+              ModularStep(dependencyDataNeeded: [id1], resultData: [id2]),
+              ModularStep(resultData: [id1]),
             ]),
         throwsA(TypeMatcher<InvalidPipelineError>()));
   });
@@ -56,8 +64,8 @@
     var id1 = DataId("data_a");
     expect(
         () => validateSteps([
-              ModularStep(resultId: id1),
-              ModularStep(resultId: id1),
+              ModularStep(resultData: [id1]),
+              ModularStep(resultData: [id1]),
             ]),
         throwsA(TypeMatcher<InvalidPipelineError>()));
   });
diff --git a/pkg/pkg.status b/pkg/pkg.status
index 5ad6e12..881f093 100644
--- a/pkg/pkg.status
+++ b/pkg/pkg.status
@@ -130,7 +130,6 @@
 [ $runtime != vm ]
 dev_compiler/test/options/*: SkipByDesign
 front_end/test/hot_reload_e2e_test: Skip
-modular_test/test/io_pipeline_test: SkipByDesign
 vm/test/*: SkipByDesign # Only meant to run on vm
 
 [ $system == linux ]
@@ -177,9 +176,13 @@
 analyzer/test/*: Skip # Issue 26813
 analyzer/tool/*: Skip # Issue 26813
 
-# Analyze dev_compiler but only run its tests on the vm
 [ $compiler != dart2analyzer && $runtime != vm ]
 dev_compiler/test/*: Skip
+modular_test/test/dependency_parser_test: SkipByDesign
+modular_test/test/find_sdk_root1_test: SkipByDesign
+modular_test/test/io_pipeline_test: SkipByDesign
+modular_test/test/loader/loader_test: SkipByDesign
+modular_test/test/src/find_sdk_root2_test: SkipByDesign
 
 [ $compiler == dart2js && $runtime == chrome && $system == macos ]
 third_party/di_tests/di_test: Pass, Slow # Issue 22896
diff --git a/pkg/vm/lib/bytecode/assembler.dart b/pkg/vm/lib/bytecode/assembler.dart
index cfb843e..b71650b 100644
--- a/pkg/vm/lib/bytecode/assembler.dart
+++ b/pkg/vm/lib/bytecode/assembler.dart
@@ -4,8 +4,6 @@
 
 library vm.bytecode.assembler;
 
-import 'dart:typed_data';
-
 import 'package:kernel/ast.dart' show TreeNode;
 
 import 'dbc.dart';
@@ -26,8 +24,8 @@
       if (offset <= jumpOffset && !allowsBackwardJumps) {
         throw 'Backward jump to this label is not allowed';
       }
-      // Jump instruction takes an offset in DBC words.
-      return (offset - jumpOffset) >> BytecodeAssembler.kLog2BytesPerBytecode;
+      // Jump instruction takes a relative offset.
+      return offset - jumpOffset;
     }
     _jumps.add(jumpOffset);
     return 0;
@@ -43,32 +41,30 @@
 }
 
 class BytecodeAssembler {
-  static const int kBitsPerInt = 64;
-  static const int kLog2BytesPerBytecode = 2;
+  static const int kByteMask = 0xFF;
+  static const int kUint32Mask = 0xFFFFFFFF;
+  static const int kMinInt8 = -0x80;
+  static const int kMaxInt8 = 0x7F;
+  static const int kMinInt24 = -0x800000;
+  static const int kMaxInt24 = 0x7FFFFF;
+  static const int kMinInt32 = -0x80000000;
+  static const int kMaxInt32 = 0x7FFFFFFF;
 
   // TODO(alexmarkov): figure out more efficient storage for generated bytecode.
   final List<int> bytecode = new List<int>();
-  final Uint32List _encodeBufferIn;
-  final Uint8List _encodeBufferOut;
   final ExceptionsTable exceptionsTable = new ExceptionsTable();
   final SourcePositions sourcePositions = new SourcePositions();
   bool isUnreachable = false;
   int currentSourcePosition = TreeNode.noOffset;
 
-  BytecodeAssembler._(this._encodeBufferIn, this._encodeBufferOut);
-
-  factory BytecodeAssembler() {
-    final buf = new Uint32List(1);
-    return new BytecodeAssembler._(buf, new Uint8List.view(buf.buffer));
-  }
+  BytecodeAssembler();
 
   int get offset => bytecode.length;
-  int get offsetInWords => bytecode.length >> kLog2BytesPerBytecode;
 
   void bind(Label label) {
     final List<int> jumps = label.bind(offset);
     for (int jumpOffset in jumps) {
-      patchJump(jumpOffset, label.jumpOperand(jumpOffset));
+      _patchJump(jumpOffset, label.jumpOperand(jumpOffset));
     }
     if (jumps.isNotEmpty || label.allowsBackwardJumps) {
       isUnreachable = false;
@@ -77,360 +73,450 @@
 
   void emitSourcePosition() {
     if (currentSourcePosition != TreeNode.noOffset && !isUnreachable) {
-      sourcePositions.add(offsetInWords, currentSourcePosition);
+      sourcePositions.add(offset, currentSourcePosition);
     }
   }
 
-  void emitWord(int word) {
+  void _emitByte(int abyte) {
+    assert(_isUint8(abyte));
+    bytecode.add(abyte);
+  }
+
+  void _emitBytes2(int b0, int b1) {
+    assert(_isUint8(b0) && _isUint8(b1));
+    bytecode.add(b0);
+    bytecode.add(b1);
+  }
+
+  void _emitBytes3(int b0, int b1, int b2) {
+    assert(_isUint8(b0) && _isUint8(b1) && _isUint8(b2));
+    bytecode.add(b0);
+    bytecode.add(b1);
+    bytecode.add(b2);
+  }
+
+  void _emitBytes4(int b0, int b1, int b2, int b3) {
+    assert(_isUint8(b0) && _isUint8(b1) && _isUint8(b2) && _isUint8(b3));
+    bytecode.add(b0);
+    bytecode.add(b1);
+    bytecode.add(b2);
+    bytecode.add(b3);
+  }
+
+  void _emitBytes5(int b0, int b1, int b2, int b3, int b4) {
+    assert(_isUint8(b0) &&
+        _isUint8(b1) &&
+        _isUint8(b2) &&
+        _isUint8(b3) &&
+        _isUint8(b4));
+    bytecode.add(b0);
+    bytecode.add(b1);
+    bytecode.add(b2);
+    bytecode.add(b3);
+    bytecode.add(b4);
+  }
+
+  void _emitBytes6(int b0, int b1, int b2, int b3, int b4, int b5) {
+    assert(_isUint8(b0) &&
+        _isUint8(b1) &&
+        _isUint8(b2) &&
+        _isUint8(b3) &&
+        _isUint8(b4) &&
+        _isUint8(b5));
+    bytecode.add(b0);
+    bytecode.add(b1);
+    bytecode.add(b2);
+    bytecode.add(b3);
+    bytecode.add(b4);
+    bytecode.add(b5);
+  }
+
+  int _byteAt(int pos) {
+    return bytecode[pos];
+  }
+
+  void _setByteAt(int pos, int value) {
+    assert(_isUint8(value));
+    bytecode[pos] = value;
+  }
+
+  int _byte0(int v) => v & kByteMask;
+  int _byte1(int v) => (v >> 8) & kByteMask;
+  int _byte2(int v) => (v >> 16) & kByteMask;
+  int _byte3(int v) => (v >> 24) & kByteMask;
+
+  bool _isInt8(int v) => (kMinInt8 <= v) && (v <= kMaxInt8);
+  bool _isInt24(int v) => (kMinInt24 <= v) && (v <= kMaxInt24);
+  bool _isInt32(int v) => (kMinInt32 <= v) && (v <= kMaxInt32);
+  bool _isUint8(int v) => (v & kByteMask) == v;
+  bool _isUint32(int v) => (v & kUint32Mask) == v;
+
+  void _emitInstruction0(Opcode opcode) {
     if (isUnreachable) {
       return;
     }
-    _encodeBufferIn[0] = word; // TODO(alexmarkov): Which endianness to use?
-    bytecode.addAll(_encodeBufferOut);
+    _emitByte(opcode.index);
   }
 
-  int _getOpcodeAt(int pos) {
-    return bytecode[pos]; // TODO(alexmarkov): Take endianness into account.
-  }
-
-  void _setWord(int pos, int word) {
-    _encodeBufferIn[0] = word; // TODO(alexmarkov): Which endianness to use?
-    bytecode.setRange(pos, pos + _encodeBufferOut.length, _encodeBufferOut);
-  }
-
-  int _unsigned(int v, int bits) {
-    assert(bits < kBitsPerInt);
-    final int mask = (1 << bits) - 1;
-    if ((v & mask) != v) {
-      throw 'Value $v is out of unsigned $bits-bit range';
+  void _emitInstructionA(Opcode opcode, int ra) {
+    if (isUnreachable) {
+      return;
     }
-    return v;
+    _emitBytes2(opcode.index, ra);
   }
 
-  int _signed(int v, int bits) {
-    assert(bits < kBitsPerInt);
-    final int shift = kBitsPerInt - bits;
-    if (((v << shift) >> shift) != v) {
-      throw 'Value $v is out of signed $bits-bit range';
+  void _emitInstructionD(Opcode opcode, int rd) {
+    if (isUnreachable) {
+      return;
     }
-    final int mask = (1 << bits) - 1;
-    return v & mask;
+    if (_isUint8(rd)) {
+      _emitBytes2(opcode.index, rd);
+    } else {
+      assert(_isUint32(rd));
+      _emitBytes5(opcode.index + kWideModifier, _byte0(rd), _byte1(rd),
+          _byte2(rd), _byte3(rd));
+    }
   }
 
-  int _uint8(int v) => _unsigned(v, 8);
-  int _uint16(int v) => _unsigned(v, 16);
+  void _emitInstructionX(Opcode opcode, int rx) {
+    if (isUnreachable) {
+      return;
+    }
+    if (_isInt8(rx)) {
+      _emitBytes2(opcode.index, rx & kByteMask);
+    } else {
+      assert(_isInt32(rx));
+      _emitBytes5(opcode.index + kWideModifier, _byte0(rx), _byte1(rx),
+          _byte2(rx), _byte3(rx));
+    }
+  }
 
-//  int _int8(int v) => _signed(v, 8);
-  int _int16(int v) => _signed(v, 16);
-  int _int24(int v) => _signed(v, 24);
+  void _emitInstructionAE(Opcode opcode, int ra, int re) {
+    if (isUnreachable) {
+      return;
+    }
+    if (_isUint8(re)) {
+      _emitBytes3(opcode.index, ra, re);
+    } else {
+      assert(_isUint32(re));
+      _emitBytes6(opcode.index + kWideModifier, ra, _byte0(re), _byte1(re),
+          _byte2(re), _byte3(re));
+    }
+  }
 
-  int _encode0(Opcode opcode) => _uint8(opcode.index);
+  void _emitInstructionAY(Opcode opcode, int ra, int ry) {
+    if (isUnreachable) {
+      return;
+    }
+    if (_isInt8(ry)) {
+      _emitBytes3(opcode.index, ra, ry & kByteMask);
+    } else {
+      assert(_isInt32(ry));
+      _emitBytes6(opcode.index + kWideModifier, ra, _byte0(ry), _byte1(ry),
+          _byte2(ry), _byte3(ry));
+    }
+  }
 
-  int _encodeA(Opcode opcode, int ra) =>
-      _uint8(opcode.index) | (_uint8(ra) << 8);
+  void _emitInstructionDF(Opcode opcode, int rd, int rf) {
+    if (isUnreachable) {
+      return;
+    }
+    if (_isUint8(rd)) {
+      _emitBytes3(opcode.index, rd, rf);
+    } else {
+      assert(_isUint32(rd));
+      _emitBytes6(opcode.index + kWideModifier, _byte0(rd), _byte1(rd),
+          _byte2(rd), _byte3(rd), rf);
+    }
+  }
 
-  int _encodeAD(Opcode opcode, int ra, int rd) =>
-      _uint8(opcode.index) | (_uint8(ra) << 8) | (_uint16(rd) << 16);
+  void _emitInstructionABC(Opcode opcode, int ra, int rb, int rc) {
+    if (isUnreachable) {
+      return;
+    }
+    _emitBytes4(opcode.index, ra, rb, rc);
+  }
 
-  int _encodeAX(Opcode opcode, int ra, int rx) =>
-      _uint8(opcode.index) | (_uint8(ra) << 8) | (_int16(rx) << 16);
-
-  int _encodeD(Opcode opcode, int rd) =>
-      _uint8(opcode.index) | (_uint16(rd) << 16);
-
-  int _encodeX(Opcode opcode, int rx) =>
-      _uint8(opcode.index) | (_int16(rx) << 16);
-
-  int _encodeABC(Opcode opcode, int ra, int rb, int rc) =>
-      _uint8(opcode.index) |
-      (_uint8(ra) << 8) |
-      (_uint8(rb) << 16) |
-      (_uint8(rc) << 24);
-
-// TODO(alexmarkov) This format is currently unused. Restore it if needed, or
-// remove it once bytecode instruction set is finalized.
-//
-//  int _encodeABY(Opcode opcode, int ra, int rb, int ry) =>
-//      _uint8(opcode.index) |
-//      (_uint8(ra) << 8) |
-//      (_uint8(rb) << 16) |
-//      (_int8(ry) << 24);
-
-  int _encodeT(Opcode opcode, int rt) =>
-      _uint8(opcode.index) | (_int24(rt) << 8);
-
-  void emitBytecode0(Opcode opcode) {
+  void emitSpecializedBytecode(Opcode opcode) {
     assert(BytecodeFormats[opcode].encoding == Encoding.k0);
     emitSourcePosition();
-    emitWord(_encode0(opcode));
+    _emitInstruction0(opcode);
   }
 
-  void _emitJumpBytecode(Opcode opcode, Label label) {
+  void _emitJumpInstruction(Opcode opcode, Label label) {
     assert(isJump(opcode));
-    if (!isUnreachable) {
-      // Do not use label if not generating instruction.
-      emitWord(_encodeT(opcode, label.jumpOperand(offset)));
+    if (isUnreachable) {
+      return;
     }
+    final int target = label.jumpOperand(offset);
+    // Use compact representation only for backwards jumps.
+    // TODO(alexmarkov): generate compact forward jumps as well.
+    if (label.isBound && _isInt8(target)) {
+      _emitBytes2(opcode.index, target & kByteMask);
+    } else {
+      assert(_isInt24(target));
+      _emitBytes4(opcode.index + kWideModifier, _byte0(target), _byte1(target),
+          _byte2(target));
+    }
+  }
+
+  void _patchJump(int pos, int rt) {
+    final Opcode opcode = Opcode.values[_byteAt(pos) - kWideModifier];
+    assert(hasWideVariant(opcode));
+    assert(isJump(opcode));
+    assert(_isInt24(rt));
+    _setByteAt(pos + 1, _byte0(rt));
+    _setByteAt(pos + 2, _byte1(rt));
+    _setByteAt(pos + 3, _byte2(rt));
   }
 
   void emitTrap() {
-    emitWord(_encode0(Opcode.kTrap));
+    _emitInstruction0(Opcode.kTrap);
     isUnreachable = true;
   }
 
   void emitDrop1() {
-    emitWord(_encode0(Opcode.kDrop1));
+    _emitInstruction0(Opcode.kDrop1);
   }
 
   void emitJump(Label label) {
-    _emitJumpBytecode(Opcode.kJump, label);
+    _emitJumpInstruction(Opcode.kJump, label);
     isUnreachable = true;
   }
 
   void emitJumpIfNoAsserts(Label label) {
-    _emitJumpBytecode(Opcode.kJumpIfNoAsserts, label);
+    _emitJumpInstruction(Opcode.kJumpIfNoAsserts, label);
   }
 
   void emitJumpIfNotZeroTypeArgs(Label label) {
-    _emitJumpBytecode(Opcode.kJumpIfNotZeroTypeArgs, label);
+    _emitJumpInstruction(Opcode.kJumpIfNotZeroTypeArgs, label);
   }
 
   void emitJumpIfEqStrict(Label label) {
-    _emitJumpBytecode(Opcode.kJumpIfEqStrict, label);
+    _emitJumpInstruction(Opcode.kJumpIfEqStrict, label);
   }
 
   void emitJumpIfNeStrict(Label label) {
-    _emitJumpBytecode(Opcode.kJumpIfNeStrict, label);
+    _emitJumpInstruction(Opcode.kJumpIfNeStrict, label);
   }
 
   void emitJumpIfTrue(Label label) {
-    _emitJumpBytecode(Opcode.kJumpIfTrue, label);
+    _emitJumpInstruction(Opcode.kJumpIfTrue, label);
   }
 
   void emitJumpIfFalse(Label label) {
-    _emitJumpBytecode(Opcode.kJumpIfFalse, label);
+    _emitJumpInstruction(Opcode.kJumpIfFalse, label);
   }
 
   void emitJumpIfNull(Label label) {
-    _emitJumpBytecode(Opcode.kJumpIfNull, label);
+    _emitJumpInstruction(Opcode.kJumpIfNull, label);
   }
 
   void emitJumpIfNotNull(Label label) {
-    _emitJumpBytecode(Opcode.kJumpIfNotNull, label);
-  }
-
-  void patchJump(int pos, int rt) {
-    final Opcode opcode = Opcode.values[_getOpcodeAt(pos)];
-    assert(isJump(opcode));
-    _setWord(pos, _encodeT(opcode, rt));
+    _emitJumpInstruction(Opcode.kJumpIfNotNull, label);
   }
 
   void emitReturnTOS() {
-    emitWord(_encode0(Opcode.kReturnTOS));
+    _emitInstruction0(Opcode.kReturnTOS);
     isUnreachable = true;
   }
 
   void emitPush(int rx) {
-    emitWord(_encodeX(Opcode.kPush, rx));
+    _emitInstructionX(Opcode.kPush, rx);
   }
 
-  void emitLoadConstant(int ra, int rd) {
-    emitWord(_encodeAD(Opcode.kLoadConstant, ra, rd));
+  void emitLoadConstant(int ra, int re) {
+    _emitInstructionAE(Opcode.kLoadConstant, ra, re);
   }
 
   void emitPushConstant(int rd) {
-    emitWord(_encodeD(Opcode.kPushConstant, rd));
+    _emitInstructionD(Opcode.kPushConstant, rd);
   }
 
   void emitPushNull() {
-    emitWord(_encode0(Opcode.kPushNull));
+    _emitInstruction0(Opcode.kPushNull);
   }
 
   void emitPushTrue() {
-    emitWord(_encode0(Opcode.kPushTrue));
+    _emitInstruction0(Opcode.kPushTrue);
   }
 
   void emitPushFalse() {
-    emitWord(_encode0(Opcode.kPushFalse));
+    _emitInstruction0(Opcode.kPushFalse);
   }
 
   void emitPushInt(int rx) {
-    emitWord(_encodeX(Opcode.kPushInt, rx));
+    _emitInstructionX(Opcode.kPushInt, rx);
   }
 
   void emitStoreLocal(int rx) {
-    emitWord(_encodeX(Opcode.kStoreLocal, rx));
+    _emitInstructionX(Opcode.kStoreLocal, rx);
   }
 
   void emitPopLocal(int rx) {
-    emitWord(_encodeX(Opcode.kPopLocal, rx));
+    _emitInstructionX(Opcode.kPopLocal, rx);
   }
 
-  void emitIndirectStaticCall(int ra, int rd) {
+  void emitDirectCall(int rd, int rf) {
     emitSourcePosition();
-    emitWord(_encodeAD(Opcode.kIndirectStaticCall, ra, rd));
+    _emitInstructionDF(Opcode.kDirectCall, rd, rf);
   }
 
-  void emitDirectCall(int ra, int rd) {
+  void emitInterfaceCall(int rd, int rf) {
     emitSourcePosition();
-    emitWord(_encodeAD(Opcode.kDirectCall, ra, rd));
+    _emitInstructionDF(Opcode.kInterfaceCall, rd, rf);
   }
 
-  void emitInterfaceCall(int ra, int rd) {
+  void emitUncheckedInterfaceCall(int rd, int rf) {
     emitSourcePosition();
-    emitWord(_encodeAD(Opcode.kInterfaceCall, ra, rd));
+    _emitInstructionDF(Opcode.kUncheckedInterfaceCall, rd, rf);
   }
 
-  void emitUncheckedInterfaceCall(int ra, int rd) {
+  void emitDynamicCall(int rd, int rf) {
     emitSourcePosition();
-    emitWord(_encodeAD(Opcode.kUncheckedInterfaceCall, ra, rd));
-  }
-
-  void emitDynamicCall(int ra, int rd) {
-    emitSourcePosition();
-    emitWord(_encodeAD(Opcode.kDynamicCall, ra, rd));
+    _emitInstructionDF(Opcode.kDynamicCall, rd, rf);
   }
 
   void emitNativeCall(int rd) {
     emitSourcePosition();
-    emitWord(_encodeD(Opcode.kNativeCall, rd));
+    _emitInstructionD(Opcode.kNativeCall, rd);
   }
 
   void emitStoreStaticTOS(int rd) {
     emitSourcePosition();
-    emitWord(_encodeD(Opcode.kStoreStaticTOS, rd));
+    _emitInstructionD(Opcode.kStoreStaticTOS, rd);
   }
 
   void emitPushStatic(int rd) {
-    emitWord(_encodeD(Opcode.kPushStatic, rd));
+    _emitInstructionD(Opcode.kPushStatic, rd);
   }
 
   void emitCreateArrayTOS() {
-    emitWord(_encode0(Opcode.kCreateArrayTOS));
+    _emitInstruction0(Opcode.kCreateArrayTOS);
   }
 
   void emitAllocate(int rd) {
     emitSourcePosition();
-    emitWord(_encodeD(Opcode.kAllocate, rd));
+    _emitInstructionD(Opcode.kAllocate, rd);
   }
 
   void emitAllocateT() {
     emitSourcePosition();
-    emitWord(_encode0(Opcode.kAllocateT));
+    _emitInstruction0(Opcode.kAllocateT);
   }
 
   void emitStoreIndexedTOS() {
-    emitWord(_encode0(Opcode.kStoreIndexedTOS));
+    _emitInstruction0(Opcode.kStoreIndexedTOS);
   }
 
   void emitStoreFieldTOS(int rd) {
     emitSourcePosition();
-    emitWord(_encodeD(Opcode.kStoreFieldTOS, rd));
+    _emitInstructionD(Opcode.kStoreFieldTOS, rd);
   }
 
   void emitStoreContextParent() {
-    emitWord(_encode0(Opcode.kStoreContextParent));
+    _emitInstruction0(Opcode.kStoreContextParent);
   }
 
-  void emitStoreContextVar(int ra, int rd) {
-    emitWord(_encodeAD(Opcode.kStoreContextVar, ra, rd));
+  void emitStoreContextVar(int ra, int re) {
+    _emitInstructionAE(Opcode.kStoreContextVar, ra, re);
   }
 
   void emitLoadFieldTOS(int rd) {
-    emitWord(_encodeD(Opcode.kLoadFieldTOS, rd));
+    _emitInstructionD(Opcode.kLoadFieldTOS, rd);
   }
 
   void emitLoadTypeArgumentsField(int rd) {
-    emitWord(_encodeD(Opcode.kLoadTypeArgumentsField, rd));
+    _emitInstructionD(Opcode.kLoadTypeArgumentsField, rd);
   }
 
   void emitLoadContextParent() {
-    emitWord(_encode0(Opcode.kLoadContextParent));
+    _emitInstruction0(Opcode.kLoadContextParent);
   }
 
-  void emitLoadContextVar(int ra, int rd) {
-    emitWord(_encodeAD(Opcode.kLoadContextVar, ra, rd));
+  void emitLoadContextVar(int ra, int re) {
+    _emitInstructionAE(Opcode.kLoadContextVar, ra, re);
   }
 
   void emitBooleanNegateTOS() {
-    emitWord(_encode0(Opcode.kBooleanNegateTOS));
+    _emitInstruction0(Opcode.kBooleanNegateTOS);
   }
 
   void emitThrow(int ra) {
     emitSourcePosition();
-    emitWord(_encodeA(Opcode.kThrow, ra));
+    _emitInstructionA(Opcode.kThrow, ra);
     isUnreachable = true;
   }
 
   void emitEntry(int rd) {
-    emitWord(_encodeD(Opcode.kEntry, rd));
+    _emitInstructionD(Opcode.kEntry, rd);
   }
 
   void emitFrame(int rd) {
-    emitWord(_encodeD(Opcode.kFrame, rd));
+    _emitInstructionD(Opcode.kFrame, rd);
   }
 
   void emitSetFrame(int ra) {
-    emitWord(_encodeA(Opcode.kSetFrame, ra));
+    _emitInstructionA(Opcode.kSetFrame, ra);
   }
 
-  void emitAllocateContext(int ra, int rd) {
-    emitWord(_encodeAD(Opcode.kAllocateContext, ra, rd));
+  void emitAllocateContext(int ra, int re) {
+    _emitInstructionAE(Opcode.kAllocateContext, ra, re);
   }
 
-  void emitCloneContext(int ra, int rd) {
-    emitWord(_encodeAD(Opcode.kCloneContext, ra, rd));
+  void emitCloneContext(int ra, int re) {
+    _emitInstructionAE(Opcode.kCloneContext, ra, re);
   }
 
-  void emitMoveSpecial(SpecialIndex ra, int rx) {
-    emitWord(_encodeAX(Opcode.kMoveSpecial, ra.index, rx));
+  void emitMoveSpecial(SpecialIndex ra, int ry) {
+    _emitInstructionAY(Opcode.kMoveSpecial, ra.index, ry);
   }
 
   void emitInstantiateType(int rd) {
     emitSourcePosition();
-    emitWord(_encodeD(Opcode.kInstantiateType, rd));
+    _emitInstructionD(Opcode.kInstantiateType, rd);
   }
 
-  void emitInstantiateTypeArgumentsTOS(int ra, int rd) {
+  void emitInstantiateTypeArgumentsTOS(int ra, int re) {
     emitSourcePosition();
-    emitWord(_encodeAD(Opcode.kInstantiateTypeArgumentsTOS, ra, rd));
+    _emitInstructionAE(Opcode.kInstantiateTypeArgumentsTOS, ra, re);
   }
 
-  void emitAssertAssignable(int ra, int rd) {
+  void emitAssertAssignable(int ra, int re) {
     emitSourcePosition();
-    emitWord(_encodeAD(Opcode.kAssertAssignable, ra, rd));
+    _emitInstructionAE(Opcode.kAssertAssignable, ra, re);
   }
 
   void emitAssertSubtype() {
     emitSourcePosition();
-    emitWord(_encode0(Opcode.kAssertSubtype));
+    _emitInstruction0(Opcode.kAssertSubtype);
   }
 
   void emitAssertBoolean(int ra) {
     emitSourcePosition();
-    emitWord(_encodeA(Opcode.kAssertBoolean, ra));
+    _emitInstructionA(Opcode.kAssertBoolean, ra);
   }
 
   void emitCheckStack(int ra) {
     emitSourcePosition();
-    emitWord(_encodeA(Opcode.kCheckStack, ra));
+    _emitInstructionA(Opcode.kCheckStack, ra);
   }
 
-  void emitCheckFunctionTypeArgs(int ra, int rd) {
+  void emitCheckFunctionTypeArgs(int ra, int re) {
     emitSourcePosition();
-    emitWord(_encodeAD(Opcode.kCheckFunctionTypeArgs, ra, rd));
+    _emitInstructionAE(Opcode.kCheckFunctionTypeArgs, ra, re);
   }
 
-  void emitEntryFixed(int ra, int rd) {
-    emitWord(_encodeAD(Opcode.kEntryFixed, ra, rd));
+  void emitEntryFixed(int ra, int re) {
+    _emitInstructionAE(Opcode.kEntryFixed, ra, re);
   }
 
   void emitEntryOptional(int ra, int rb, int rc) {
-    emitWord(_encodeABC(Opcode.kEntryOptional, ra, rb, rc));
+    _emitInstructionABC(Opcode.kEntryOptional, ra, rb, rc);
   }
 
   void emitAllocateClosure(int rd) {
     emitSourcePosition();
-    emitWord(_encodeD(Opcode.kAllocateClosure, rd));
+    _emitInstructionD(Opcode.kAllocateClosure, rd);
   }
 }
diff --git a/pkg/vm/lib/bytecode/dbc.dart b/pkg/vm/lib/bytecode/dbc.dart
index 730ee69..2ee6f20 100644
--- a/pkg/vm/lib/bytecode/dbc.dart
+++ b/pkg/vm/lib/bytecode/dbc.dart
@@ -10,99 +10,299 @@
 /// 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 = 6;
+const int currentBytecodeFormatVersion = 7;
 
 /// Version of experimental / bleeding edge bytecode format.
 /// Produced by bytecode generator when --use-future-bytecode-format
 /// option is enabled.
 const int futureBytecodeFormatVersion = currentBytecodeFormatVersion + 1;
 
-/// Alignment of bytecode instructions.
-const int bytecodeInstructionsAlignment = 4;
-
 enum Opcode {
+  // Old instructions, used before bytecode v7.
+  // TODO(alexmarkov): remove
+
+  kTrap_Old,
+
+  // Prologue and stack management.
+  kEntry_Old,
+  kEntryFixed_Old,
+  kEntryOptional_Old,
+  kLoadConstant_Old,
+  kFrame_Old,
+  kCheckFunctionTypeArgs_Old,
+  kCheckStack_Old,
+
+  // Object allocation.
+  kAllocate_Old,
+  kAllocateT_Old,
+  kCreateArrayTOS_Old,
+
+  // Context allocation and access.
+  kAllocateContext_Old,
+  kCloneContext_Old,
+  kLoadContextParent_Old,
+  kStoreContextParent_Old,
+  kLoadContextVar_Old,
+  kStoreContextVar_Old,
+
+  // Constants.
+  kPushConstant_Old,
+  kPushNull_Old,
+  kPushTrue_Old,
+  kPushFalse_Old,
+  kPushInt_Old,
+
+  // Locals and expression stack.
+  kDrop1_Old,
+  kPush_Old,
+  kPopLocal_Old,
+  kStoreLocal_Old,
+
+  // Instance fields and arrays.
+  kLoadFieldTOS_Old,
+  kStoreFieldTOS_Old,
+  kStoreIndexedTOS_Old,
+
+  // Static fields.
+  kPushStatic_Old,
+  kStoreStaticTOS_Old,
+
+  // Jumps.
+  kJump_Old,
+  kJumpIfNoAsserts_Old,
+  kJumpIfNotZeroTypeArgs_Old,
+  kJumpIfEqStrict_Old,
+  kJumpIfNeStrict_Old,
+  kJumpIfTrue_Old,
+  kJumpIfFalse_Old,
+  kJumpIfNull_Old,
+  kJumpIfNotNull_Old,
+
+  // Calls.
+  kUnused00_Old,
+  kInterfaceCall_Old,
+  kDynamicCall_Old,
+  kNativeCall_Old,
+  kReturnTOS_Old,
+
+  // Types and type checks.
+  kAssertAssignable_Old,
+  kAssertBoolean_Old,
+  kAssertSubtype_Old,
+  kLoadTypeArgumentsField_Old,
+  kInstantiateType_Old,
+  kInstantiateTypeArgumentsTOS_Old,
+
+  // Exception handling.
+  kThrow_Old,
+  kMoveSpecial_Old,
+  kSetFrame_Old,
+
+  // Bool operations.
+  kBooleanNegateTOS_Old,
+
+  // Null operations.
+  kEqualsNull_Old,
+
+  // Int operations.
+  kNegateInt_Old,
+  kAddInt_Old,
+  kSubInt_Old,
+  kMulInt_Old,
+  kTruncDivInt_Old,
+  kModInt_Old,
+  kBitAndInt_Old,
+  kBitOrInt_Old,
+  kBitXorInt_Old,
+  kShlInt_Old,
+  kShrInt_Old,
+  kCompareIntEq_Old,
+  kCompareIntGt_Old,
+  kCompareIntLt_Old,
+  kCompareIntGe_Old,
+  kCompareIntLe_Old,
+
+  kDirectCall_Old,
+
+  kAllocateClosure_Old,
+
+  kUncheckedInterfaceCall_Old,
+
+  // Double operations.
+  kNegateDouble_Old,
+  kAddDouble_Old,
+  kSubDouble_Old,
+  kMulDouble_Old,
+  kDivDouble_Old,
+  kCompareDoubleEq_Old,
+  kCompareDoubleGt_Old,
+  kCompareDoubleLt_Old,
+  kCompareDoubleGe_Old,
+  kCompareDoubleLe_Old,
+
+  // Bytecode instructions since bytecode format v7:
+
   kTrap,
 
   // Prologue and stack management.
   kEntry,
+  kEntry_Wide,
   kEntryFixed,
+  kEntryFixed_Wide,
   kEntryOptional,
+  kUnused00, // Reserved for EntryNoLocals.
   kLoadConstant,
+  kLoadConstant_Wide,
   kFrame,
+  kFrame_Wide,
   kCheckFunctionTypeArgs,
+  kCheckFunctionTypeArgs_Wide,
   kCheckStack,
+  kUnused01,
+  kUnused02, // Reserved for CheckParameterTypes
+  kUnused03, // Reserved for CheckParameterTypes_Wide
 
   // Object allocation.
   kAllocate,
+  kAllocate_Wide,
   kAllocateT,
   kCreateArrayTOS,
+  kAllocateClosure,
+  kAllocateClosure_Wide,
 
   // Context allocation and access.
   kAllocateContext,
+  kAllocateContext_Wide,
   kCloneContext,
+  kCloneContext_Wide,
   kLoadContextParent,
   kStoreContextParent,
   kLoadContextVar,
+  kLoadContextVar_Wide,
+  kUnused04, // Reserved for LoadContextVar0
+  kUnused05,
   kStoreContextVar,
+  kStoreContextVar_Wide,
 
   // Constants.
   kPushConstant,
-  kPushNull,
+  kPushConstant_Wide,
+  kUnused06, // Reserved for PushConstant0
+  kUnused07,
   kPushTrue,
   kPushFalse,
   kPushInt,
+  kPushInt_Wide,
+  kUnused08, // Reserved for PushInt0
+  kUnused09, // Reserved for PushInt1
+  kUnused10, // Reserved for PushInt2
+  kUnused11,
+  kPushNull,
 
   // Locals and expression stack.
   kDrop1,
   kPush,
+  kPush_Wide,
+  kUnused12, // Reserved for PushLocal0
+  kUnused13, // Reserved for PushLocal1
+  kUnused14, // Reserved for PushLocal2
+  kUnused15, // Reserved for PushLocal3
+  kUnused16, // Reserved for PushParamLast0
+  kUnused17, // Reserved for PushParamLast1
   kPopLocal,
+  kPopLocal_Wide,
+  kUnused18, // Reserved for PopLocal0
+  kUnused19,
   kStoreLocal,
+  kStoreLocal_Wide,
 
   // Instance fields and arrays.
   kLoadFieldTOS,
+  kLoadFieldTOS_Wide,
   kStoreFieldTOS,
+  kStoreFieldTOS_Wide,
   kStoreIndexedTOS,
+  kUnused20,
 
   // Static fields.
   kPushStatic,
+  kPushStatic_Wide,
   kStoreStaticTOS,
+  kStoreStaticTOS_Wide,
 
   // Jumps.
   kJump,
+  kJump_Wide,
   kJumpIfNoAsserts,
+  kJumpIfNoAsserts_Wide,
   kJumpIfNotZeroTypeArgs,
+  kJumpIfNotZeroTypeArgs_Wide,
   kJumpIfEqStrict,
+  kJumpIfEqStrict_Wide,
   kJumpIfNeStrict,
+  kJumpIfNeStrict_Wide,
   kJumpIfTrue,
+  kJumpIfTrue_Wide,
   kJumpIfFalse,
+  kJumpIfFalse_Wide,
   kJumpIfNull,
+  kJumpIfNull_Wide,
   kJumpIfNotNull,
+  kJumpIfNotNull_Wide,
 
   // Calls.
-  kIndirectStaticCall,
+  kDirectCall,
+  kDirectCall_Wide,
+  kUnused21, // Reserved for DirectCall1
+  kUnused22, // Reserved for DirectCall1_Wide
   kInterfaceCall,
+  kInterfaceCall_Wide,
+  kUnused23, // Reserved for InterfaceCall1
+  kUnused24, // Reserved for InterfaceCall1_Wide
+  kUnused25, // Reserved for InterfaceCall2
+  kUnused26, // Reserved for InterfaceCall2_Wide
+  kUnused27, // Reserved for InterfaceCall3
+  kUnused28, // Reserved for InterfaceCall3_Wide
+  kUncheckedInterfaceCall,
+  kUncheckedInterfaceCall_Wide,
   kDynamicCall,
+  kDynamicCall_Wide,
   kNativeCall,
+  kNativeCall_Wide,
   kReturnTOS,
+  kUnused29,
 
   // Types and type checks.
   kAssertAssignable,
+  kAssertAssignable_Wide,
+  kUnused30, // Reserved for AsSimpleType
+  kUnused31, // Reserved for AsSimpleType_Wide
   kAssertBoolean,
   kAssertSubtype,
   kLoadTypeArgumentsField,
+  kLoadTypeArgumentsField_Wide,
   kInstantiateType,
+  kInstantiateType_Wide,
   kInstantiateTypeArgumentsTOS,
+  kInstantiateTypeArgumentsTOS_Wide,
+  kUnused32, // Reserved for IsType
+  kUnused33, // Reserved for IsType_Wide
+  kUnused34, // Reserved for IsSimpleType
+  kUnused35, // Reserved for IsSimpleType_Wide
 
   // Exception handling.
   kThrow,
-  kMoveSpecial,
   kSetFrame,
+  kMoveSpecial,
+  kMoveSpecial_Wide,
 
   // Bool operations.
   kBooleanNegateTOS,
 
   // Null operations.
   kEqualsNull,
+  kUnused36, // Reserved for CheckNull
+  kUnused37, // Reserved for CheckNull_Wide
 
   // Int operations.
   kNegateInt,
@@ -122,12 +322,6 @@
   kCompareIntGe,
   kCompareIntLe,
 
-  kDirectCall,
-
-  kAllocateClosure,
-
-  kUncheckedInterfaceCall,
-
   // Double operations.
   kNegateDouble,
   kAddDouble,
@@ -141,16 +335,47 @@
   kCompareDoubleLe,
 }
 
+/// Compact variants of opcodes are always even.
+/// Wide variant = opcode + kWideModifier.
+const int kWideModifier = 1;
+
+/// Opcode should fit into 1 byte.
+const int kMaxOpcodes = 256;
+
 enum Encoding {
-  k0,
-  kA,
-  kAD,
-  kAX,
-  kD,
-  kX,
-  kABC,
-  kABY,
-  kT,
+  k0, // No operands.
+  kA, // 1 operand: A = 8-bit unsigned.
+  kD, // 1 operand: D = 8/32-bit unsigned.
+  kX, // 1 operand: X = 8/32-bit signed.
+  kT, // 1 operand: T = 8/24-bit signed.
+  kAE, // 2 operands: A = 8-bit unsigned, E = 8/32-bit unsigned
+  kAY, // 2 operands: A = 8-bit unsigned, Y = 8/32-bit signed
+  kDF, // 2 operands: D = 8/32-bit unsigned, F = 8-bit unsigned
+  kABC, // 3 operands: A, B, C - 8-bit unsigned.
+}
+
+int instructionSize(Encoding encoding, bool isWide) {
+  switch (encoding) {
+    case Encoding.k0:
+      return 1;
+    case Encoding.kA:
+      return 2;
+    case Encoding.kD:
+      return isWide ? 5 : 2;
+    case Encoding.kX:
+      return isWide ? 5 : 2;
+    case Encoding.kT:
+      return isWide ? 4 : 2;
+    case Encoding.kAE:
+      return isWide ? 6 : 3;
+    case Encoding.kAY:
+      return isWide ? 6 : 3;
+    case Encoding.kDF:
+      return isWide ? 6 : 3;
+    case Encoding.kABC:
+      return 4;
+  }
+  throw 'Unexpected instruction encoding $encoding';
 }
 
 enum Operand {
@@ -175,15 +400,15 @@
   Opcode.kEntry: const Format(
       Encoding.kD, const [Operand.imm, Operand.none, Operand.none]),
   Opcode.kEntryFixed: const Format(
-      Encoding.kAD, const [Operand.imm, Operand.imm, Operand.none]),
+      Encoding.kAE, const [Operand.imm, Operand.imm, Operand.none]),
   Opcode.kEntryOptional: const Format(
       Encoding.kABC, const [Operand.imm, Operand.imm, Operand.imm]),
   Opcode.kLoadConstant: const Format(
-      Encoding.kAD, const [Operand.reg, Operand.lit, Operand.none]),
+      Encoding.kAE, const [Operand.reg, Operand.lit, Operand.none]),
   Opcode.kFrame: const Format(
       Encoding.kD, const [Operand.imm, Operand.none, Operand.none]),
   Opcode.kCheckFunctionTypeArgs: const Format(
-      Encoding.kAD, const [Operand.imm, Operand.reg, Operand.none]),
+      Encoding.kAE, const [Operand.imm, Operand.reg, Operand.none]),
   Opcode.kCheckStack: const Format(
       Encoding.kA, const [Operand.imm, Operand.none, Operand.none]),
   Opcode.kAllocate: const Format(
@@ -193,17 +418,17 @@
   Opcode.kCreateArrayTOS: const Format(
       Encoding.k0, const [Operand.none, Operand.none, Operand.none]),
   Opcode.kAllocateContext: const Format(
-      Encoding.kAD, const [Operand.imm, Operand.imm, Operand.none]),
+      Encoding.kAE, const [Operand.imm, Operand.imm, Operand.none]),
   Opcode.kCloneContext: const Format(
-      Encoding.kAD, const [Operand.imm, Operand.imm, Operand.none]),
+      Encoding.kAE, const [Operand.imm, Operand.imm, Operand.none]),
   Opcode.kLoadContextParent: const Format(
       Encoding.k0, const [Operand.none, Operand.none, Operand.none]),
   Opcode.kStoreContextParent: const Format(
       Encoding.k0, const [Operand.none, Operand.none, Operand.none]),
   Opcode.kLoadContextVar: const Format(
-      Encoding.kAD, const [Operand.imm, Operand.imm, Operand.none]),
+      Encoding.kAE, const [Operand.imm, Operand.imm, Operand.none]),
   Opcode.kStoreContextVar: const Format(
-      Encoding.kAD, const [Operand.imm, Operand.imm, Operand.none]),
+      Encoding.kAE, const [Operand.imm, Operand.imm, Operand.none]),
   Opcode.kPushConstant: const Format(
       Encoding.kD, const [Operand.lit, Operand.none, Operand.none]),
   Opcode.kPushNull: const Format(
@@ -250,18 +475,16 @@
       Encoding.kT, const [Operand.tgt, Operand.none, Operand.none]),
   Opcode.kJumpIfNotNull: const Format(
       Encoding.kT, const [Operand.tgt, Operand.none, Operand.none]),
-  Opcode.kIndirectStaticCall: const Format(
-      Encoding.kAD, const [Operand.imm, Operand.lit, Operand.none]),
   Opcode.kInterfaceCall: const Format(
-      Encoding.kAD, const [Operand.imm, Operand.lit, Operand.none]),
+      Encoding.kDF, const [Operand.lit, Operand.imm, Operand.none]),
   Opcode.kDynamicCall: const Format(
-      Encoding.kAD, const [Operand.imm, Operand.lit, Operand.none]),
+      Encoding.kDF, const [Operand.lit, Operand.imm, Operand.none]),
   Opcode.kNativeCall: const Format(
       Encoding.kD, const [Operand.lit, Operand.none, Operand.none]),
   Opcode.kReturnTOS: const Format(
       Encoding.k0, const [Operand.none, Operand.none, Operand.none]),
   Opcode.kAssertAssignable: const Format(
-      Encoding.kAD, const [Operand.imm, Operand.lit, Operand.none]),
+      Encoding.kAE, const [Operand.imm, Operand.lit, Operand.none]),
   Opcode.kAssertBoolean: const Format(
       Encoding.kA, const [Operand.imm, Operand.none, Operand.none]),
   Opcode.kAssertSubtype: const Format(
@@ -271,11 +494,11 @@
   Opcode.kInstantiateType: const Format(
       Encoding.kD, const [Operand.lit, Operand.none, Operand.none]),
   Opcode.kInstantiateTypeArgumentsTOS: const Format(
-      Encoding.kAD, const [Operand.imm, Operand.lit, Operand.none]),
+      Encoding.kAE, const [Operand.imm, Operand.lit, Operand.none]),
   Opcode.kThrow: const Format(
       Encoding.kA, const [Operand.imm, Operand.none, Operand.none]),
   Opcode.kMoveSpecial: const Format(
-      Encoding.kAX, const [Operand.spe, Operand.xeg, Operand.none]),
+      Encoding.kAY, const [Operand.spe, Operand.xeg, Operand.none]),
   Opcode.kSetFrame: const Format(
       Encoding.kA, const [Operand.imm, Operand.none, Operand.none]),
   Opcode.kBooleanNegateTOS: const Format(
@@ -315,11 +538,11 @@
   Opcode.kCompareIntLe: const Format(
       Encoding.k0, const [Operand.none, Operand.none, Operand.none]),
   Opcode.kDirectCall: const Format(
-      Encoding.kAD, const [Operand.imm, Operand.lit, Operand.none]),
+      Encoding.kDF, const [Operand.lit, Operand.imm, Operand.none]),
   Opcode.kAllocateClosure: const Format(
       Encoding.kD, const [Operand.lit, Operand.none, Operand.none]),
   Opcode.kUncheckedInterfaceCall: const Format(
-      Encoding.kAD, const [Operand.imm, Operand.lit, Operand.none]),
+      Encoding.kDF, const [Operand.lit, Operand.imm, Operand.none]),
   Opcode.kNegateDouble: const Format(
       Encoding.k0, const [Operand.none, Operand.none, Operand.none]),
   Opcode.kAddDouble: const Format(
@@ -350,18 +573,80 @@
   stackTrace,
 }
 
+/// Returns [true] if there is a wide variant for the given opcode.
+bool hasWideVariant(Opcode opcode) {
+  final encoding = BytecodeFormats[opcode].encoding;
+  switch (encoding) {
+    case Encoding.k0:
+    case Encoding.kA:
+    case Encoding.kABC:
+      return false;
+    case Encoding.kD:
+    case Encoding.kX:
+    case Encoding.kT:
+    case Encoding.kAE:
+    case Encoding.kAY:
+    case Encoding.kDF:
+      return true;
+  }
+  throw 'Unexpected instruction encoding $encoding';
+}
+
+bool isWideOpcode(Opcode opcode) {
+  return (BytecodeFormats[opcode] == null) &&
+      hasWideVariant(Opcode.values[opcode.index - kWideModifier]);
+}
+
+Opcode fromWideOpcode(Opcode opcode) {
+  assert(isWideOpcode(opcode));
+  return Opcode.values[opcode.index - kWideModifier];
+}
+
+void verifyBytecodeInstructionDeclarations() {
+  const String kWideSuffix = '_Wide';
+  for (Opcode opcode in Opcode.values) {
+    final format = BytecodeFormats[opcode];
+    if (opcode.toString().endsWith(kWideSuffix)) {
+      if (format != null) {
+        throw 'Bytecode format should not be defined for wide opcode $opcode.';
+      }
+      final Opcode compact = Opcode.values[opcode.index - kWideModifier];
+      if (compact.toString() + kWideSuffix != opcode.toString()) {
+        throw 'Wide opcode $opcode should immediately follow its compact opcode (previous opcode is $compact).';
+      }
+      if (!hasWideVariant(compact)) {
+        throw 'Wide opcode $opcode should not be defined for opcode $compact with encoding ${BytecodeFormats[compact].encoding}.';
+      }
+    }
+    if (format == null) {
+      continue;
+    }
+    if (hasWideVariant(opcode)) {
+      if (Opcode.values[opcode.index + kWideModifier].toString() !=
+          opcode.toString() + kWideSuffix) {
+        throw 'Opcode $opcode$kWideSuffix should immedialy follow $opcode.';
+      }
+      if (opcode.index.isOdd) {
+        throw 'Opcode $opcode (${format.encoding}) has a wide variant and should be even';
+      }
+    }
+  }
+  if (Opcode.values.length > kMaxOpcodes) {
+    throw 'Too many opcodes';
+  }
+}
+
 bool isJump(Opcode opcode) => BytecodeFormats[opcode].encoding == Encoding.kT;
 
 bool isThrow(Opcode opcode) => opcode == Opcode.kThrow;
 
 bool isCall(Opcode opcode) {
   switch (opcode) {
-    case Opcode.kIndirectStaticCall:
+    case Opcode.kDirectCall:
     case Opcode.kInterfaceCall:
     case Opcode.kUncheckedInterfaceCall:
     case Opcode.kDynamicCall:
     case Opcode.kNativeCall:
-    case Opcode.kDirectCall:
       return true;
     default:
       return false;
@@ -389,14 +674,14 @@
 }
 
 // Bytecode instructions reference constant pool indices using
-// unsigned 16-bit operands.
-const int constantPoolIndexLimit = 1 << 16;
+// unsigned 32-bit operands.
+const int constantPoolIndexLimit = 1 << 32;
 
-// Local variables are referenced using 16-bit signed operands.
-const int localVariableIndexLimit = 1 << 15;
+// Local variables are referenced using 32-bit signed operands.
+const int localVariableIndexLimit = 1 << 31;
 
-// Captured variables are referenced using 16-bit unsigned operands.
-const int capturedVariableIndexLimit = 1 << 16;
+// Captured variables are referenced using 32-bit unsigned operands.
+const int capturedVariableIndexLimit = 1 << 32;
 
 // Context IDs are referenced using 8-bit unsigned operands.
 const int contextIdLimit = 1 << 8;
diff --git a/pkg/vm/lib/bytecode/declarations.dart b/pkg/vm/lib/bytecode/declarations.dart
index a028f6e..5fde12c 100644
--- a/pkg/vm/lib/bytecode/declarations.dart
+++ b/pkg/vm/lib/bytecode/declarations.dart
@@ -9,10 +9,7 @@
     show BufferedWriter, BufferedReader, BytecodeSizeStatistics, StringTable;
 import 'constant_pool.dart' show ConstantPool;
 import 'dbc.dart'
-    show
-        currentBytecodeFormatVersion,
-        futureBytecodeFormatVersion,
-        bytecodeInstructionsAlignment;
+    show currentBytecodeFormatVersion, futureBytecodeFormatVersion;
 import 'disassembler.dart' show BytecodeDisassembler;
 import 'exceptions.dart' show ExceptionsTable;
 import 'object_table.dart' show ObjectTable, ObjectHandle, NameAndType;
@@ -1029,13 +1026,11 @@
 
 void _writeBytecodeInstructions(BufferedWriter writer, List<int> bytecodes) {
   writer.writePackedUInt30(bytecodes.length);
-  writer.align(bytecodeInstructionsAlignment);
   writer.writeBytes(bytecodes);
   BytecodeSizeStatistics.instructionsSize += bytecodes.length;
 }
 
 List<int> _readBytecodeInstructions(BufferedReader reader) {
   int len = reader.readPackedUInt30();
-  reader.align(bytecodeInstructionsAlignment);
   return reader.readBytesAsUint8List(len);
 }
diff --git a/pkg/vm/lib/bytecode/disassembler.dart b/pkg/vm/lib/bytecode/disassembler.dart
index 153e837..5d53446 100644
--- a/pkg/vm/lib/bytecode/disassembler.dart
+++ b/pkg/vm/lib/bytecode/disassembler.dart
@@ -13,8 +13,15 @@
 
 class Instruction {
   final Opcode opcode;
+  final bool isWide;
   final List<int> operands;
-  Instruction(this.opcode, this.operands);
+  final int pc;
+
+  Instruction(this.opcode, this.isWide, this.operands, this.pc);
+
+  Format get format => BytecodeFormats[opcode];
+
+  int get length => instructionSize(format.encoding, isWide);
 
   @override
   int get hashCode => opcode.index.hashCode ^ listHashCode(operands);
@@ -28,9 +35,7 @@
 }
 
 class BytecodeDisassembler {
-  static const int kOpcodeMask = 0xFF;
-  static const int kBitsPerInt = 64;
-
+  Uint8List _bytecode;
   List<Instruction> _instructions;
   int _labelCount;
   Map<int, String> _labels;
@@ -47,14 +52,19 @@
     return _disasm();
   }
 
-  void _init(List<int> bytecode) {
-    final uint8list = new Uint8List.fromList(bytecode);
-    // TODO(alexmarkov): endianness?
-    Uint32List words = uint8list.buffer.asUint32List();
+  List<Instruction> decode(Uint8List bytecode) {
+    _init(bytecode);
+    return _instructions;
+  }
 
-    _instructions = new List<Instruction>(words.length);
-    for (int i = 0; i < words.length; i++) {
-      _instructions[i] = decodeInstruction(words[i]);
+  void _init(List<int> bytecode) {
+    _bytecode = new Uint8List.fromList(bytecode);
+
+    _instructions = new List<Instruction>();
+    for (int pos = 0; pos < _bytecode.length;) {
+      final instr = decodeInstructionAt(pos);
+      _instructions.add(instr);
+      pos += instr.length;
     }
 
     _labelCount = 0;
@@ -62,58 +72,73 @@
     _markers = <int, List<String>>{};
   }
 
-  Instruction decodeInstruction(int word) {
-    final opcode = Opcode.values[word & kOpcodeMask];
+  Instruction decodeInstructionAt(int pos) {
+    Opcode opcode = Opcode.values[_bytecode[pos]];
+    bool isWide = isWideOpcode(opcode);
+    if (isWide) {
+      opcode = fromWideOpcode(opcode);
+    }
+
     final format = BytecodeFormats[opcode];
-    return new Instruction(opcode, _decodeOperands(format, word));
+    final operands = _decodeOperands(format, pos, isWide);
+    return new Instruction(opcode, isWide, operands, pos);
   }
 
-  List<int> _decodeOperands(Format format, int word) {
+  List<int> _decodeOperands(Format format, int pos, bool isWide) {
     switch (format.encoding) {
       case Encoding.k0:
         return const [];
       case Encoding.kA:
-        return [_unsigned(word, 8, 8)];
-      case Encoding.kAD:
-        return [_unsigned(word, 8, 8), _unsigned(word, 16, 16)];
-      case Encoding.kAX:
-        return [_unsigned(word, 8, 8), _signed(word, 16, 16)];
+        return [_bytecode[pos + 1]];
       case Encoding.kD:
-        return [_unsigned(word, 16, 16)];
+        return isWide ? [_decodeUint32At(pos + 1)] : [_bytecode[pos + 1]];
       case Encoding.kX:
-        return [_signed(word, 16, 16)];
-      case Encoding.kABC:
-        return [
-          _unsigned(word, 8, 8),
-          _unsigned(word, 16, 8),
-          _unsigned(word, 24, 8)
-        ];
-      case Encoding.kABY:
-        return [
-          _unsigned(word, 8, 8),
-          _unsigned(word, 16, 8),
-          _signed(word, 24, 8)
-        ];
+        return isWide
+            ? [_decodeUint32At(pos + 1).toSigned(32)]
+            : [_bytecode[pos + 1].toSigned(8)];
       case Encoding.kT:
-        return [_signed(word, 8, 24)];
+        return isWide
+            ? [
+                (_bytecode[pos + 1] +
+                        (_bytecode[pos + 2] << 8) +
+                        (_bytecode[pos + 3] << 16))
+                    .toSigned(24)
+              ]
+            : [_bytecode[pos + 1].toSigned(8)];
+      case Encoding.kAE:
+        return [
+          _bytecode[pos + 1],
+          isWide ? _decodeUint32At(pos + 2) : _bytecode[pos + 2],
+        ];
+      case Encoding.kAY:
+        return [
+          _bytecode[pos + 1],
+          isWide
+              ? _decodeUint32At(pos + 2).toSigned(32)
+              : _bytecode[pos + 2].toSigned(8)
+        ];
+      case Encoding.kDF:
+        return isWide
+            ? [_decodeUint32At(pos + 1), _bytecode[pos + 5]]
+            : [_bytecode[pos + 1], _bytecode[pos + 2]];
+      case Encoding.kABC:
+        return [_bytecode[pos + 1], _bytecode[pos + 2], _bytecode[pos + 3]];
     }
     throw 'Unexpected format $format';
   }
 
-  int _unsigned(int word, int pos, int bits) =>
-      (word >> pos) & ((1 << bits) - 1);
-
-  int _signed(int word, int pos, int bits) =>
-      _unsigned(word, pos, bits) <<
-      (kBitsPerInt - bits) >>
-      (kBitsPerInt - bits);
+  _decodeUint32At(int pos) =>
+      _bytecode[pos] +
+      (_bytecode[pos + 1] << 8) +
+      (_bytecode[pos + 2] << 16) +
+      (_bytecode[pos + 3] << 24);
 
   void _scanForJumpTargets() {
     for (int i = 0; i < _instructions.length; i++) {
       final instr = _instructions[i];
       if (isJump(instr.opcode)) {
-        final target = i + instr.operands[0];
-        assert(0 <= target && target < _instructions.length);
+        final target = instr.pc + instr.operands[0];
+        assert(0 <= target && target < _bytecode.length);
         if (!_labels.containsKey(target)) {
           final label = 'L${++_labelCount}';
           _labels[target] = label;
@@ -147,17 +172,17 @@
 
   String _disasm() {
     StringBuffer out = new StringBuffer();
-    for (int i = 0; i < _instructions.length; i++) {
-      List<String> markers = _markers[i];
+    for (Instruction instr in _instructions) {
+      List<String> markers = _markers[instr.pc];
       if (markers != null) {
         markers.forEach(out.writeln);
       }
-      writeInstruction(out, i, _instructions[i]);
+      writeInstruction(out, instr);
     }
     return out.toString();
   }
 
-  void writeInstruction(StringBuffer out, int bci, Instruction instr) {
+  void writeInstruction(StringBuffer out, Instruction instr) {
     final format = BytecodeFormats[instr.opcode];
     assert(format != null);
 
@@ -184,14 +209,14 @@
         out.write(', ');
       }
       final operand =
-          _formatOperand(bci, format.operands[i], instr.operands[i]);
+          _formatOperand(instr.pc, format.operands[i], instr.operands[i]);
       out.write(operand);
     }
 
     out.writeln();
   }
 
-  String _formatOperand(int bci, Operand fmt, int value) {
+  String _formatOperand(int pc, Operand fmt, int value) {
     switch (fmt) {
       case Operand.none:
         break;
@@ -206,7 +231,7 @@
       case Operand.tgt:
         return (_labels == null)
             ? value.toString()
-            : _labels[bci + value] ?? (throw 'Label not found');
+            : _labels[pc + value] ?? (throw 'Label not found');
       case Operand.spe:
         return SpecialIndex.values[value]
             .toString()
diff --git a/pkg/vm/lib/bytecode/exceptions.dart b/pkg/vm/lib/bytecode/exceptions.dart
index 2147790..3ae6e1c 100644
--- a/pkg/vm/lib/bytecode/exceptions.dart
+++ b/pkg/vm/lib/bytecode/exceptions.dart
@@ -11,7 +11,7 @@
 In kernel binary, try blocks are encoded in the following way
 (using notation from pkg/kernel/binary.md):
 
-// Offset of a bytecode instruction, in DBC words.
+// Offset of a bytecode instruction.
 type BytecodeOffset = UInt;
 
 type TryBlock {
diff --git a/pkg/vm/lib/bytecode/gen_bytecode.dart b/pkg/vm/lib/bytecode/gen_bytecode.dart
index 21721a6..216ac55 100644
--- a/pkg/vm/lib/bytecode/gen_bytecode.dart
+++ b/pkg/vm/lib/bytecode/gen_bytecode.dart
@@ -50,6 +50,7 @@
 
 void generateBytecode(
   ast.Component component, {
+  bool enableAsserts: true,
   bool emitSourcePositions: false,
   bool emitAnnotations: false,
   bool omitAssertSourcePositions: false,
@@ -59,6 +60,7 @@
   List<Library> libraries,
   ClassHierarchy hierarchy,
 }) {
+  verifyBytecodeInstructionDeclarations();
   final coreTypes = new CoreTypes(component);
   void ignoreAmbiguousSupertypes(Class cls, Supertype a, Supertype b) {}
   hierarchy ??= new ClassHierarchy(component,
@@ -74,6 +76,7 @@
       typeEnvironment,
       constantsBackend,
       environmentDefines,
+      enableAsserts,
       emitSourcePositions,
       emitAnnotations,
       omitAssertSourcePositions,
@@ -90,6 +93,7 @@
   final TypeEnvironment typeEnvironment;
   final ConstantsBackend constantsBackend;
   final Map<String, String> environmentDefines;
+  final bool enableAsserts;
   final bool emitSourcePositions;
   final bool emitAnnotations;
   final bool omitAssertSourcePositions;
@@ -138,6 +142,7 @@
       this.typeEnvironment,
       this.constantsBackend,
       this.environmentDefines,
+      this.enableAsserts,
       this.emitSourcePositions,
       this.emitAnnotations,
       this.omitAssertSourcePositions,
@@ -739,6 +744,9 @@
   }
 
   void _genPushInt(int value) {
+    // TODO(alexmarkov): relax this constraint as PushInt instruction can
+    // hold up to 32-bit signed operand (note that interpreter assumes
+    // it is Smi).
     if (value.bitLength + 1 <= 16) {
       asm.emitPushInt(value);
     } else {
@@ -786,7 +794,7 @@
         : (isSet ? InvocationKind.setter : InvocationKind.method);
     final cpIndex = cp.addDirectCall(kind, target, argDesc);
 
-    asm.emitDirectCall(totalArgCount, cpIndex);
+    asm.emitDirectCall(cpIndex, totalArgCount);
   }
 
   void _genDirectCallWithArgs(Member target, Arguments args,
@@ -1065,7 +1073,7 @@
       final argDesc = objectTable.getArgDescHandle(2);
       final cpIndex = cp.addInterfaceCall(
           InvocationKind.method, objectSimpleInstanceOf, argDesc);
-      asm.emitInterfaceCall(2, cpIndex);
+      asm.emitInterfaceCall(cpIndex, 2);
       return;
     }
 
@@ -1079,7 +1087,7 @@
     final argDesc = objectTable.getArgDescHandle(4);
     final cpIndex =
         cp.addInterfaceCall(InvocationKind.method, objectInstanceOf, argDesc);
-    asm.emitInterfaceCall(4, cpIndex);
+    asm.emitInterfaceCall(cpIndex, 4);
   }
 
   void start(Member node) {
@@ -1120,12 +1128,8 @@
       functionTypeParametersSet = functionTypeParameters.toSet();
     }
     // TODO(alexmarkov): improve caching in ConstantEvaluator and reuse it
-    constantEvaluator = new ConstantEvaluator(
-        constantsBackend,
-        environmentDefines,
-        typeEnvironment,
-        /* enableAsserts = */ true,
-        errorReporter)
+    constantEvaluator = new ConstantEvaluator(constantsBackend,
+        environmentDefines, typeEnvironment, enableAsserts, errorReporter)
       ..env = new EvaluationEnvironment();
 
     if (node.isAbstract || node is Field && !hasInitializerCode(node)) {
@@ -1146,7 +1150,7 @@
     savedAssemblers = <BytecodeAssembler>[];
     currentLoopDepth = 0;
 
-    locals = new LocalVariables(node);
+    locals = new LocalVariables(node, enableAsserts);
     locals.enterScope(node);
     assert(!locals.isSyncYieldingFrame);
 
@@ -2290,18 +2294,18 @@
         throw 'Unexpected specialized bytecode $opcode';
     }
 
-    asm.emitBytecode0(opcode);
+    asm.emitSpecializedBytecode(opcode);
   }
 
   void _genInstanceCall(
       int totalArgCount, int callCpIndex, bool isDynamic, bool isUnchecked) {
     if (isDynamic) {
       assert(!isUnchecked);
-      asm.emitDynamicCall(totalArgCount, callCpIndex);
+      asm.emitDynamicCall(callCpIndex, totalArgCount);
     } else if (isUnchecked) {
-      asm.emitUncheckedInterfaceCall(totalArgCount, callCpIndex);
+      asm.emitUncheckedInterfaceCall(callCpIndex, totalArgCount);
     } else {
-      asm.emitInterfaceCall(totalArgCount, callCpIndex);
+      asm.emitInterfaceCall(callCpIndex, totalArgCount);
     }
   }
 
@@ -2682,6 +2686,10 @@
 
   @override
   visitAssertStatement(AssertStatement node) {
+    if (!enableAsserts) {
+      return;
+    }
+
     final Label done = new Label();
     asm.emitJumpIfNoAsserts(done);
 
@@ -2711,6 +2719,10 @@
 
   @override
   visitAssertBlock(AssertBlock node) {
+    if (!enableAsserts) {
+      return;
+    }
+
     final Label done = new Label();
     asm.emitJumpIfNoAsserts(done);
 
@@ -2794,9 +2806,9 @@
     // Front-end inserts implicit cast (type check) which ensures that
     // result of iterable expression is Iterable<dynamic>.
     asm.emitInterfaceCall(
-        1,
         cp.addInterfaceCall(InvocationKind.getter, iterableIterator,
-            objectTable.getArgDescHandle(1)));
+            objectTable.getArgDescHandle(1)),
+        1);
 
     final iteratorTemp = locals.tempIndexInFrame(node);
     asm.emitPopLocal(iteratorTemp);
@@ -2828,9 +2840,9 @@
     }
 
     asm.emitInterfaceCall(
-        1,
         cp.addInterfaceCall(InvocationKind.method, iteratorMoveNext,
-            objectTable.getArgDescHandle(1)));
+            objectTable.getArgDescHandle(1)),
+        1);
     _genJumpIfFalse(/* negated = */ false, done);
 
     _enterScope(node);
@@ -2839,9 +2851,9 @@
 
     asm.emitPush(iteratorTemp);
     asm.emitInterfaceCall(
-        1,
         cp.addInterfaceCall(InvocationKind.getter, iteratorCurrent,
-            objectTable.getArgDescHandle(1)));
+            objectTable.getArgDescHandle(1)),
+        1);
 
     _genStoreVar(node.variable);
 
@@ -2998,9 +3010,9 @@
           asm.emitPush(temp);
           _genPushConstExpr(expr);
           asm.emitInterfaceCall(
-              2,
-              cp.addInterfaceCall(InvocationKind.method, coreTypes.objectEquals,
-                  equalsArgDesc));
+              cp.addInterfaceCall(
+                  InvocationKind.method, coreTypes.objectEquals, equalsArgDesc),
+              2);
           _genJumpIfTrue(/* negated = */ false, caseLabel);
         }
       }
@@ -3088,13 +3100,13 @@
 
     _saveContextForTryBlock(node);
 
-    return asm.exceptionsTable.enterTryBlock(asm.offsetInWords);
+    return asm.exceptionsTable.enterTryBlock(asm.offset);
   }
 
   /// End try block and start its handler.
   void _endTryBlock(TreeNode node, TryBlock tryBlock) {
-    tryBlock.endPC = asm.offsetInWords;
-    tryBlock.handlerPC = asm.offsetInWords;
+    tryBlock.endPC = asm.offset;
+    tryBlock.handlerPC = asm.offset;
 
     // Exception handlers are reachable although there are no labels or jumps.
     asm.isUnreachable = false;
diff --git a/pkg/vm/lib/bytecode/local_vars.dart b/pkg/vm/lib/bytecode/local_vars.dart
index 5d3862d..178bfa1 100644
--- a/pkg/vm/lib/bytecode/local_vars.dart
+++ b/pkg/vm/lib/bytecode/local_vars.dart
@@ -24,6 +24,7 @@
       <TreeNode, VariableDeclaration>{};
   final Map<ForInStatement, VariableDeclaration> _capturedIteratorVars =
       <ForInStatement, VariableDeclaration>{};
+  final bool enableAsserts;
 
   Scope _currentScope;
   Frame _currentFrame;
@@ -175,7 +176,7 @@
   List<VariableDeclaration> get sortedNamedParameters =>
       _currentFrame.sortedNamedParameters;
 
-  LocalVariables(Member node) {
+  LocalVariables(Member node, this.enableAsserts) {
     final scopeBuilder = new _ScopeBuilder(this);
     node.accept(scopeBuilder);
 
@@ -608,7 +609,18 @@
   }
 
   @override
+  visitAssertStatement(AssertStatement node) {
+    if (!locals.enableAsserts) {
+      return;
+    }
+    super.visitAssertStatement(node);
+  }
+
+  @override
   visitAssertBlock(AssertBlock node) {
+    if (!locals.enableAsserts) {
+      return;
+    }
     _visitWithScope(node);
   }
 
@@ -1056,7 +1068,18 @@
   }
 
   @override
+  visitAssertStatement(AssertStatement node) {
+    if (!locals.enableAsserts) {
+      return;
+    }
+    super.visitAssertStatement(node);
+  }
+
+  @override
   visitAssertBlock(AssertBlock node) {
+    if (!locals.enableAsserts) {
+      return;
+    }
     _visit(node, scope: true);
   }
 
diff --git a/pkg/vm/lib/bytecode/ngrams.dart b/pkg/vm/lib/bytecode/ngrams.dart
index 040b51b..54e028b 100644
--- a/pkg/vm/lib/bytecode/ngrams.dart
+++ b/pkg/vm/lib/bytecode/ngrams.dart
@@ -16,16 +16,9 @@
 
 class NGram {
   List<Instruction> instrs;
-  List<int> _words;
   BytecodeDisassembler _disassembler;
 
-  NGram(List<int> words, {bool mergePushes = false}) {
-    _disassembler = new BytecodeDisassembler();
-    _words = words;
-    instrs = new List<Instruction>(words.length);
-    for (int i = 0; i < instrs.length; i++) {
-      instrs[i] = _disassembler.decodeInstruction(words[i]);
-    }
+  NGram(this.instrs, {bool mergePushes = false}) {
     if (mergePushes) {
       _mergePushes(instrs);
     }
@@ -48,7 +41,7 @@
   String toString() {
     StringBuffer out = new StringBuffer();
     for (var instr in instrs) {
-      _disassembler.writeInstruction(out, 0, instr);
+      _disassembler.writeInstruction(out, instr);
     }
     return out.toString();
   }
@@ -57,7 +50,7 @@
   static void _mergePushes(List<Instruction> instrs) {
     for (int i = 0; i < instrs.length; i++) {
       if (isPush(instrs[i].opcode)) {
-        instrs[i] = new Instruction(Opcode.kPush, <int>[0]);
+        instrs[i] = new Instruction(Opcode.kPush, false, <int>[0], 0);
       }
     }
   }
@@ -104,14 +97,15 @@
 }
 
 class NGramReader {
-  Uint32List _words;
+  List<Instruction> _instructions;
 
   Map<NGram, int> _ngramCounts = <NGram, int>{};
 
   NGramReader(String traceFilename) {
     File traceFile = File(traceFilename);
-    Uint8List data = traceFile.readAsBytesSync();
-    _words = Uint32List.view(data.buffer);
+    Uint8List bytecode = traceFile.readAsBytesSync();
+    final disassembler = new BytecodeDisassembler();
+    _instructions = disassembler.decode(bytecode);
   }
 
   Map<NGram, int> get ngramCounts => _ngramCounts;
@@ -119,8 +113,9 @@
   void readAllNGrams(int windowSize,
       {bool basicBlocks: true, bool mergePushes: false}) {
     int offset = 0;
-    while (offset + windowSize < _words.length) {
-      Uint32List window = _words.sublist(offset, offset + windowSize);
+    while (offset + windowSize < _instructions.length) {
+      List<Instruction> window =
+          _instructions.sublist(offset, offset + windowSize);
       offset += 1;
       NGram ngram = new NGram(window, mergePushes: mergePushes);
       if (basicBlocks && ngram.controlFlowIsNotLast) {
diff --git a/pkg/vm/lib/frontend_server.dart b/pkg/vm/lib/frontend_server.dart
index 0d7c7af..bce696d 100644
--- a/pkg/vm/lib/frontend_server.dart
+++ b/pkg/vm/lib/frontend_server.dart
@@ -113,6 +113,9 @@
           'improved speed.',
       defaultsTo: false,
       hide: true)
+  ..addFlag('track-widget-creation',
+      help: 'Run a kernel transformer to track creation locations for widgets.',
+      defaultsTo: false)
   ..addMultiOption('enable-experiment',
       help: 'Comma separated list of experimental features, eg set-literals.',
       hide: true);
@@ -319,7 +322,10 @@
       return false;
     }
 
-    compilerOptions.target = createFrontEndTarget(options['target']);
+    compilerOptions.target = createFrontEndTarget(
+      options['target'],
+      trackWidgetCreation: options['track-widget-creation'],
+    );
     if (compilerOptions.target == null) {
       print('Failed to create front-end target ${options['target']}.');
       return false;
diff --git a/pkg/vm/lib/kernel_front_end.dart b/pkg/vm/lib/kernel_front_end.dart
index 703cfa8..d65f56b 100644
--- a/pkg/vm/lib/kernel_front_end.dart
+++ b/pkg/vm/lib/kernel_front_end.dart
@@ -264,6 +264,7 @@
       outputFileName,
       environmentDefines: environmentDefines,
       genBytecode: genBytecode,
+      enableAsserts: enableAsserts,
       emitBytecodeSourcePositions: emitBytecodeSourcePositions,
       emitBytecodeAnnotations: emitBytecodeAnnotations,
       dropAST: dropAST,
@@ -317,6 +318,7 @@
   if (genBytecode && !errorDetector.hasCompilationErrors && component != null) {
     await runWithFrontEndCompilerContext(source, options, component, () {
       generateBytecode(component,
+          enableAsserts: enableAsserts,
           emitSourcePositions: emitBytecodeSourcePositions,
           emitAnnotations: emitBytecodeAnnotations,
           useFutureBytecodeFormat: useFutureBytecodeFormat,
@@ -532,11 +534,13 @@
 }
 
 /// Create front-end target with given name.
-Target createFrontEndTarget(String targetName) {
+Target createFrontEndTarget(String targetName,
+    {bool trackWidgetCreation = false}) {
   // Make sure VM-specific targets are available.
   installAdditionalTargets();
 
-  final TargetFlags targetFlags = new TargetFlags();
+  final TargetFlags targetFlags =
+      new TargetFlags(trackWidgetCreation: trackWidgetCreation);
   return getTarget(targetName, targetFlags);
 }
 
@@ -612,6 +616,10 @@
   }
   // file:///a/b/x/y/main.dart -> package:x.y/main.dart
   for (var line in packages) {
+    if (line.isEmpty || line.startsWith("#")) {
+      continue;
+    }
+
     final colon = line.indexOf(':');
     if (colon == -1) {
       continue;
@@ -646,6 +654,7 @@
   String outputFileName, {
   Map<String, String> environmentDefines,
   bool genBytecode: false,
+  bool enableAsserts: true,
   bool emitBytecodeSourcePositions: false,
   bool emitBytecodeAnnotations: false,
   bool dropAST: false,
@@ -707,6 +716,7 @@
         generateBytecode(component,
             libraries: libraries,
             hierarchy: hierarchy,
+            enableAsserts: enableAsserts,
             emitSourcePositions: emitBytecodeSourcePositions,
             emitAnnotations: emitBytecodeAnnotations,
             useFutureBytecodeFormat: useFutureBytecodeFormat,
diff --git a/pkg/vm/lib/target/flutter.dart b/pkg/vm/lib/target/flutter.dart
index 1faa9a2..02673e7 100644
--- a/pkg/vm/lib/target/flutter.dart
+++ b/pkg/vm/lib/target/flutter.dart
@@ -3,7 +3,10 @@
 // BSD-style license that can be found in the LICENSE file.
 library vm.target.flutter;
 
+import 'package:kernel/ast.dart' show Component, Library;
+import 'package:kernel/core_types.dart' show CoreTypes;
 import 'package:kernel/target/targets.dart';
+import 'package:kernel/transformations/track_widget_constructor_locations.dart';
 import 'package:vm/target/vm.dart' show VmTarget;
 
 class FlutterTarget extends VmTarget {
@@ -41,4 +44,16 @@
         'dart:ui',
         'dart:vmservice_io',
       ];
+
+  @override
+  void performPreConstantEvaluationTransformations(
+      Component component,
+      CoreTypes coreTypes,
+      List<Library> libraries,
+      DiagnosticReporter diagnosticReporter,
+      {void logger(String msg)}) {
+    if (flags.trackWidgetCreation) {
+      new WidgetCreatorTracker().transform(component, libraries);
+    }
+  }
 }
diff --git a/pkg/vm/testcases/bytecode/asserts.dart.expect b/pkg/vm/testcases/bytecode/asserts.dart.expect
index de42a48..8bfc0e9 100644
--- a/pkg/vm/testcases/bytecode/asserts.dart.expect
+++ b/pkg/vm/testcases/bytecode/asserts.dart.expect
@@ -26,7 +26,7 @@
   PushInt              0
   PushInt              0
   PushNull
-  DirectCall           3, CP#0
+  DirectCall           CP#0, 3
   Drop1
 L1:
   PushNull
@@ -48,14 +48,14 @@
   CheckStack           0
   JumpIfNoAsserts      L1
   Push                 FP[-6]
-  DynamicCall          1, CP#1
+  DynamicCall          CP#1, 1
   AssertBoolean        0
   JumpIfTrue           L1
   PushInt              0
   PushInt              0
   Push                 FP[-5]
-  DynamicCall          1, CP#2
-  DirectCall           3, CP#3
+  DynamicCall          CP#2, 1
+  DirectCall           CP#3, 3
   Drop1
 L1:
   PushNull
diff --git a/pkg/vm/testcases/bytecode/async.dart.expect b/pkg/vm/testcases/bytecode/async.dart.expect
index cce2837..4805482 100644
--- a/pkg/vm/testcases/bytecode/async.dart.expect
+++ b/pkg/vm/testcases/bytecode/async.dart.expect
@@ -101,7 +101,7 @@
   AllocateT
   StoreLocal           r2
   Push                 r2
-  DirectCall           1, CP#8
+  DirectCall           CP#8, 1
   Drop1
   StoreContextVar      0, 1
   Push                 r0
@@ -145,27 +145,27 @@
   StoreContextVar      0, 8
   Push                 r0
   LoadContextVar       0, 8
-  DirectCall           1, CP#29
+  DirectCall           CP#29, 1
   PopLocal             r3
   Push                 r0
   Push                 r0
   LoadContextVar       0, 8
-  DirectCall           1, CP#31
+  DirectCall           CP#31, 1
   StoreContextVar      0, 3
   Push                 r0
   Push                 r0
   LoadContextVar       0, 8
-  DirectCall           1, CP#33
+  DirectCall           CP#33, 1
   StoreContextVar      0, 4
   Push                 r0
   LoadContextVar       0, 1
   Push                 r0
   LoadContextVar       0, 8
-  DynamicCall          2, CP#36
+  DynamicCall          CP#36, 2
   Drop1
   Push                 r0
   LoadContextVar       0, 1
-  InterfaceCall        1, CP#37
+  InterfaceCall        CP#37, 1
   ReturnTOS
 
 }
@@ -204,7 +204,7 @@
   LoadContextVar       0, 4
   Push                 r4
   LoadContextVar       0, 8
-  DirectCall           4, CP#12
+  DirectCall           CP#12, 4
   PopLocal             r8
   PushNull
   ReturnTOS
@@ -221,7 +221,7 @@
   LoadContextVar       0, 1
   Push                 r4
   LoadContextVar       0, 2
-  DirectCall           2, CP#14
+  DirectCall           CP#14, 2
   Drop1
   PushNull
   ReturnTOS
@@ -244,7 +244,7 @@
   LoadContextVar       0, 1
   Push                 r8
   Push                 r9
-  InterfaceCall        3, CP#17
+  InterfaceCall        CP#17, 3
   Drop1
   Jump                 L3
 L3:
@@ -275,7 +275,7 @@
   AllocateT
   StoreLocal           r2
   Push                 r2
-  DirectCall           1, CP#2
+  DirectCall           CP#2, 1
   Drop1
   StoreContextVar      0, 0
   Push                 r0
@@ -312,22 +312,22 @@
   StoreFieldTOS        CP#6
   PopLocal             r6
   Push                 r6
-  DirectCall           1, CP#23
+  DirectCall           CP#23, 1
   PopLocal             r3
   Push                 r6
-  DirectCall           1, CP#25
+  DirectCall           CP#25, 1
   PopLocal             r4
   Push                 r6
-  DirectCall           1, CP#27
+  DirectCall           CP#27, 1
   PopLocal             r5
   Push                 r0
   LoadContextVar       0, 0
   Push                 r6
-  DynamicCall          2, CP#30
+  DynamicCall          CP#30, 2
   Drop1
   Push                 r0
   LoadContextVar       0, 0
-  InterfaceCall        1, CP#31
+  InterfaceCall        CP#31, 1
   ReturnTOS
 }
 ConstantPool {
@@ -393,7 +393,7 @@
   LoadContextVar       0, 0
   Push                 r4
   LoadContextVar       0, 1
-  DirectCall           2, CP#8
+  DirectCall           CP#8, 2
   Drop1
   PushNull
   ReturnTOS
@@ -412,7 +412,7 @@
   LoadContextVar       0, 0
   Push                 r8
   Push                 r9
-  InterfaceCall        3, CP#11
+  InterfaceCall        CP#11, 3
   Drop1
   Jump                 L3
 L3:
@@ -446,7 +446,7 @@
   AllocateT
   StoreLocal           r2
   Push                 r2
-  DirectCall           1, CP#2
+  DirectCall           CP#2, 1
   Drop1
   StoreContextVar      0, 2
   Push                 r0
@@ -493,27 +493,27 @@
   StoreContextVar      0, 10
   Push                 r0
   LoadContextVar       0, 10
-  DirectCall           1, CP#27
+  DirectCall           CP#27, 1
   PopLocal             r3
   Push                 r0
   Push                 r0
   LoadContextVar       0, 10
-  DirectCall           1, CP#29
+  DirectCall           CP#29, 1
   StoreContextVar      0, 4
   Push                 r0
   Push                 r0
   LoadContextVar       0, 10
-  DirectCall           1, CP#31
+  DirectCall           CP#31, 1
   StoreContextVar      0, 5
   Push                 r0
   LoadContextVar       0, 2
   Push                 r0
   LoadContextVar       0, 10
-  DynamicCall          2, CP#34
+  DynamicCall          CP#34, 2
   Drop1
   Push                 r0
   LoadContextVar       0, 2
-  InterfaceCall        1, CP#35
+  InterfaceCall        CP#35, 1
   ReturnTOS
 }
 ConstantPool {
@@ -589,7 +589,7 @@
   LoadContextVar       0, 5
   Push                 r4
   LoadContextVar       0, 10
-  DirectCall           4, CP#8
+  DirectCall           CP#8, 4
   PopLocal             r8
   PushNull
   ReturnTOS
@@ -617,7 +617,7 @@
   LoadContextVar       0, 5
   Push                 r4
   LoadContextVar       0, 10
-  DirectCall           4, CP#8
+  DirectCall           CP#8, 4
   PopLocal             r9
   PushNull
   ReturnTOS
@@ -632,7 +632,7 @@
   Push                 r4
   LoadContextVar       0, 9
   Push                 r1
-  InterfaceCall        2, CP#10
+  InterfaceCall        CP#10, 2
   StoreContextVar      0, 3
   Jump                 L4
 L4:
@@ -640,7 +640,7 @@
   LoadContextVar       0, 2
   Push                 r4
   LoadContextVar       0, 3
-  DirectCall           2, CP#12
+  DirectCall           CP#12, 2
   Drop1
   PushNull
   ReturnTOS
@@ -663,7 +663,7 @@
   LoadContextVar       0, 2
   Push                 r8
   Push                 r9
-  InterfaceCall        3, CP#15
+  InterfaceCall        CP#15, 3
   Drop1
   Jump                 L5
 L5:
@@ -700,7 +700,7 @@
   AllocateT
   StoreLocal           r2
   Push                 r2
-  DirectCall           1, CP#2
+  DirectCall           CP#2, 1
   Drop1
   StoreContextVar      0, 1
   Push                 r0
@@ -750,27 +750,27 @@
   StoreContextVar      0, 10
   Push                 r0
   LoadContextVar       0, 10
-  DirectCall           1, CP#35
+  DirectCall           CP#35, 1
   PopLocal             r3
   Push                 r0
   Push                 r0
   LoadContextVar       0, 10
-  DirectCall           1, CP#37
+  DirectCall           CP#37, 1
   StoreContextVar      0, 3
   Push                 r0
   Push                 r0
   LoadContextVar       0, 10
-  DirectCall           1, CP#39
+  DirectCall           CP#39, 1
   StoreContextVar      0, 4
   Push                 r0
   LoadContextVar       0, 1
   Push                 r0
   LoadContextVar       0, 10
-  DynamicCall          2, CP#42
+  DynamicCall          CP#42, 2
   Drop1
   Push                 r0
   LoadContextVar       0, 1
-  InterfaceCall        1, CP#43
+  InterfaceCall        CP#43, 1
   ReturnTOS
 }
 ConstantPool {
@@ -869,7 +869,7 @@
   LoadContextParent
   LoadContextParent
   LoadContextVar       0, 0
-  InterfaceCall        1, CP#8
+  InterfaceCall        CP#8, 1
   PopLocal             r8
   Push                 r4
   Push                 r8
@@ -879,7 +879,7 @@
   Push                 r4
   LoadContextVar       2, 1
   StoreLocal           r8
-  InterfaceCall        1, CP#10
+  InterfaceCall        CP#10, 1
   JumpIfFalse          L3
   AllocateContext      3, 1
   StoreLocal           r5
@@ -889,7 +889,7 @@
   PopLocal             r4
   Push                 r4
   Push                 r8
-  InterfaceCall        1, CP#12
+  InterfaceCall        CP#12, 1
   StoreContextVar      3, 0
   Push                 r4
   LoadContextParent
@@ -923,7 +923,7 @@
   LoadContextParent
   Push                 r4
   StoreContextVar      0, 6
-  DirectCall           0, CP#14
+  DirectCall           CP#14, 0
   Push                 r4
   LoadContextParent
   LoadContextParent
@@ -939,7 +939,7 @@
   LoadContextParent
   LoadContextParent
   LoadContextVar       0, 10
-  DirectCall           4, CP#16
+  DirectCall           CP#16, 4
   PopLocal             r10
   PushNull
   ReturnTOS
@@ -964,8 +964,8 @@
   LoadContextParent
   LoadContextVar       0, 8
   Push                 r1
-  InterfaceCall        2, CP#18
-  InterfaceCall        2, CP#18
+  InterfaceCall        CP#18, 2
+  InterfaceCall        CP#18, 2
   StoreContextVar      1, 0
   Push                 r4
   LoadContextParent
@@ -1024,7 +1024,7 @@
   LoadContextVar       0, 1
   Push                 r4
   LoadContextVar       0, 2
-  DirectCall           2, CP#20
+  DirectCall           CP#20, 2
   Drop1
   PushNull
   ReturnTOS
@@ -1047,7 +1047,7 @@
   LoadContextVar       0, 1
   Push                 r8
   Push                 r9
-  InterfaceCall        3, CP#23
+  InterfaceCall        CP#23, 3
   Drop1
   Jump                 L10
 L10:
@@ -1087,7 +1087,7 @@
   AllocateT
   StoreLocal           r2
   Push                 r2
-  DirectCall           1, CP#2
+  DirectCall           CP#2, 1
   Drop1
   StoreContextVar      0, 3
   Push                 r0
@@ -1152,27 +1152,27 @@
   StoreContextVar      0, 17
   Push                 r0
   LoadContextVar       0, 17
-  DirectCall           1, CP#33
+  DirectCall           CP#33, 1
   PopLocal             r3
   Push                 r0
   Push                 r0
   LoadContextVar       0, 17
-  DirectCall           1, CP#35
+  DirectCall           CP#35, 1
   StoreContextVar      0, 5
   Push                 r0
   Push                 r0
   LoadContextVar       0, 17
-  DirectCall           1, CP#37
+  DirectCall           CP#37, 1
   StoreContextVar      0, 6
   Push                 r0
   LoadContextVar       0, 3
   Push                 r0
   LoadContextVar       0, 17
-  DynamicCall          2, CP#40
+  DynamicCall          CP#40, 2
   Drop1
   Push                 r0
   LoadContextVar       0, 3
-  InterfaceCall        1, CP#41
+  InterfaceCall        CP#41, 1
   ReturnTOS
 }
 ConstantPool {
@@ -1284,7 +1284,7 @@
   Push                 r4
   LoadContextParent
   LoadContextVar       0, 17
-  DirectCall           4, CP#8
+  DirectCall           CP#8, 4
   PopLocal             r13
   PushNull
   ReturnTOS
@@ -1300,7 +1300,7 @@
   LoadContextParent
   LoadContextVar       0, 14
   Push                 r1
-  InterfaceCall        2, CP#10
+  InterfaceCall        CP#10, 2
   StoreContextVar      1, 0
   Jump                 L3
 Try #2 end:
@@ -1328,7 +1328,7 @@
   Push                 r4
   LoadContextVar       1, 1
   PushConstant         CP#13
-  InterfaceCall        2, CP#14
+  InterfaceCall        CP#14, 2
   JumpIfFalse          L4
   Push                 r4
   LoadContextParent
@@ -1361,7 +1361,7 @@
   Push                 r4
   LoadContextParent
   LoadContextVar       0, 17
-  DirectCall           4, CP#8
+  DirectCall           CP#8, 4
   PopLocal             r13
   PushNull
   ReturnTOS
@@ -1377,7 +1377,7 @@
   LoadContextParent
   LoadContextVar       0, 15
   Push                 r1
-  InterfaceCall        2, CP#10
+  InterfaceCall        CP#10, 2
   StoreContextVar      1, 0
   Push                 r4
   LoadContextParent
@@ -1408,7 +1408,7 @@
   Push                 r9
   StoreContextVar      0, 13
   PushConstant         CP#16
-  DirectCall           1, CP#17
+  DirectCall           CP#17, 1
   Drop1
   Push                 r4
   LoadContextParent
@@ -1435,7 +1435,7 @@
   Push                 r4
   LoadContextParent
   LoadContextVar       0, 17
-  DirectCall           4, CP#8
+  DirectCall           CP#8, 4
   PopLocal             r12
   PushNull
   ReturnTOS
@@ -1451,7 +1451,7 @@
   LoadContextParent
   LoadContextVar       0, 16
   Push                 r1
-  InterfaceCall        2, CP#10
+  InterfaceCall        CP#10, 2
   StoreContextVar      1, 0
   Push                 r4
   LoadContextParent
@@ -1470,7 +1470,7 @@
   LoadContextVar       0, 10
   PopLocal             r4
   PushConstant         CP#16
-  DirectCall           1, CP#17
+  DirectCall           CP#17, 1
   Drop1
   Push                 r4
   LoadContextParent
@@ -1497,7 +1497,7 @@
   Push                 r4
   LoadContextParent
   LoadContextVar       0, 17
-  DirectCall           4, CP#8
+  DirectCall           CP#8, 4
   PopLocal             r12
   PushNull
   ReturnTOS
@@ -1513,7 +1513,7 @@
   LoadContextParent
   LoadContextVar       0, 16
   Push                 r1
-  InterfaceCall        2, CP#10
+  InterfaceCall        CP#10, 2
   StoreContextVar      1, 0
   Push                 r4
   LoadContextParent
@@ -1532,7 +1532,7 @@
   LoadContextVar       0, 10
   PopLocal             r4
   PushConstant         CP#16
-  DirectCall           1, CP#17
+  DirectCall           CP#17, 1
   Drop1
   Push                 r4
   LoadContextParent
@@ -1559,7 +1559,7 @@
   Push                 r4
   LoadContextParent
   LoadContextVar       0, 17
-  DirectCall           4, CP#8
+  DirectCall           CP#8, 4
   PopLocal             r12
   PushNull
   ReturnTOS
@@ -1575,7 +1575,7 @@
   LoadContextParent
   LoadContextVar       0, 16
   Push                 r1
-  InterfaceCall        2, CP#10
+  InterfaceCall        CP#10, 2
   StoreContextVar      1, 0
   Push                 r4
   LoadContextParent
@@ -1591,7 +1591,7 @@
   LoadContextVar       0, 3
   Push                 r4
   LoadContextVar       0, 4
-  DirectCall           2, CP#19
+  DirectCall           CP#19, 2
   Drop1
   PushNull
   ReturnTOS
@@ -1614,7 +1614,7 @@
   LoadContextVar       0, 3
   Push                 r8
   Push                 r9
-  InterfaceCall        3, CP#21
+  InterfaceCall        CP#21, 3
   Drop1
   Jump                 L12
 L12:
@@ -1739,7 +1739,7 @@
   AllocateT
   StoreLocal           r2
   Push                 r2
-  DirectCall           1, CP#5
+  DirectCall           CP#5, 1
   Drop1
   StoreContextVar      1, 0
   Push                 r0
@@ -1786,27 +1786,27 @@
   StoreContextVar      1, 8
   Push                 r0
   LoadContextVar       1, 8
-  DirectCall           1, CP#29
+  DirectCall           CP#29, 1
   PopLocal             r3
   Push                 r0
   Push                 r0
   LoadContextVar       1, 8
-  DirectCall           1, CP#31
+  DirectCall           CP#31, 1
   StoreContextVar      1, 2
   Push                 r0
   Push                 r0
   LoadContextVar       1, 8
-  DirectCall           1, CP#33
+  DirectCall           CP#33, 1
   StoreContextVar      1, 3
   Push                 r0
   LoadContextVar       1, 0
   Push                 r0
   LoadContextVar       1, 8
-  DynamicCall          2, CP#36
+  DynamicCall          CP#36, 2
   Drop1
   Push                 r0
   LoadContextVar       1, 0
-  InterfaceCall        1, CP#37
+  InterfaceCall        CP#37, 1
   ReturnTOS
 
 }
@@ -1871,7 +1871,7 @@
   Push                 r4
   LoadContextParent
   LoadContextVar       1, 8
-  DirectCall           4, CP#9
+  DirectCall           CP#9, 4
   PopLocal             r11
   PushNull
   ReturnTOS
@@ -1908,7 +1908,7 @@
   MoveSpecial          exception, r8
   MoveSpecial          stackTrace, r9
   PushConstant         CP#12
-  DirectCall           1, CP#13
+  DirectCall           CP#13, 1
   Drop1
   Push                 r8
   Push                 r9
@@ -1921,7 +1921,7 @@
   LoadContextVar       1, 7
   PopLocal             r4
   PushConstant         CP#12
-  DirectCall           1, CP#13
+  DirectCall           CP#13, 1
   Drop1
   Push                 r4
   LoadContextParent
@@ -1932,7 +1932,7 @@
   LoadContextVar       1, 0
   Push                 r4
   LoadContextVar       1, 1
-  DirectCall           2, CP#15
+  DirectCall           CP#15, 2
   Drop1
   PushNull
   ReturnTOS
@@ -1955,7 +1955,7 @@
   LoadContextVar       1, 0
   Push                 r8
   Push                 r9
-  InterfaceCall        3, CP#17
+  InterfaceCall        CP#17, 3
   Drop1
   Jump                 L5
 L5:
@@ -1989,7 +1989,7 @@
   AllocateT
   StoreLocal           r2
   Push                 r2
-  DirectCall           1, CP#2
+  DirectCall           CP#2, 1
   Drop1
   StoreContextVar      0, 1
   Push                 r0
@@ -2033,27 +2033,27 @@
   StoreContextVar      0, 8
   Push                 r0
   LoadContextVar       0, 8
-  DirectCall           1, CP#29
+  DirectCall           CP#29, 1
   PopLocal             r3
   Push                 r0
   Push                 r0
   LoadContextVar       0, 8
-  DirectCall           1, CP#31
+  DirectCall           CP#31, 1
   StoreContextVar      0, 3
   Push                 r0
   Push                 r0
   LoadContextVar       0, 8
-  DirectCall           1, CP#33
+  DirectCall           CP#33, 1
   StoreContextVar      0, 4
   Push                 r0
   LoadContextVar       0, 1
   Push                 r0
   LoadContextVar       0, 8
-  DynamicCall          2, CP#36
+  DynamicCall          CP#36, 2
   Drop1
   Push                 r0
   LoadContextVar       0, 1
-  InterfaceCall        1, CP#37
+  InterfaceCall        CP#37, 1
   ReturnTOS
 }
 ConstantPool {
@@ -2132,7 +2132,7 @@
   LoadContextVar       0, 4
   Push                 r4
   LoadContextVar       0, 8
-  DirectCall           4, CP#8
+  DirectCall           CP#8, 4
   PopLocal             r8
   PushNull
   ReturnTOS
@@ -2146,13 +2146,13 @@
   JumpIfNoAsserts      L2
   Push                 r1
   PushInt              42
-  InterfaceCall        2, CP#10
+  InterfaceCall        CP#10, 2
   AssertBoolean        0
   JumpIfTrue           L2
   PushInt              0
   PushInt              0
   PushNull
-  DirectCall           3, CP#12
+  DirectCall           CP#12, 3
   Drop1
 L2:
   Push                 r4
@@ -2164,7 +2164,7 @@
   LoadContextVar       0, 1
   Push                 r4
   LoadContextVar       0, 2
-  DirectCall           2, CP#14
+  DirectCall           CP#14, 2
   Drop1
   PushNull
   ReturnTOS
@@ -2187,7 +2187,7 @@
   LoadContextVar       0, 1
   Push                 r8
   Push                 r9
-  InterfaceCall        3, CP#17
+  InterfaceCall        CP#17, 3
   Drop1
   Jump                 L5
 L5:
diff --git a/pkg/vm/testcases/bytecode/bootstrapping.dart.expect b/pkg/vm/testcases/bytecode/bootstrapping.dart.expect
index a71a37a..e80bb9b 100644
--- a/pkg/vm/testcases/bytecode/bootstrapping.dart.expect
+++ b/pkg/vm/testcases/bytecode/bootstrapping.dart.expect
@@ -51,8 +51,8 @@
   Entry                0
   CheckStack           0
   Push                 FP[-5]
-  InterfaceCall        1, CP#0
-  DirectCall           1, CP#2
+  InterfaceCall        CP#0, 1
+  DirectCall           CP#2, 1
   Drop1
   PushNull
   ReturnTOS
@@ -134,13 +134,13 @@
   PushConstant         CP#0
   PushStatic           CP#0
   PushConstant         CP#1
-  InterfaceCall        2, CP#2
+  InterfaceCall        CP#2, 2
   AssertBoolean        0
   JumpIfTrue           L1
   PushConstant         CP#0
   PushStatic           CP#0
   PushConstant         CP#4
-  InterfaceCall        2, CP#2
+  InterfaceCall        CP#2, 2
   AssertBoolean        0
   PopLocal             r1
   Jump                 L2
@@ -153,7 +153,7 @@
   PushConstant         CP#0
   PushStatic           CP#0
   PushConstant         CP#5
-  InterfaceCall        2, CP#2
+  InterfaceCall        CP#2, 2
   AssertBoolean        0
   PopLocal             r0
   Jump                 L4
@@ -165,15 +165,15 @@
   JumpIfFalse          L5
   PushConstant         CP#0
   PushStatic           CP#0
-  DirectCall           1, CP#6
+  DirectCall           CP#6, 1
   ReturnTOS
 L5:
-  DirectCall           0, CP#8
+  DirectCall           CP#8, 0
   PushNull
   PushConstant         CP#0
   PushStatic           CP#0
-  DirectCall           2, CP#10
-  InterfaceCall        2, CP#12
+  DirectCall           CP#10, 2
+  InterfaceCall        CP#12, 2
   ReturnTOS
 }
 ConstantPool {
@@ -203,7 +203,7 @@
   Entry                1
   CheckStack           0
   PushConstant         CP#0
-  DirectCall           1, CP#1
+  DirectCall           CP#1, 1
   Drop1
   PushNull
   ReturnTOS
@@ -229,7 +229,7 @@
   JumpIfFalse          L1
   PushConstant         CP#1
   PushStatic           CP#1
-  DirectCall           1, CP#2
+  DirectCall           CP#2, 1
   StoreLocal           r1
   Push                 r1
   StoreStaticTOS       CP#0
@@ -289,7 +289,7 @@
   Entry                0
   CheckStack           0
   Push                 FP[-5]
-  DirectCall           1, CP#0
+  DirectCall           CP#0, 1
   Drop1
   PushNull
   ReturnTOS
@@ -324,7 +324,7 @@
   Entry                0
   CheckStack           0
   Push                 FP[-5]
-  DirectCall           1, CP#0
+  DirectCall           CP#0, 1
   Drop1
   PushNull
   ReturnTOS
@@ -397,10 +397,10 @@
   Allocate             CP#0
   StoreLocal           r1
   Push                 r1
-  DirectCall           1, CP#1
+  DirectCall           CP#1, 1
   Drop1
   Push                 FP[-5]
-  DirectCall           2, CP#3
+  DirectCall           CP#3, 2
   StoreStaticTOS       CP#5
   PushNull
   ReturnTOS
@@ -430,10 +430,10 @@
   Allocate             CP#1
   StoreLocal           r1
   Push                 r1
-  DirectCall           1, CP#2
+  DirectCall           CP#2, 1
   Drop1
-  DirectCall           0, CP#4
-  DirectCall           2, CP#6
+  DirectCall           CP#4, 0
+  DirectCall           CP#6, 2
   StoreStaticTOS       CP#0
 L1:
   PushConstant         CP#0
@@ -460,8 +460,8 @@
 Bytecode {
   Entry                0
   CheckStack           0
-  DirectCall           0, CP#0
-  DirectCall           1, CP#2
+  DirectCall           CP#0, 0
+  DirectCall           CP#2, 1
   ReturnTOS
 }
 ConstantPool {
@@ -511,7 +511,7 @@
   Entry                0
   CheckStack           0
   Push                 FP[-5]
-  DirectCall           1, CP#0
+  DirectCall           CP#0, 1
   Drop1
   PushNull
   ReturnTOS
@@ -531,7 +531,7 @@
   Entry                0
   CheckStack           0
   Push                 FP[-5]
-  DirectCall           1, CP#0
+  DirectCall           CP#0, 1
   Drop1
   PushNull
   ReturnTOS
@@ -550,7 +550,7 @@
 Bytecode {
   Entry                0
   CheckStack           0
-  DirectCall           0, CP#0
+  DirectCall           CP#0, 0
   ReturnTOS
 }
 ConstantPool {
@@ -567,7 +567,7 @@
 Bytecode {
   Entry                0
   CheckStack           0
-  DirectCall           0, CP#0
+  DirectCall           CP#0, 0
   ReturnTOS
 }
 ConstantPool {
@@ -636,7 +636,7 @@
   Entry                0
   CheckStack           0
   Push                 FP[-5]
-  DirectCall           1, CP#0
+  DirectCall           CP#0, 1
   Drop1
   PushNull
   ReturnTOS
@@ -694,7 +694,7 @@
   JumpIfFalse          L3
   PushConstant         CP#1
   PushStatic           CP#1
-  DynamicCall          1, CP#3
+  DynamicCall          CP#3, 1
   StoreStaticTOS       CP#0
 L3:
   PushConstant         CP#0
@@ -751,7 +751,7 @@
   Entry                0
   CheckStack           0
   Push                 FP[-5]
-  DirectCall           1, CP#0
+  DirectCall           CP#0, 1
   Drop1
   PushNull
   ReturnTOS
@@ -783,7 +783,7 @@
   Entry                0
   CheckStack           0
   Push                 FP[-5]
-  DirectCall           1, CP#0
+  DirectCall           CP#0, 1
   Drop1
   PushNull
   ReturnTOS
diff --git a/pkg/vm/testcases/bytecode/closures.dart.expect b/pkg/vm/testcases/bytecode/closures.dart.expect
index c168ee6..465e333 100644
--- a/pkg/vm/testcases/bytecode/closures.dart.expect
+++ b/pkg/vm/testcases/bytecode/closures.dart.expect
@@ -44,7 +44,7 @@
   PopLocal             r2
   Push                 r2
   PushInt              3
-  DynamicCall          2, CP#17
+  DynamicCall          CP#17, 2
   Drop1
   Push                 r0
   LoadContextVar       0, 0
@@ -160,8 +160,8 @@
   Push                 r0
   InstantiateType      CP#8
   StoreIndexedTOS
-  DirectCall           2, CP#9
-  DirectCall           1, CP#11
+  DirectCall           CP#9, 2
+  DirectCall           CP#11, 1
   Drop1
   PushNull
   ReturnTOS
@@ -197,9 +197,9 @@
   AllocateT
   StoreLocal           r0
   Push                 r0
-  DirectCall           1, CP#3
+  DirectCall           CP#3, 1
   Drop1
-  InterfaceCall        2, CP#5
+  InterfaceCall        CP#5, 2
   Drop1
   PushConstant         CP#7
   PushConstant         CP#2
@@ -207,9 +207,9 @@
   AllocateT
   StoreLocal           r0
   Push                 r0
-  DirectCall           1, CP#3
+  DirectCall           CP#3, 1
   Drop1
-  InterfaceCall        2, CP#5
+  InterfaceCall        CP#5, 2
   Drop1
   PushConstant         CP#7
   PushConstant         CP#8
@@ -217,9 +217,9 @@
   AllocateT
   StoreLocal           r0
   Push                 r0
-  DirectCall           1, CP#3
+  DirectCall           CP#3, 1
   Drop1
-  InterfaceCall        2, CP#5
+  InterfaceCall        CP#5, 2
   Drop1
   PushNull
   ReturnTOS
@@ -267,7 +267,7 @@
   StoreLocal           r3
   PushConstant         CP#18
   StoreLocal           r6
-  DirectCall           2, CP#19
+  DirectCall           CP#19, 2
   Drop1
   Allocate             CP#21
   StoreLocal           r5
@@ -340,7 +340,7 @@
   LoadFieldTOS         CP#6
   PushInt              0
   PushInt              1
-  DirectCall           4, CP#8
+  DirectCall           CP#8, 4
   PopLocal             r0
   Push                 FP[-5]
   PushConstant         CP#10
@@ -389,7 +389,7 @@
   Entry                0
   CheckStack           0
   Push                 FP[-5]
-  DirectCall           1, CP#0
+  DirectCall           CP#0, 1
   Drop1
   PushNull
   ReturnTOS
@@ -421,7 +421,7 @@
   Entry                0
   CheckStack           0
   Push                 FP[-5]
-  DirectCall           1, CP#0
+  DirectCall           CP#0, 1
   Drop1
   PushNull
   ReturnTOS
@@ -453,7 +453,7 @@
   Entry                0
   CheckStack           0
   Push                 FP[-5]
-  DirectCall           1, CP#0
+  DirectCall           CP#0, 1
   Drop1
   PushNull
   ReturnTOS
@@ -485,7 +485,7 @@
   Entry                0
   CheckStack           0
   Push                 FP[-5]
-  DirectCall           1, CP#0
+  DirectCall           CP#0, 1
   Drop1
   PushNull
   ReturnTOS
@@ -517,7 +517,7 @@
   Entry                0
   CheckStack           0
   Push                 FP[-5]
-  DirectCall           1, CP#0
+  DirectCall           CP#0, 1
   Drop1
   PushNull
   ReturnTOS
@@ -549,7 +549,7 @@
   Entry                0
   CheckStack           0
   Push                 FP[-5]
-  DirectCall           1, CP#0
+  DirectCall           CP#0, 1
   Drop1
   PushNull
   ReturnTOS
@@ -581,7 +581,7 @@
   Entry                0
   CheckStack           0
   Push                 FP[-5]
-  DirectCall           1, CP#0
+  DirectCall           CP#0, 1
   Drop1
   PushNull
   ReturnTOS
@@ -613,7 +613,7 @@
   Entry                0
   CheckStack           0
   Push                 FP[-5]
-  DirectCall           1, CP#0
+  DirectCall           CP#0, 1
   Drop1
   PushNull
   ReturnTOS
@@ -645,7 +645,7 @@
   Entry                0
   CheckStack           0
   Push                 FP[-5]
-  DirectCall           1, CP#0
+  DirectCall           CP#0, 1
   Drop1
   PushNull
   ReturnTOS
@@ -692,11 +692,11 @@
   PopLocal             r3
   PushConstant         CP#43
   Push                 r3
-  DynamicCall          2, CP#44
+  DynamicCall          CP#44, 2
   Drop1
   PushConstant         CP#45
   Push                 r3
-  DynamicCall          2, CP#46
+  DynamicCall          CP#46, 2
   Drop1
   PushNull
   ReturnTOS
@@ -772,7 +772,7 @@
   LoadFieldTOS         CP#6
   PushInt              2
   PushInt              4
-  DirectCall           4, CP#8
+  DirectCall           CP#8, 4
   PopLocal             r0
   AllocateClosure      CP#10
   StoreLocal           r4
@@ -796,11 +796,11 @@
   PopLocal             r3
   PushConstant         CP#37
   Push                 r3
-  DynamicCall          2, CP#39
+  DynamicCall          CP#39, 2
   Drop1
   PushConstant         CP#40
   Push                 r3
-  DynamicCall          2, CP#41
+  DynamicCall          CP#41, 2
   Drop1
   PushNull
   ReturnTOS
@@ -829,7 +829,7 @@
   LoadFieldTOS         CP#6
   PushInt              4
   PushInt              6
-  DirectCall           4, CP#8
+  DirectCall           CP#8, 4
   PopLocal             r0
   AllocateClosure      CP#11
   StoreLocal           r4
@@ -852,7 +852,7 @@
   StoreFieldTOS        CP#1
   PopLocal             r3
   Push                 r3
-  DynamicCall          1, CP#35
+  DynamicCall          CP#35, 1
   Drop1
   PushNull
   ReturnTOS
@@ -927,15 +927,15 @@
   Push                 r0
   InstantiateType      CP#21
   StoreIndexedTOS
-  DirectCall           2, CP#22
-  DirectCall           1, CP#24
+  DirectCall           CP#22, 2
+  DirectCall           CP#24, 1
   Drop1
   Push                 r1
   LoadContextVar       0, 0
   LoadTypeArgumentsField CP#14
   Push                 r0
   InstantiateTypeArgumentsTOS 0, CP#26
-  DirectCall           1, CP#27
+  DirectCall           CP#27, 1
   Drop1
   PushNull
   ReturnTOS
@@ -981,7 +981,7 @@
   Entry                0
   CheckStack           0
   Push                 FP[-5]
-  DirectCall           1, CP#0
+  DirectCall           CP#0, 1
   Drop1
   PushNull
   ReturnTOS
@@ -1034,22 +1034,22 @@
   PopLocal             r3
   Push                 r3
   PushInt              10
-  DynamicCall          2, CP#25
+  DynamicCall          CP#25, 2
   Drop1
   Push                 r3
   PushInt              11
-  DynamicCall          2, CP#26
+  DynamicCall          CP#26, 2
   Drop1
   Push                 r2
-  DirectCall           1, CP#21
+  DirectCall           CP#21, 1
   Drop1
   Push                 r0
   LoadContextVar       0, 2
-  DirectCall           1, CP#21
+  DirectCall           CP#21, 1
   Drop1
   Push                 r0
   LoadContextVar       0, 1
-  DirectCall           1, CP#21
+  DirectCall           CP#21, 1
   Drop1
   Push                 r0
   PushInt              42
@@ -1073,7 +1073,7 @@
   StoreFieldTOS        CP#1
   PopLocal             r2
   Push                 r2
-  DynamicCall          1, CP#31
+  DynamicCall          CP#31, 1
   Drop1
   PushNull
   ReturnTOS
@@ -1170,11 +1170,11 @@
   StoreFieldTOS        CP#1
   PopLocal             r3
   Push                 r3
-  DynamicCall          1, CP#20
+  DynamicCall          CP#20, 1
   Drop1
   Push                 r0
   LoadContextVar       1, 1
-  DirectCall           1, CP#21
+  DirectCall           CP#21, 1
   Drop1
 L1:
   PushNull
@@ -1201,7 +1201,7 @@
   Push                 r0
   LoadContextParent
   LoadContextVar       0, 0
-  InterfaceCall        1, CP#7
+  InterfaceCall        CP#7, 1
   Push                 r0
   LoadContextVar       1, 0
   AddInt
@@ -1222,7 +1222,7 @@
   LoadContextVar       0, 0
   Push                 r0
   LoadContextVar       0, 3
-  InterfaceCall        2, CP#28
+  InterfaceCall        CP#28, 2
   Drop1
   PushNull
   ReturnTOS
@@ -1285,7 +1285,7 @@
   Entry                0
   CheckStack           0
   Push                 FP[-5]
-  DirectCall           1, CP#0
+  DirectCall           CP#0, 1
   Drop1
   PushNull
   ReturnTOS
@@ -1311,11 +1311,11 @@
   StoreContextVar      0, 0
   PushConstant         CP#0
   PushConstant         CP#1
-  DirectCall           2, CP#2
+  DirectCall           CP#2, 2
   PopLocal             r2
   PushConstant         CP#0
   PushConstant         CP#1
-  DirectCall           2, CP#2
+  DirectCall           CP#2, 2
   PopLocal             r4
   AllocateContext      1, 1
   StoreLocal           r1
@@ -1351,7 +1351,7 @@
   Push                 r3
   Push                 r0
   StoreFieldTOS        CP#5
-  InterfaceCall        2, CP#17
+  InterfaceCall        CP#17, 2
   Drop1
   Push                 r4
   AllocateClosure      CP#19
@@ -1371,7 +1371,7 @@
   Push                 r3
   Push                 r0
   StoreFieldTOS        CP#5
-  InterfaceCall        2, CP#17
+  InterfaceCall        CP#17, 2
   Drop1
   Push                 r0
   CloneContext         1, 1
@@ -1475,18 +1475,18 @@
   Entry                5
   CheckStack           0
   Push                 FP[-5]
-  InterfaceCall        1, CP#0
+  InterfaceCall        CP#0, 1
   PopLocal             r2
 L2:
   CheckStack           1
   Push                 r2
-  InterfaceCall        1, CP#2
+  InterfaceCall        CP#2, 1
   JumpIfFalse          L1
   AllocateContext      0, 1
   PopLocal             r0
   Push                 r0
   Push                 r2
-  InterfaceCall        1, CP#4
+  InterfaceCall        CP#4, 1
   StoreContextVar      0, 0
   AllocateClosure      CP#6
   StoreLocal           r4
@@ -1507,11 +1507,11 @@
   StoreFieldTOS        CP#7
   PopLocal             r3
   Push                 r3
-  DynamicCall          1, CP#20
+  DynamicCall          CP#20, 1
   Drop1
   Push                 r0
   LoadContextVar       0, 0
-  DirectCall           1, CP#21
+  DirectCall           CP#21, 1
   Drop1
   Push                 r0
   LoadContextParent
@@ -1606,7 +1606,7 @@
   Entry                0
   CheckStack           0
   Push                 FP[-5]
-  DirectCall           1, CP#0
+  DirectCall           CP#0, 1
   Drop1
   PushNull
   ReturnTOS
@@ -1773,7 +1773,7 @@
   StoreFieldTOS        CP#1
   PopLocal             r2
   Push                 r2
-  DynamicCall          1, CP#16
+  DynamicCall          CP#16, 1
   Drop1
   PushNull
   ReturnTOS
diff --git a/pkg/vm/testcases/bytecode/deferred_lib.dart.expect b/pkg/vm/testcases/bytecode/deferred_lib.dart.expect
index 3974030..f4ef7c3 100644
--- a/pkg/vm/testcases/bytecode/deferred_lib.dart.expect
+++ b/pkg/vm/testcases/bytecode/deferred_lib.dart.expect
@@ -20,9 +20,9 @@
   Entry                1
   CheckStack           0
   PushNull
-  DirectCall           1, CP#0
+  DirectCall           CP#0, 1
   PopLocal             r0
-  DirectCall           0, CP#2
+  DirectCall           CP#2, 0
   ReturnTOS
 }
 ConstantPool {
@@ -42,7 +42,7 @@
   Entry                0
   CheckStack           0
   PushNull
-  DirectCall           1, CP#0
+  DirectCall           CP#0, 1
   ReturnTOS
 }
 ConstantPool {
diff --git a/pkg/vm/testcases/bytecode/field_initializers.dart.expect b/pkg/vm/testcases/bytecode/field_initializers.dart.expect
index b122da6..ee724e8 100644
--- a/pkg/vm/testcases/bytecode/field_initializers.dart.expect
+++ b/pkg/vm/testcases/bytecode/field_initializers.dart.expect
@@ -70,7 +70,7 @@
   PushInt              44
   StoreFieldTOS        CP#2
   Push                 FP[-6]
-  DirectCall           1, CP#6
+  DirectCall           CP#6, 1
   Drop1
   PushNull
   ReturnTOS
@@ -111,7 +111,7 @@
   AddInt
   StoreFieldTOS        CP#2
   Push                 FP[-7]
-  DirectCall           1, CP#6
+  DirectCall           CP#6, 1
   Drop1
   PushNull
   ReturnTOS
@@ -139,7 +139,7 @@
   CheckStack           0
   Push                 FP[-5]
   PushInt              45
-  DirectCall           2, CP#0
+  DirectCall           CP#0, 2
   Drop1
   PushNull
   ReturnTOS
@@ -163,7 +163,7 @@
   Push                 FP[-6]
   Push                 FP[-5]
   MulInt
-  DirectCall           3, CP#0
+  DirectCall           CP#0, 3
   Drop1
   PushNull
   ReturnTOS
@@ -221,7 +221,7 @@
   StoreFieldTOS        CP#0
   Push                 FP[-5]
   PushInt              49
-  DirectCall           2, CP#2
+  DirectCall           CP#2, 2
   Drop1
   PushNull
   ReturnTOS
@@ -252,7 +252,7 @@
   Push                 FP[-6]
   Push                 FP[-5]
   PushInt              51
-  DirectCall           4, CP#2
+  DirectCall           CP#2, 4
   Drop1
   PushNull
   ReturnTOS
diff --git a/pkg/vm/testcases/bytecode/hello.dart.expect b/pkg/vm/testcases/bytecode/hello.dart.expect
index ce754e8..aa15b42 100644
--- a/pkg/vm/testcases/bytecode/hello.dart.expect
+++ b/pkg/vm/testcases/bytecode/hello.dart.expect
@@ -20,7 +20,7 @@
   Entry                0
   CheckStack           0
   PushConstant         CP#0
-  DirectCall           1, CP#1
+  DirectCall           CP#1, 1
   Drop1
   PushNull
   ReturnTOS
diff --git a/pkg/vm/testcases/bytecode/instance_creation.dart.expect b/pkg/vm/testcases/bytecode/instance_creation.dart.expect
index b79b398..7243ab2 100644
--- a/pkg/vm/testcases/bytecode/instance_creation.dart.expect
+++ b/pkg/vm/testcases/bytecode/instance_creation.dart.expect
@@ -23,7 +23,7 @@
   StoreLocal           r0
   Push                 r0
   PushConstant         CP#1
-  DirectCall           2, CP#2
+  DirectCall           CP#2, 2
   Drop1
   ReturnTOS
 }
@@ -49,7 +49,7 @@
   StoreLocal           r0
   Push                 r0
   PushConstant         CP#2
-  DirectCall           2, CP#3
+  DirectCall           CP#3, 2
   Drop1
   Drop1
   PushConstant         CP#6
@@ -57,7 +57,7 @@
   AllocateT
   StoreLocal           r0
   Push                 r0
-  DirectCall           1, CP#7
+  DirectCall           CP#7, 1
   Drop1
   Drop1
   PushNull
@@ -93,7 +93,7 @@
   AllocateT
   StoreLocal           r1
   Push                 r1
-  DirectCall           1, CP#2
+  DirectCall           CP#2, 1
   Drop1
   Drop1
   PushNull
@@ -116,7 +116,7 @@
   Entry                0
   CheckStack           0
   PushConstant         CP#0
-  DirectCall           1, CP#1
+  DirectCall           CP#1, 1
   Drop1
   PushNull
   ReturnTOS
@@ -137,11 +137,11 @@
   Entry                0
   CheckStack           0
   PushNull
-  DirectCall           1, CP#0
+  DirectCall           CP#0, 1
   Drop1
   PushNull
   PushInt              42
-  DirectCall           2, CP#2
+  DirectCall           CP#2, 2
   Drop1
   PushNull
   ReturnTOS
@@ -164,7 +164,7 @@
   CheckStack           0
   PushConstant         CP#0
   PushInt              0
-  DirectCall           2, CP#1
+  DirectCall           CP#1, 2
   ReturnTOS
 }
 ConstantPool {
@@ -184,7 +184,7 @@
   CheckStack           0
   PushConstant         CP#0
   Push                 FP[-5]
-  DirectCall           2, CP#1
+  DirectCall           CP#1, 2
   ReturnTOS
 }
 ConstantPool {
@@ -202,12 +202,12 @@
 Bytecode {
   Entry                0
   CheckStack           0
-  DirectCall           0, CP#0
+  DirectCall           CP#0, 0
   Drop1
-  DirectCall           0, CP#2
+  DirectCall           CP#2, 0
   Drop1
   PushConstant         CP#4
-  DirectCall           1, CP#5
+  DirectCall           CP#5, 1
   Drop1
   PushNull
   ReturnTOS
@@ -246,7 +246,7 @@
   Entry                1
   CheckStack           0
   Push                 FP[-5]
-  DirectCall           1, CP#0
+  DirectCall           CP#0, 1
   Drop1
   PushNull
   PushInt              4
@@ -274,8 +274,8 @@
   PushNull
   InstantiateType      CP#6
   StoreIndexedTOS
-  DirectCall           1, CP#7
-  DirectCall           1, CP#9
+  DirectCall           CP#7, 1
+  DirectCall           CP#9, 1
   Drop1
   PushNull
   ReturnTOS
@@ -320,7 +320,7 @@
   Entry                0
   CheckStack           0
   Push                 FP[-6]
-  DirectCall           1, CP#0
+  DirectCall           CP#0, 1
   Drop1
   PushNull
   ReturnTOS
@@ -352,7 +352,7 @@
   Entry                1
   CheckStack           0
   Push                 FP[-5]
-  DirectCall           1, CP#0
+  DirectCall           CP#0, 1
   Drop1
   PushNull
   PushInt              2
@@ -369,8 +369,8 @@
   PushNull
   InstantiateType      CP#3
   StoreIndexedTOS
-  DirectCall           1, CP#5
-  DirectCall           1, CP#7
+  DirectCall           CP#5, 1
+  DirectCall           CP#7, 1
   Drop1
   PushNull
   ReturnTOS
@@ -410,7 +410,7 @@
   Entry                1
   CheckStack           0
   Push                 FP[-6]
-  DirectCall           1, CP#0
+  DirectCall           CP#0, 1
   Drop1
   PushNull
   PushInt              2
@@ -424,8 +424,8 @@
   PushInt              1
   Push                 FP[-5]
   StoreIndexedTOS
-  DirectCall           1, CP#3
-  DirectCall           1, CP#5
+  DirectCall           CP#3, 1
+  DirectCall           CP#5, 1
   Drop1
   PushNull
   ReturnTOS
@@ -463,7 +463,7 @@
   Entry                0
   CheckStack           0
   Push                 FP[-5]
-  DirectCall           1, CP#0
+  DirectCall           CP#0, 1
   Drop1
   PushNull
   ReturnTOS
@@ -484,7 +484,7 @@
   CheckStack           0
   Push                 FP[-5]
   LoadTypeArgumentsField CP#0
-  DirectCall           1, CP#1
+  DirectCall           CP#1, 1
   ReturnTOS
 }
 ConstantPool {
@@ -517,7 +517,7 @@
   Entry                0
   CheckStack           0
   Push                 FP[-5]
-  DirectCall           1, CP#0
+  DirectCall           CP#0, 1
   Drop1
   PushNull
   ReturnTOS
@@ -538,7 +538,7 @@
   CheckStack           0
   Push                 FP[-5]
   LoadTypeArgumentsField CP#0
-  DirectCall           1, CP#1
+  DirectCall           CP#1, 1
   ReturnTOS
 }
 ConstantPool {
@@ -571,7 +571,7 @@
   Entry                0
   CheckStack           0
   Push                 FP[-5]
-  DirectCall           1, CP#0
+  DirectCall           CP#0, 1
   Drop1
   PushNull
   ReturnTOS
@@ -598,7 +598,7 @@
   AllocateT
   StoreLocal           r0
   Push                 r0
-  DirectCall           1, CP#2
+  DirectCall           CP#2, 1
   Drop1
   ReturnTOS
 }
@@ -633,7 +633,7 @@
   Entry                0
   CheckStack           0
   Push                 FP[-5]
-  DirectCall           1, CP#0
+  DirectCall           CP#0, 1
   Drop1
   PushNull
   ReturnTOS
@@ -665,7 +665,7 @@
   Entry                0
   CheckStack           0
   Push                 FP[-6]
-  DirectCall           1, CP#0
+  DirectCall           CP#0, 1
   Drop1
   PushNull
   ReturnTOS
@@ -691,7 +691,7 @@
   StoreLocal           r2
   Push                 r2
   Push                 r1
-  DirectCall           2, CP#3
+  DirectCall           CP#3, 2
   Drop1
   ReturnTOS
 }
@@ -760,7 +760,7 @@
   AllocateT
   StoreLocal           r0
   Push                 r0
-  DirectCall           1, CP#1
+  DirectCall           CP#1, 1
   Drop1
   ReturnTOS
 }
@@ -791,7 +791,7 @@
   Entry                0
   CheckStack           0
   Push                 FP[-5]
-  DirectCall           1, CP#0
+  DirectCall           CP#0, 1
   Drop1
   PushNull
   ReturnTOS
diff --git a/pkg/vm/testcases/bytecode/literals.dart.expect b/pkg/vm/testcases/bytecode/literals.dart.expect
index bc4b45d..290438e 100644
--- a/pkg/vm/testcases/bytecode/literals.dart.expect
+++ b/pkg/vm/testcases/bytecode/literals.dart.expect
@@ -67,19 +67,19 @@
   Entry                0
   CheckStack           0
   PushConstant         CP#0
-  DirectCall           1, CP#1
+  DirectCall           CP#1, 1
   Drop1
   PushConstant         CP#3
-  DirectCall           1, CP#1
+  DirectCall           CP#1, 1
   Drop1
   PushInt              6
-  DirectCall           1, CP#1
+  DirectCall           CP#1, 1
   Drop1
   PushConstant         CP#4
-  DirectCall           1, CP#1
+  DirectCall           CP#1, 1
   Drop1
   PushConstant         CP#5
-  DirectCall           1, CP#1
+  DirectCall           CP#1, 1
   Drop1
   PushNull
   ReturnTOS
@@ -103,22 +103,22 @@
   Entry                0
   CheckStack           0
   PushInt              42
-  DirectCall           1, CP#0
+  DirectCall           CP#0, 1
   Drop1
   PushConstant         CP#2
-  DirectCall           1, CP#0
+  DirectCall           CP#0, 1
   Drop1
   PushConstant         CP#3
-  DirectCall           1, CP#0
+  DirectCall           CP#0, 1
   Drop1
   PushConstant         CP#4
-  DirectCall           1, CP#0
+  DirectCall           CP#0, 1
   Drop1
   PushConstant         CP#5
-  DirectCall           1, CP#0
+  DirectCall           CP#0, 1
   Drop1
   PushConstant         CP#6
-  DirectCall           1, CP#0
+  DirectCall           CP#0, 1
   Drop1
   PushNull
   ReturnTOS
@@ -160,8 +160,8 @@
   PushInt              2
   PushInt              3
   StoreIndexedTOS
-  DirectCall           2, CP#1
-  DirectCall           1, CP#3
+  DirectCall           CP#1, 2
+  DirectCall           CP#3, 1
   Drop1
   PushConstant         CP#5
   StoreLocal           r0
@@ -176,14 +176,14 @@
   Push                 r0
   PushInt              1
   Push                 FP[-5]
-  InterfaceCall        1, CP#7
+  InterfaceCall        CP#7, 1
   StoreIndexedTOS
   Push                 r0
   PushInt              2
   PushConstant         CP#9
   StoreIndexedTOS
-  DirectCall           2, CP#1
-  DirectCall           1, CP#3
+  DirectCall           CP#1, 2
+  DirectCall           CP#3, 1
   Drop1
   PushNull
   ReturnTOS
@@ -233,8 +233,8 @@
   PushInt              3
   PushInt              2
   StoreIndexedTOS
-  DirectCall           2, CP#2
-  DirectCall           1, CP#4
+  DirectCall           CP#2, 2
+  DirectCall           CP#4, 1
   Drop1
   PushConstant         CP#6
   PushConstant         CP#1
@@ -252,21 +252,21 @@
   Push                 r1
   PushInt              2
   Push                 FP[-6]
-  InterfaceCall        1, CP#8
+  InterfaceCall        CP#8, 1
   StoreIndexedTOS
   Push                 r1
   PushInt              3
   PushInt              3
   StoreIndexedTOS
-  DirectCall           2, CP#2
-  DirectCall           1, CP#4
+  DirectCall           CP#2, 2
+  DirectCall           CP#4, 1
   Drop1
   PushNull
   Push                 r0
   InstantiateTypeArgumentsTOS 0, CP#10
   PushConstant         CP#11
-  DirectCall           2, CP#2
-  DirectCall           1, CP#4
+  DirectCall           CP#2, 2
+  DirectCall           CP#4, 1
   Drop1
   PushNull
   Push                 r0
@@ -283,8 +283,8 @@
   PushInt              1
   PushInt              4
   StoreIndexedTOS
-  DirectCall           2, CP#2
-  DirectCall           1, CP#4
+  DirectCall           CP#2, 2
+  DirectCall           CP#4, 1
   Drop1
   PushNull
   ReturnTOS
@@ -315,10 +315,10 @@
   Entry                0
   CheckStack           0
   PushConstant         CP#0
-  DirectCall           1, CP#1
+  DirectCall           CP#1, 1
   Drop1
   PushConstant         CP#3
-  DirectCall           1, CP#1
+  DirectCall           CP#1, 1
   Drop1
   PushNull
   ReturnTOS
@@ -342,12 +342,12 @@
   CheckStack           0
   CheckFunctionTypeArgs 1, r0
   PushConstant         CP#0
-  DirectCall           1, CP#1
+  DirectCall           CP#1, 1
   Drop1
   PushNull
   Push                 r0
   InstantiateType      CP#3
-  DirectCall           1, CP#1
+  DirectCall           CP#1, 1
   Drop1
   PushNull
   ReturnTOS
@@ -519,7 +519,7 @@
   Push                 FP[-5]
   StoreFieldTOS        CP#2
   Push                 FP[-7]
-  DirectCall           1, CP#4
+  DirectCall           CP#4, 1
   Drop1
   PushNull
   ReturnTOS
@@ -543,7 +543,7 @@
   Entry                0
   CheckStack           0
   Push                 FP[-5]
-  DirectCall           1, CP#0
+  DirectCall           CP#0, 1
   ReturnTOS
 }
 ConstantPool {
@@ -587,7 +587,7 @@
   Push                 FP[-5]
   StoreFieldTOS        CP#0
   Push                 FP[-6]
-  DirectCall           1, CP#2
+  DirectCall           CP#2, 1
   Drop1
   PushNull
   ReturnTOS
@@ -632,7 +632,7 @@
   Push                 FP[-5]
   PushInt              5
   MulInt
-  DirectCall           2, CP#2
+  DirectCall           CP#2, 2
   Drop1
   PushNull
   ReturnTOS
@@ -680,7 +680,7 @@
   Push                 r2
   StoreFieldTOS        CP#3
   Push                 r0
-  DirectCall           1, CP#5
+  DirectCall           CP#5, 1
   Drop1
   PushNull
   ReturnTOS
@@ -719,7 +719,7 @@
   Entry                0
   CheckStack           0
   Push                 FP[-5]
-  DirectCall           1, CP#0
+  DirectCall           CP#0, 1
   Drop1
   PushNull
   ReturnTOS
@@ -751,7 +751,7 @@
   Entry                0
   CheckStack           0
   Push                 FP[-5]
-  DirectCall           1, CP#0
+  DirectCall           CP#0, 1
   Drop1
   PushNull
   ReturnTOS
diff --git a/pkg/vm/testcases/bytecode/loops.dart.expect b/pkg/vm/testcases/bytecode/loops.dart.expect
index d4b5acb..99ac193 100644
--- a/pkg/vm/testcases/bytecode/loops.dart.expect
+++ b/pkg/vm/testcases/bytecode/loops.dart.expect
@@ -27,13 +27,13 @@
   CheckStack           1
   Push                 r1
   Push                 FP[-5]
-  InterfaceCall        1, CP#0
+  InterfaceCall        CP#0, 1
   CompareIntLt
   JumpIfFalse          L1
   Push                 r0
   Push                 FP[-5]
   Push                 r1
-  InterfaceCall        2, CP#2
+  InterfaceCall        CP#2, 2
   AddInt
   PopLocal             r0
   Push                 r1
@@ -74,7 +74,7 @@
   JumpIfFalse          L1
   Push                 r1
   Push                 FP[-5]
-  InterfaceCall        1, CP#0
+  InterfaceCall        CP#0, 1
   CompareIntGe
   JumpIfFalse          L2
   Jump                 L1
@@ -82,7 +82,7 @@
   Push                 r0
   Push                 FP[-5]
   Push                 r1
-  InterfaceCall        2, CP#2
+  InterfaceCall        CP#2, 2
   AddInt
   PopLocal             r0
   Push                 r1
@@ -120,7 +120,7 @@
   CheckStack           1
   Push                 r1
   Push                 FP[-5]
-  InterfaceCall        1, CP#0
+  InterfaceCall        CP#0, 1
   CompareIntLt
   JumpIfFalse          L1
   Push                 r1
@@ -132,7 +132,7 @@
   Push                 r0
   Push                 FP[-5]
   Push                 r1
-  InterfaceCall        2, CP#2
+  InterfaceCall        CP#2, 2
   AddInt
   PopLocal             r0
 L3:
@@ -170,7 +170,7 @@
   CheckStack           1
   Push                 r1
   Push                 FP[-5]
-  InterfaceCall        1, CP#0
+  InterfaceCall        CP#0, 1
   CompareIntLt
   JumpIfFalse          L1
   Push                 r0
@@ -183,7 +183,7 @@
   StoreLocal           r1
   PopLocal             r3
   Push                 r2
-  InterfaceCall        2, CP#2
+  InterfaceCall        CP#2, 2
   AddInt
   PopLocal             r0
   Jump                 L2
@@ -216,7 +216,7 @@
   Push                 r0
   Push                 FP[-5]
   Push                 r1
-  InterfaceCall        2, CP#0
+  InterfaceCall        CP#0, 2
   AddInt
   PopLocal             r0
   Push                 r1
@@ -225,7 +225,7 @@
   PopLocal             r1
   Push                 r1
   Push                 FP[-5]
-  InterfaceCall        1, CP#2
+  InterfaceCall        CP#2, 1
   CompareIntLt
   JumpIfTrue           L1
   Push                 r0
@@ -250,15 +250,15 @@
   PushInt              0
   PopLocal             r0
   Push                 FP[-5]
-  InterfaceCall        1, CP#0
+  InterfaceCall        CP#0, 1
   PopLocal             r1
 L2:
   CheckStack           1
   Push                 r1
-  InterfaceCall        1, CP#2
+  InterfaceCall        CP#2, 1
   JumpIfFalse          L1
   Push                 r1
-  InterfaceCall        1, CP#4
+  InterfaceCall        CP#4, 1
   PopLocal             r2
   Push                 r0
   Push                 r2
@@ -292,15 +292,15 @@
   PushInt              42
   PopLocal             r1
   Push                 FP[-5]
-  InterfaceCall        1, CP#0
+  InterfaceCall        CP#0, 1
   PopLocal             r2
 L2:
   CheckStack           1
   Push                 r2
-  InterfaceCall        1, CP#2
+  InterfaceCall        CP#2, 1
   JumpIfFalse          L1
   Push                 r2
-  InterfaceCall        1, CP#4
+  InterfaceCall        CP#4, 1
   PopLocal             r3
   Push                 r3
   PopLocal             r1
diff --git a/pkg/vm/testcases/bytecode/optional_params.dart.expect b/pkg/vm/testcases/bytecode/optional_params.dart.expect
index 3ff8087..49156f2 100644
--- a/pkg/vm/testcases/bytecode/optional_params.dart.expect
+++ b/pkg/vm/testcases/bytecode/optional_params.dart.expect
@@ -34,8 +34,8 @@
   PushInt              1
   Push                 r0
   StoreIndexedTOS
-  DirectCall           1, CP#3
-  DirectCall           1, CP#5
+  DirectCall           CP#3, 1
+  DirectCall           CP#5, 1
   Drop1
   PushNull
   PushInt              2
@@ -49,8 +49,8 @@
   PushInt              1
   Push                 r1
   StoreIndexedTOS
-  DirectCall           1, CP#3
-  DirectCall           1, CP#5
+  DirectCall           CP#3, 1
+  DirectCall           CP#5, 1
   Drop1
   PushNull
   PushInt              2
@@ -64,8 +64,8 @@
   PushInt              1
   Push                 r2
   StoreIndexedTOS
-  DirectCall           1, CP#3
-  DirectCall           1, CP#5
+  DirectCall           CP#3, 1
+  DirectCall           CP#5, 1
   Drop1
   PushNull
   ReturnTOS
@@ -110,8 +110,8 @@
   PushInt              1
   Push                 r0
   StoreIndexedTOS
-  DirectCall           1, CP#7
-  DirectCall           1, CP#9
+  DirectCall           CP#7, 1
+  DirectCall           CP#9, 1
   Drop1
   PushNull
   PushInt              2
@@ -125,8 +125,8 @@
   PushInt              1
   Push                 r1
   StoreIndexedTOS
-  DirectCall           1, CP#7
-  DirectCall           1, CP#9
+  DirectCall           CP#7, 1
+  DirectCall           CP#9, 1
   Drop1
   PushNull
   PushInt              2
@@ -140,8 +140,8 @@
   PushInt              1
   Push                 r2
   StoreIndexedTOS
-  DirectCall           1, CP#7
-  DirectCall           1, CP#9
+  DirectCall           CP#7, 1
+  DirectCall           CP#9, 1
   Drop1
   PushNull
   PushInt              2
@@ -155,8 +155,8 @@
   PushInt              1
   Push                 r3
   StoreIndexedTOS
-  DirectCall           1, CP#7
-  DirectCall           1, CP#9
+  DirectCall           CP#7, 1
+  DirectCall           CP#9, 1
   Drop1
   PushNull
   PushInt              2
@@ -170,8 +170,8 @@
   PushInt              1
   Push                 r4
   StoreIndexedTOS
-  DirectCall           1, CP#7
-  DirectCall           1, CP#9
+  DirectCall           CP#7, 1
+  DirectCall           CP#9, 1
   Drop1
   PushNull
   ReturnTOS
@@ -213,13 +213,13 @@
   PushNull
   Push                 r4
   InstantiateType      CP#4
-  DirectCall           1, CP#5
+  DirectCall           CP#5, 1
   Drop1
   Push                 r1
-  DirectCall           1, CP#5
+  DirectCall           CP#5, 1
   Drop1
   Push                 r3
-  DirectCall           1, CP#5
+  DirectCall           CP#5, 1
   Drop1
   PushNull
   ReturnTOS
@@ -245,12 +245,12 @@
   CheckStack           0
   PushConstant         CP#0
   PushConstant         CP#1
-  DirectCall           2, CP#2
+  DirectCall           CP#2, 2
   Drop1
   PushConstant         CP#4
   PushConstant         CP#5
   PushConstant         CP#1
-  DirectCall           3, CP#6
+  DirectCall           CP#6, 3
   Drop1
   PushNull
   ReturnTOS
diff --git a/pkg/vm/testcases/bytecode/super_calls.dart.expect b/pkg/vm/testcases/bytecode/super_calls.dart.expect
index 286cf41..31ff703 100644
--- a/pkg/vm/testcases/bytecode/super_calls.dart.expect
+++ b/pkg/vm/testcases/bytecode/super_calls.dart.expect
@@ -44,7 +44,7 @@
   Entry                0
   CheckStack           0
   Push                 FP[-5]
-  DirectCall           1, CP#0
+  DirectCall           CP#0, 1
   Drop1
   PushNull
   ReturnTOS
@@ -127,7 +127,7 @@
   Entry                0
   CheckStack           0
   Push                 FP[-5]
-  DirectCall           1, CP#0
+  DirectCall           CP#0, 1
   Drop1
   PushNull
   ReturnTOS
@@ -150,7 +150,7 @@
   Push                 FP[-6]
   PushConstant         CP#1
   PushInt              2
-  DirectCall           4, CP#2
+  DirectCall           CP#2, 4
   ReturnTOS
 }
 ConstantPool {
@@ -170,7 +170,7 @@
   Entry                1
   CheckStack           0
   Push                 FP[-5]
-  DirectCall           1, CP#0
+  DirectCall           CP#0, 1
   ReturnTOS
 }
 ConstantPool {
@@ -188,7 +188,7 @@
   Entry                1
   CheckStack           0
   Push                 FP[-5]
-  DirectCall           1, CP#0
+  DirectCall           CP#0, 1
   ReturnTOS
 }
 ConstantPool {
@@ -207,9 +207,9 @@
   CheckStack           0
   PushConstant         CP#0
   Push                 FP[-5]
-  DirectCall           1, CP#1
+  DirectCall           CP#1, 1
   PushConstant         CP#3
-  DynamicCall          3, CP#5
+  DynamicCall          CP#5, 3
   ReturnTOS
 }
 ConstantPool {
@@ -232,7 +232,7 @@
   CheckStack           0
   Push                 FP[-5]
   PushInt              3
-  DirectCall           2, CP#0
+  DirectCall           CP#0, 2
   Drop1
   PushNull
   ReturnTOS
@@ -275,7 +275,7 @@
   Entry                0
   CheckStack           0
   Push                 FP[-5]
-  DirectCall           1, CP#0
+  DirectCall           CP#0, 1
   Drop1
   PushNull
   ReturnTOS
@@ -323,7 +323,7 @@
   Entry                0
   CheckStack           0
   Push                 FP[-5]
-  DirectCall           1, CP#0
+  DirectCall           CP#0, 1
   Drop1
   PushNull
   ReturnTOS
@@ -370,8 +370,8 @@
   PushInt              5
   StoreIndexedTOS
   PushTrue
-  DirectCall           4, CP#6
-  DirectCall           2, CP#8
+  DirectCall           CP#6, 4
+  DirectCall           CP#8, 2
   ReturnTOS
 }
 ConstantPool {
@@ -408,8 +408,8 @@
   Push                 FP[-5]
   StoreIndexedTOS
   PushTrue
-  DirectCall           4, CP#3
-  DirectCall           2, CP#5
+  DirectCall           CP#3, 4
+  DirectCall           CP#5, 2
   ReturnTOS
 }
 ConstantPool {
@@ -443,8 +443,8 @@
   Push                 FP[-5]
   StoreIndexedTOS
   PushTrue
-  DirectCall           4, CP#3
-  DirectCall           2, CP#5
+  DirectCall           CP#3, 4
+  DirectCall           CP#5, 2
   ReturnTOS
 }
 ConstantPool {
@@ -479,10 +479,10 @@
   Push                 FP[-5]
   StoreIndexedTOS
   PushTrue
-  DirectCall           4, CP#4
-  DirectCall           2, CP#6
+  DirectCall           CP#4, 4
+  DirectCall           CP#6, 2
   PushConstant         CP#8
-  DynamicCall          3, CP#10
+  DynamicCall          CP#10, 3
   ReturnTOS
 }
 ConstantPool {
@@ -524,8 +524,8 @@
   PushInt              3
   StoreIndexedTOS
   PushTrue
-  DirectCall           4, CP#3
-  DirectCall           2, CP#5
+  DirectCall           CP#3, 4
+  DirectCall           CP#5, 2
   Drop1
   PushNull
   ReturnTOS
diff --git a/pkg/vm/testcases/bytecode/switch.dart.expect b/pkg/vm/testcases/bytecode/switch.dart.expect
index b7ca049..80a1682 100644
--- a/pkg/vm/testcases/bytecode/switch.dart.expect
+++ b/pkg/vm/testcases/bytecode/switch.dart.expect
@@ -25,15 +25,15 @@
   PopLocal             r1
   Push                 r1
   PushInt              1
-  InterfaceCall        2, CP#0
+  InterfaceCall        CP#0, 2
   JumpIfTrue           L1
   Push                 r1
   PushInt              2
-  InterfaceCall        2, CP#0
+  InterfaceCall        CP#0, 2
   JumpIfTrue           L2
   Push                 r1
   PushInt              3
-  InterfaceCall        2, CP#0
+  InterfaceCall        CP#0, 2
   JumpIfTrue           L3
   Jump                 L4
 L1:
@@ -72,27 +72,27 @@
   PopLocal             r1
   Push                 r1
   PushInt              1
-  InterfaceCall        2, CP#0
+  InterfaceCall        CP#0, 2
   JumpIfTrue           L1
   Push                 r1
   PushInt              2
-  InterfaceCall        2, CP#0
+  InterfaceCall        CP#0, 2
   JumpIfTrue           L1
   Push                 r1
   PushInt              3
-  InterfaceCall        2, CP#0
+  InterfaceCall        CP#0, 2
   JumpIfTrue           L1
   Push                 r1
   PushInt              4
-  InterfaceCall        2, CP#0
+  InterfaceCall        CP#0, 2
   JumpIfTrue           L2
   Push                 r1
   PushInt              5
-  InterfaceCall        2, CP#0
+  InterfaceCall        CP#0, 2
   JumpIfTrue           L2
   Push                 r1
   PushInt              6
-  InterfaceCall        2, CP#0
+  InterfaceCall        CP#0, 2
   JumpIfTrue           L2
   Jump                 L3
 L1:
@@ -130,27 +130,27 @@
   PopLocal             r1
   Push                 r1
   PushInt              1
-  InterfaceCall        2, CP#0
+  InterfaceCall        CP#0, 2
   JumpIfTrue           L1
   Push                 r1
   PushInt              2
-  InterfaceCall        2, CP#0
+  InterfaceCall        CP#0, 2
   JumpIfTrue           L1
   Push                 r1
   PushInt              3
-  InterfaceCall        2, CP#0
+  InterfaceCall        CP#0, 2
   JumpIfTrue           L1
   Push                 r1
   PushInt              4
-  InterfaceCall        2, CP#0
+  InterfaceCall        CP#0, 2
   JumpIfTrue           L2
   Push                 r1
   PushInt              5
-  InterfaceCall        2, CP#0
+  InterfaceCall        CP#0, 2
   JumpIfTrue           L2
   Push                 r1
   PushInt              6
-  InterfaceCall        2, CP#0
+  InterfaceCall        CP#0, 2
   JumpIfTrue           L2
   Jump                 L3
 L1:
diff --git a/pkg/vm/testcases/bytecode/try_blocks.dart.expect b/pkg/vm/testcases/bytecode/try_blocks.dart.expect
index 126eae9..3527e207 100644
--- a/pkg/vm/testcases/bytecode/try_blocks.dart.expect
+++ b/pkg/vm/testcases/bytecode/try_blocks.dart.expect
@@ -21,7 +21,7 @@
   CheckStack           0
 Try #0 start:
   PushConstant         CP#0
-  DirectCall           1, CP#1
+  DirectCall           CP#1, 1
   Drop1
   Jump                 L1
 Try #0 end:
@@ -43,8 +43,8 @@
   PushInt              1
   Push                 r2
   StoreIndexedTOS
-  DirectCall           1, CP#5
-  DirectCall           1, CP#1
+  DirectCall           CP#5, 1
+  DirectCall           CP#1, 1
   Drop1
   Jump                 L1
 L1:
@@ -52,7 +52,7 @@
   ReturnTOS
 }
 ExceptionsTable {
-  try-index 0, outer -1, start 2, end 6, handler 6, types [CP#3]
+  try-index 0, outer -1, start 4, end 14, handler 14, types [CP#3]
 }
 ConstantPool {
   [0] = ObjectRef 'danger!'
@@ -75,7 +75,7 @@
   CheckStack           0
 Try #0 start:
   PushConstant         CP#0
-  DirectCall           1, CP#1
+  DirectCall           CP#1, 1
   Drop1
   Jump                 L1
 Try #0 end:
@@ -85,16 +85,16 @@
   MoveSpecial          stackTrace, r1
   Push                 r0
   PushConstant         CP#3
-  InterfaceCall        2, CP#4
+  InterfaceCall        CP#4, 2
   JumpIfFalse          L2
   PushConstant         CP#6
-  DirectCall           1, CP#1
+  DirectCall           CP#1, 1
   Drop1
   Jump                 L1
 L2:
   Push                 r0
   PushConstant         CP#7
-  InterfaceCall        2, CP#4
+  InterfaceCall        CP#4, 2
   JumpIfFalse          L3
   Push                 r0
   PopLocal             r2
@@ -110,14 +110,14 @@
   PushInt              1
   Push                 r2
   StoreIndexedTOS
-  DirectCall           1, CP#9
-  DirectCall           1, CP#1
+  DirectCall           CP#9, 1
+  DirectCall           CP#1, 1
   Drop1
   Jump                 L1
 L3:
   Push                 r0
   PushConstant         CP#11
-  InterfaceCall        2, CP#4
+  InterfaceCall        CP#4, 2
   JumpIfFalse          L4
   Push                 r0
   PopLocal             r2
@@ -143,8 +143,8 @@
   PushInt              3
   Push                 r3
   StoreIndexedTOS
-  DirectCall           1, CP#9
-  DirectCall           1, CP#1
+  DirectCall           CP#9, 1
+  DirectCall           CP#1, 1
   Drop1
   Jump                 L1
 L4:
@@ -172,8 +172,8 @@
   PushInt              3
   Push                 r3
   StoreIndexedTOS
-  DirectCall           1, CP#9
-  DirectCall           1, CP#1
+  DirectCall           CP#9, 1
+  DirectCall           CP#1, 1
   Drop1
   Jump                 L1
 L1:
@@ -181,7 +181,7 @@
   ReturnTOS
 }
 ExceptionsTable {
-  try-index 0, outer -1, start 2, end 6, handler 6, needs-stack-trace, types [CP#3, CP#7, CP#11, CP#14]
+  try-index 0, outer -1, start 4, end 14, handler 14, needs-stack-trace, types [CP#3, CP#7, CP#11, CP#14]
 }
 ConstantPool {
   [0] = ObjectRef 'danger!'
@@ -241,11 +241,11 @@
   StoreFieldTOS        CP#1
   PopLocal             r4
   Push                 r4
-  DynamicCall          1, CP#18
+  DynamicCall          CP#18, 1
   Drop1
   Push                 r0
   LoadContextVar       0, 1
-  DirectCall           1, CP#4
+  DirectCall           CP#4, 1
   Drop1
   Jump                 L1
 Try #0 end:
@@ -281,8 +281,8 @@
   Push                 r0
   LoadContextVar       0, 2
   StoreIndexedTOS
-  DirectCall           1, CP#21
-  DirectCall           1, CP#4
+  DirectCall           CP#21, 1
+  DirectCall           CP#4, 1
   Drop1
   AllocateClosure      CP#23
   StoreLocal           r5
@@ -312,7 +312,7 @@
   ReturnTOS
 }
 ExceptionsTable {
-  try-index 0, outer -1, start 9, end 38, handler 38, needs-stack-trace, types [CP#6]
+  try-index 0, outer -1, start 20, end 80, handler 80, needs-stack-trace, types [CP#6]
 }
 ConstantPool {
   [0] = ClosureFunction 0
@@ -358,7 +358,7 @@
   PopLocal             r2
 Try #0 start:
   PushConstant         CP#3
-  DirectCall           1, CP#4
+  DirectCall           CP#4, 1
   Drop1
   Jump                 L1
 Try #0 end:
@@ -372,7 +372,7 @@
   PopLocal             r4
   Push                 r0
   LoadContextVar       0, 0
-  DirectCall           1, CP#4
+  DirectCall           CP#4, 1
   Drop1
   Push                 r0
   PushInt              3
@@ -395,7 +395,7 @@
   PopLocal             r2
 Try #0 start:
   PushConstant         CP#24
-  DirectCall           1, CP#4
+  DirectCall           CP#4, 1
   Drop1
   Jump                 L1
 Try #0 end:
@@ -407,7 +407,7 @@
   MoveSpecial          stackTrace, r3
   Push                 r2
   PushConstant         CP#25
-  InterfaceCall        2, CP#26
+  InterfaceCall        CP#26, 2
   JumpIfFalse          L2
   Push                 r2
   PopLocal             r4
@@ -432,8 +432,8 @@
   Push                 r0
   LoadContextVar       0, 2
   StoreIndexedTOS
-  DirectCall           1, CP#21
-  DirectCall           1, CP#4
+  DirectCall           CP#21, 1
+  DirectCall           CP#4, 1
   Drop1
   Jump                 L1
 L2:
@@ -458,7 +458,7 @@
 Try #0 start:
 Try #1 start:
   PushConstant         CP#0
-  DirectCall           1, CP#1
+  DirectCall           CP#1, 1
   Drop1
   Jump                 L1
 Try #1 end:
@@ -470,7 +470,7 @@
   PopLocal             r4
 Try #2 start:
   PushConstant         CP#4
-  DirectCall           1, CP#1
+  DirectCall           CP#1, 1
   Drop1
   Push                 FP[-5]
   AssertBoolean        0
@@ -488,7 +488,7 @@
   Push                 r5
   PopLocal             r7
   PushConstant         CP#5
-  DirectCall           1, CP#1
+  DirectCall           CP#1, 1
   Drop1
   Jump                 L3
 L3:
@@ -505,10 +505,10 @@
   Push                 r1
   PopLocal             r3
   PushConstant         CP#6
-  DirectCall           1, CP#1
+  DirectCall           CP#1, 1
   Drop1
   Push                 r3
-  DirectCall           1, CP#1
+  DirectCall           CP#1, 1
   Drop1
   Jump                 L4
 L4:
@@ -516,9 +516,9 @@
   ReturnTOS
 }
 ExceptionsTable {
-  try-index 0, outer -1, start 2, end 32, handler 32, needs-stack-trace, types [CP#3]
-  try-index 1, outer 0, start 2, end 6, handler 6, needs-stack-trace, types [CP#3]
-  try-index 2, outer 0, start 11, end 21, handler 21, types [CP#3]
+  try-index 0, outer -1, start 4, end 80, handler 80, needs-stack-trace, types [CP#3]
+  try-index 1, outer 0, start 4, end 14, handler 14, needs-stack-trace, types [CP#3]
+  try-index 2, outer 0, start 26, end 50, handler 50, types [CP#3]
 }
 ConstantPool {
   [0] = ObjectRef 'try 1 > try 2'
@@ -561,19 +561,19 @@
   MoveSpecial          exception, r1
   MoveSpecial          stackTrace, r2
   Push                 r0
-  DirectCall           1, CP#1
+  DirectCall           CP#1, 1
   Drop1
   Push                 r1
   Push                 r2
   Throw                1
 L3:
   Push                 r0
-  DirectCall           1, CP#1
+  DirectCall           CP#1, 1
   Drop1
   Jump                 L1
 L4:
   Push                 r0
-  DirectCall           1, CP#1
+  DirectCall           CP#1, 1
   Drop1
   Push                 r0
   PushInt              1
@@ -586,7 +586,7 @@
   ReturnTOS
 }
 ExceptionsTable {
-  try-index 0, outer -1, start 9, end 15, handler 15, needs-stack-trace, types [CP#0]
+  try-index 0, outer -1, start 19, end 36, handler 36, needs-stack-trace, types [CP#0]
 }
 ConstantPool {
   [0] = Type dynamic
@@ -613,11 +613,11 @@
   PopLocal             r2
   Push                 r2
   PushInt              1
-  InterfaceCall        2, CP#0
+  InterfaceCall        CP#0, 2
   JumpIfTrue           L1
   Push                 r2
   PushInt              2
-  InterfaceCall        2, CP#0
+  InterfaceCall        CP#0, 2
   JumpIfTrue           L2
   Jump                 L3
 L1:
@@ -625,7 +625,7 @@
   PopLocal             r3
 Try #0 start:
   PushConstant         CP#2
-  DirectCall           1, CP#3
+  DirectCall           CP#3, 1
   Drop1
   Push                 r0
   PushInt              3
@@ -634,7 +634,7 @@
   PopLocal             r5
 Try #1 start:
   PushConstant         CP#5
-  DirectCall           1, CP#3
+  DirectCall           CP#3, 1
   Drop1
   AllocateClosure      CP#6
   StoreLocal           r8
@@ -655,7 +655,7 @@
   StoreFieldTOS        CP#7
   PopLocal             r7
   Push                 r7
-  DynamicCall          1, CP#20
+  DynamicCall          CP#20, 1
   Drop1
   Jump                 L4
 Try #1 end:
@@ -666,7 +666,7 @@
   MoveSpecial          exception, r5
   MoveSpecial          stackTrace, r6
   PushConstant         CP#22
-  DirectCall           1, CP#3
+  DirectCall           CP#3, 1
   Drop1
   Push                 r5
   Push                 r6
@@ -675,7 +675,7 @@
   Push                 r5
   PopLocal             r0
   PushConstant         CP#22
-  DirectCall           1, CP#3
+  DirectCall           CP#3, 1
   Drop1
   Jump                 L5
 Try #0 end:
@@ -686,7 +686,7 @@
   MoveSpecial          exception, r3
   MoveSpecial          stackTrace, r4
   PushConstant         CP#24
-  DirectCall           1, CP#3
+  DirectCall           CP#3, 1
   Drop1
   Push                 r3
   Push                 r4
@@ -695,12 +695,12 @@
   Push                 r3
   PopLocal             r0
   PushConstant         CP#24
-  DirectCall           1, CP#3
+  DirectCall           CP#3, 1
   Drop1
   Jump                 L2
 L2:
   PushConstant         CP#25
-  DirectCall           1, CP#3
+  DirectCall           CP#3, 1
   Drop1
   Jump                 L3
 L3:
@@ -708,8 +708,8 @@
   ReturnTOS
 }
 ExceptionsTable {
-  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]
+  try-index 0, outer -1, start 53, end 158, handler 158, needs-stack-trace, types [CP#21]
+  try-index 1, outer 0, start 70, end 120, handler 120, needs-stack-trace, types [CP#21]
 }
 ConstantPool {
   [0] = InterfaceCall 'dart:core::Object::==', ArgDesc num-args 2, num-type-args 0, names []
@@ -748,11 +748,11 @@
   PopLocal             r0
   Push                 r0
   LoadContextVar       0, 0
-  DirectCall           1, CP#3
+  DirectCall           CP#3, 1
   Drop1
   Push                 r0
   LoadContextVar       0, 1
-  DirectCall           1, CP#3
+  DirectCall           CP#3, 1
   Drop1
   PushNull
   ReturnTOS
@@ -806,10 +806,10 @@
   MoveSpecial          stackTrace, r4
   Push                 r0
   LoadContextVar       0, 0
-  DirectCall           1, CP#3
+  DirectCall           CP#3, 1
   Drop1
   Push                 r2
-  DynamicCall          1, CP#19
+  DynamicCall          CP#19, 1
   Drop1
   Push                 r3
   Push                 r4
@@ -819,10 +819,10 @@
   PopLocal             r0
   Push                 r0
   LoadContextVar       0, 0
-  DirectCall           1, CP#3
+  DirectCall           CP#3, 1
   Drop1
   Push                 r2
-  DynamicCall          1, CP#20
+  DynamicCall          CP#20, 1
   Drop1
   Push                 r0
   LoadContextParent
@@ -831,7 +831,7 @@
   ReturnTOS
 }
 ExceptionsTable {
-  try-index 0, outer -1, start 11, end 30, handler 30, needs-stack-trace, types [CP#6]
+  try-index 0, outer -1, start 23, end 61, handler 61, needs-stack-trace, types [CP#6]
 }
 ConstantPool {
   [0] = ClosureFunction 0
@@ -865,13 +865,13 @@
   PopLocal             r0
   Push                 r0
   LoadContextVar       0, 0
-  DirectCall           1, CP#3
+  DirectCall           CP#3, 1
   Drop1
   Push                 r0
   PopLocal             r2
 Try #0 start:
   PushConstant         CP#5
-  DirectCall           1, CP#3
+  DirectCall           CP#3, 1
   Drop1
   Jump                 L1
 Try #0 end:
@@ -885,7 +885,7 @@
   PopLocal             r4
 Try #1 start:
   PushConstant         CP#7
-  DirectCall           1, CP#3
+  DirectCall           CP#3, 1
   Drop1
   Jump                 L2
 Try #1 end:
@@ -897,7 +897,7 @@
   MoveSpecial          stackTrace, r5
   Push                 r0
   LoadContextVar       0, 0
-  DirectCall           1, CP#3
+  DirectCall           CP#3, 1
   Drop1
   Push                 r4
   Push                 r5
@@ -907,7 +907,7 @@
   PopLocal             r0
   Push                 r0
   LoadContextVar       0, 0
-  DirectCall           1, CP#3
+  DirectCall           CP#3, 1
   Drop1
   PushInt              43
   ReturnTOS
@@ -918,7 +918,7 @@
   PopLocal             r4
 Try #2 start:
   PushConstant         CP#7
-  DirectCall           1, CP#3
+  DirectCall           CP#3, 1
   Drop1
   Jump                 L3
 Try #2 end:
@@ -930,7 +930,7 @@
   MoveSpecial          stackTrace, r5
   Push                 r0
   LoadContextVar       0, 0
-  DirectCall           1, CP#3
+  DirectCall           CP#3, 1
   Drop1
   Push                 r4
   Push                 r5
@@ -940,7 +940,7 @@
   PopLocal             r0
   Push                 r0
   LoadContextVar       0, 0
-  DirectCall           1, CP#3
+  DirectCall           CP#3, 1
   Drop1
   PushInt              43
   ReturnTOS
@@ -959,7 +959,7 @@
 Try #0 start:
 Try #1 start:
   PushConstant         CP#0
-  DirectCall           1, CP#1
+  DirectCall           CP#1, 1
   Drop1
   Jump                 L1
 Try #1 end:
@@ -970,7 +970,7 @@
   Push                 r2
   PopLocal             r4
   PushConstant         CP#4
-  DirectCall           1, CP#1
+  DirectCall           CP#1, 1
   Drop1
   Jump                 L1
 L1:
@@ -981,21 +981,21 @@
   MoveSpecial          exception, r0
   MoveSpecial          stackTrace, r1
   PushConstant         CP#5
-  DirectCall           1, CP#1
+  DirectCall           CP#1, 1
   Drop1
   Push                 r0
   Push                 r1
   Throw                1
 L2:
   PushConstant         CP#5
-  DirectCall           1, CP#1
+  DirectCall           CP#1, 1
   Drop1
   PushNull
   ReturnTOS
 }
 ExceptionsTable {
-  try-index 0, outer -1, start 2, end 16, handler 16, needs-stack-trace, types [CP#3]
-  try-index 1, outer 0, start 2, end 6, handler 6, types [CP#3]
+  try-index 0, outer -1, start 4, end 40, handler 40, needs-stack-trace, types [CP#3]
+  try-index 1, outer 0, start 4, end 14, handler 14, types [CP#3]
 }
 ConstantPool {
   [0] = ObjectRef 'try'
diff --git a/pkg/vm/testcases/bytecode/type_ops.dart.expect b/pkg/vm/testcases/bytecode/type_ops.dart.expect
index 22da680..ca572e8 100644
--- a/pkg/vm/testcases/bytecode/type_ops.dart.expect
+++ b/pkg/vm/testcases/bytecode/type_ops.dart.expect
@@ -23,20 +23,20 @@
   CheckStack           0
   Push                 FP[-5]
   PushConstant         CP#0
-  InterfaceCall        2, CP#1
+  InterfaceCall        CP#1, 2
   JumpIfFalse          L1
   PushConstant         CP#3
-  DirectCall           1, CP#4
+  DirectCall           CP#4, 1
   Drop1
 L1:
   Push                 FP[-5]
   PushNull
   PushNull
   PushConstant         CP#6
-  InterfaceCall        4, CP#7
+  InterfaceCall        CP#7, 4
   JumpIfFalse          L2
   PushConstant         CP#9
-  DirectCall           1, CP#4
+  DirectCall           CP#4, 1
   Drop1
 L2:
   Push                 FP[-5]
@@ -123,7 +123,7 @@
   Entry                0
   CheckStack           0
   Push                 FP[-5]
-  DirectCall           1, CP#0
+  DirectCall           CP#0, 1
   Drop1
   PushNull
   ReturnTOS
@@ -155,7 +155,7 @@
   Entry                0
   CheckStack           0
   Push                 FP[-5]
-  DirectCall           1, CP#0
+  DirectCall           CP#0, 1
   Drop1
   PushNull
   ReturnTOS
@@ -187,7 +187,7 @@
   Entry                0
   CheckStack           0
   Push                 FP[-5]
-  DirectCall           1, CP#0
+  DirectCall           CP#0, 1
   Drop1
   PushNull
   ReturnTOS
@@ -230,7 +230,7 @@
   AssertAssignable     0, CP#3
   StoreFieldTOS        CP#4
   Push                 FP[-6]
-  DirectCall           1, CP#6
+  DirectCall           CP#6, 1
   Drop1
   PushNull
   ReturnTOS
@@ -260,10 +260,10 @@
   LoadTypeArgumentsField CP#0
   PushNull
   PushConstant         CP#1
-  InterfaceCall        4, CP#2
+  InterfaceCall        CP#2, 4
   JumpIfFalse          L1
   PushConstant         CP#4
-  DirectCall           1, CP#5
+  DirectCall           CP#5, 1
   Drop1
 L1:
   Push                 FP[-5]
@@ -271,10 +271,10 @@
   LoadTypeArgumentsField CP#0
   PushNull
   PushConstant         CP#7
-  InterfaceCall        4, CP#2
+  InterfaceCall        CP#2, 4
   JumpIfFalse          L2
   PushConstant         CP#8
-  DirectCall           1, CP#5
+  DirectCall           CP#5, 1
   Drop1
 L2:
   Push                 FP[-6]
@@ -285,7 +285,7 @@
   PushNull
   PushConstant         CP#10
   AssertAssignable     0, CP#11
-  UncheckedInterfaceCall 2, CP#12
+  UncheckedInterfaceCall CP#12, 2
   Drop1
   PushNull
   ReturnTOS
@@ -322,10 +322,10 @@
   PushNull
   Push                 r0
   PushConstant         CP#0
-  InterfaceCall        4, CP#1
+  InterfaceCall        CP#1, 4
   JumpIfFalse          L1
   PushConstant         CP#3
-  DirectCall           1, CP#4
+  DirectCall           CP#4, 1
   Drop1
 L1:
   Push                 FP[-5]
@@ -333,10 +333,10 @@
   LoadTypeArgumentsField CP#6
   Push                 r0
   PushConstant         CP#7
-  InterfaceCall        4, CP#1
+  InterfaceCall        CP#1, 4
   JumpIfFalse          L2
   PushConstant         CP#8
-  DirectCall           1, CP#4
+  DirectCall           CP#4, 1
   Drop1
 L2:
   Push                 FP[-5]
@@ -346,7 +346,7 @@
   Push                 r0
   PushConstant         CP#10
   AssertAssignable     0, CP#11
-  InterfaceCall        1, CP#12
+  InterfaceCall        CP#12, 1
   ReturnTOS
 }
 ConstantPool {
@@ -394,7 +394,7 @@
   PushConstant         CP#3
   AssertAssignable     0, CP#4
   StoreIndexedTOS
-  DirectCall           2, CP#5
+  DirectCall           CP#5, 2
   PopLocal             r0
   Push                 FP[-5]
   PushConstant         CP#2
diff --git a/runtime/PRESUBMIT.py b/runtime/PRESUBMIT.py
index 44c53df..e790a8b 100644
--- a/runtime/PRESUBMIT.py
+++ b/runtime/PRESUBMIT.py
@@ -21,7 +21,7 @@
   match = re.search('\\bmemcpy\\b', content)
   if match:
     line_number = content[0:match.start()].count('\n') + 1
-    print "%s:%d: use of memcpy is forbidden" % (filename, line_number)
+    print("%s:%d: use of memcpy is forbidden" % (filename, line_number))
     return 1
   return 0
 
diff --git a/runtime/bin/BUILD.gn b/runtime/bin/BUILD.gn
index 7c93362..5b5cacc 100644
--- a/runtime/bin/BUILD.gn
+++ b/runtime/bin/BUILD.gn
@@ -839,31 +839,6 @@
   }
 }
 
-dart_executable("dart_precompiled_runtime_for_linking") {
-  extra_configs = [ "..:dart_precompiled_runtime_config" ]
-  extra_deps = [
-    "..:libdart_precompiled_runtime",
-    "../platform:libdart_platform_precompiled_runtime",
-  ]
-  if (dart_runtime_mode != "release") {
-    extra_deps += [ "../observatory:standalone_observatory_archive" ]
-  }
-  extra_sources = [
-    "builtin.cc",
-    "gzip.cc",
-    "gzip.h",
-    "loader.cc",
-    "loader.h",
-    "main.cc",
-    "snapshot_empty.cc",
-  ]
-  if (dart_runtime_mode == "release") {
-    extra_sources += [ "observatory_assets_empty.cc" ]
-  }
-  extra_defines = [ "DART_LINK_APP_SNAPSHOT" ]
-  target_type = "static_library"
-}
-
 dart_executable("dartaotruntime") {
   extra_configs = [ "..:dart_precompiled_runtime_config" ]
   extra_deps = [
diff --git a/runtime/bin/cli_sources.gni b/runtime/bin/cli_sources.gni
index 532fbba..ed72a04 100644
--- a/runtime/bin/cli_sources.gni
+++ b/runtime/bin/cli_sources.gni
@@ -3,4 +3,4 @@
 # BSD-style license that can be found in the LICENSE file.
 
 # This file contains all sources for the dart:cli library.
-cli_runtime_sources = [ "cli_patch.dart" ]
+cli_runtime_dart_files = [ "cli_patch.dart" ]
diff --git a/runtime/bin/crypto_android.cc b/runtime/bin/crypto_android.cc
index 6af505f..6db66eb 100644
--- a/runtime/bin/crypto_android.cc
+++ b/runtime/bin/crypto_android.cc
@@ -17,8 +17,8 @@
 
 bool Crypto::GetRandomBytes(intptr_t count, uint8_t* buffer) {
   ThreadSignalBlocker signal_blocker(SIGPROF);
-  intptr_t fd =
-      TEMP_FAILURE_RETRY_NO_SIGNAL_BLOCKER(open("/dev/urandom", O_RDONLY));
+  intptr_t fd = TEMP_FAILURE_RETRY_NO_SIGNAL_BLOCKER(
+      open("/dev/urandom", O_RDONLY | O_CLOEXEC));
   if (fd < 0) {
     return false;
   }
diff --git a/runtime/bin/crypto_linux.cc b/runtime/bin/crypto_linux.cc
index 9a14ee3..d3af9e0 100644
--- a/runtime/bin/crypto_linux.cc
+++ b/runtime/bin/crypto_linux.cc
@@ -17,8 +17,8 @@
 
 bool Crypto::GetRandomBytes(intptr_t count, uint8_t* buffer) {
   ThreadSignalBlocker signal_blocker(SIGPROF);
-  intptr_t fd =
-      TEMP_FAILURE_RETRY_NO_SIGNAL_BLOCKER(open("/dev/urandom", O_RDONLY));
+  intptr_t fd = TEMP_FAILURE_RETRY_NO_SIGNAL_BLOCKER(
+      open("/dev/urandom", O_RDONLY | O_CLOEXEC));
   if (fd < 0) {
     return false;
   }
diff --git a/runtime/bin/crypto_macos.cc b/runtime/bin/crypto_macos.cc
index 5d0690e..e5bf130 100644
--- a/runtime/bin/crypto_macos.cc
+++ b/runtime/bin/crypto_macos.cc
@@ -17,8 +17,8 @@
 
 bool Crypto::GetRandomBytes(intptr_t count, uint8_t* buffer) {
   ThreadSignalBlocker signal_blocker(SIGPROF);
-  intptr_t fd =
-      TEMP_FAILURE_RETRY_NO_SIGNAL_BLOCKER(open("/dev/urandom", O_RDONLY));
+  intptr_t fd = TEMP_FAILURE_RETRY_NO_SIGNAL_BLOCKER(
+      open("/dev/urandom", O_RDONLY | O_CLOEXEC));
   if (fd < 0) {
     return false;
   }
diff --git a/runtime/bin/eventhandler_fuchsia.cc b/runtime/bin/eventhandler_fuchsia.cc
index 9f10a7e..837b7a0 100644
--- a/runtime/bin/eventhandler_fuchsia.cc
+++ b/runtime/bin/eventhandler_fuchsia.cc
@@ -76,7 +76,7 @@
 namespace bin {
 
 intptr_t IOHandle::Read(void* buffer, intptr_t num_bytes) {
-  MutexLocker ml(mutex_);
+  MutexLocker ml(&mutex_);
   const ssize_t read_bytes = NO_RETRY_EXPECTED(read(fd_, buffer, num_bytes));
   const int err = errno;
   LOG_INFO("IOHandle::Read: fd = %ld. read %ld bytes\n", fd_, read_bytes);
@@ -105,7 +105,7 @@
 }
 
 intptr_t IOHandle::Write(const void* buffer, intptr_t num_bytes) {
-  MutexLocker ml(mutex_);
+  MutexLocker ml(&mutex_);
   const ssize_t written_bytes =
       NO_RETRY_EXPECTED(write(fd_, buffer, num_bytes));
   const int err = errno;
@@ -122,7 +122,7 @@
 }
 
 intptr_t IOHandle::Accept(struct sockaddr* addr, socklen_t* addrlen) {
-  MutexLocker ml(mutex_);
+  MutexLocker ml(&mutex_);
   const intptr_t socket = NO_RETRY_EXPECTED(accept(fd_, addr, addrlen));
   const int err = errno;
   LOG_INFO("IOHandle::Accept: fd = %ld. socket = %ld\n", fd_, socket);
@@ -138,7 +138,7 @@
 }
 
 intptr_t IOHandle::AvailableBytes() {
-  MutexLocker ml(mutex_);
+  MutexLocker ml(&mutex_);
   ASSERT(fd_ >= 0);
   intptr_t available = FDUtils::AvailableBytes(fd_);
   LOG_INFO("IOHandle::AvailableBytes(): fd = %ld, bytes = %ld\n", fd_,
@@ -153,12 +153,12 @@
 }
 
 void IOHandle::Close() {
-  MutexLocker ml(mutex_);
+  MutexLocker ml(&mutex_);
   VOID_NO_RETRY_EXPECTED(close(fd_));
 }
 
 uint32_t IOHandle::MaskToEpollEvents(intptr_t mask) {
-  MutexLocker ml(mutex_);
+  MutexLocker ml(&mutex_);
   // Do not ask for POLLERR and POLLHUP explicitly as they are
   // triggered anyway.
   uint32_t events = POLLRDHUP;
@@ -230,12 +230,12 @@
 }
 
 bool IOHandle::AsyncWait(zx_handle_t port, uint32_t events, uint64_t key) {
-  MutexLocker ml(mutex_);
+  MutexLocker ml(&mutex_);
   return AsyncWaitLocked(port, events, key);
 }
 
 void IOHandle::CancelWait(zx_handle_t port, uint64_t key) {
-  MutexLocker ml(mutex_);
+  MutexLocker ml(&mutex_);
   LOG_INFO("IOHandle::CancelWait: fd = %ld\n", fd_);
   ASSERT(port != ZX_HANDLE_INVALID);
   ASSERT(handle_ != ZX_HANDLE_INVALID);
@@ -246,14 +246,14 @@
 }
 
 uint32_t IOHandle::WaitEnd(zx_signals_t observed) {
-  MutexLocker ml(mutex_);
+  MutexLocker ml(&mutex_);
   uint32_t events = 0;
   fdio_unsafe_wait_end(fdio_, observed, &events);
   return events;
 }
 
 intptr_t IOHandle::ToggleEvents(intptr_t event_mask) {
-  MutexLocker ml(mutex_);
+  MutexLocker ml(&mutex_);
   if (!write_events_enabled_) {
     LOG_INFO("IOHandle::ToggleEvents: fd = %ld de-asserting write\n", fd_);
     event_mask = event_mask & ~(1 << kOutEvent);
diff --git a/runtime/bin/eventhandler_fuchsia.h b/runtime/bin/eventhandler_fuchsia.h
index 0ff514b..07acef97 100644
--- a/runtime/bin/eventhandler_fuchsia.h
+++ b/runtime/bin/eventhandler_fuchsia.h
@@ -31,7 +31,7 @@
  public:
   explicit IOHandle(intptr_t fd)
       : ReferenceCounted(),
-        mutex_(new Mutex()),
+        mutex_(),
         write_events_enabled_(true),
         read_events_enabled_(true),
         fd_(fd),
@@ -65,13 +65,12 @@
     if (fdio_ != NULL) {
       fdio_unsafe_release(fdio_);
     }
-    delete mutex_;
   }
 
   bool AsyncWaitLocked(zx_handle_t port, uint32_t events, uint64_t key);
 
   // Mutex that protects the state here.
-  Mutex* mutex_;
+  Mutex mutex_;
   bool write_events_enabled_;
   bool read_events_enabled_;
   // Bytes remaining to be read from the socket. Read events should only be
diff --git a/runtime/bin/eventhandler_win.cc b/runtime/bin/eventhandler_win.cc
index f9f25de..37b4f28 100644
--- a/runtime/bin/eventhandler_win.cc
+++ b/runtime/bin/eventhandler_win.cc
@@ -116,10 +116,9 @@
       read_thread_handle_(NULL),
       read_thread_starting_(false),
       read_thread_finished_(false),
-      monitor_(new Monitor()) {}
+      monitor_() {}
 
 Handle::~Handle() {
-  delete monitor_;
 }
 
 bool Handle::CreateCompletionPort(HANDLE completion_port) {
@@ -133,7 +132,7 @@
 }
 
 void Handle::Close() {
-  MonitorLocker ml(monitor_);
+  MonitorLocker ml(&monitor_);
   if (!SupportsOverlappedIO()) {
     // If the handle uses synchronous I/O (e.g. stdin), cancel any pending
     // operation before closing the handle, so the read thread is not blocked.
@@ -174,7 +173,7 @@
 }
 
 void Handle::WaitForReadThreadStarted() {
-  MonitorLocker ml(monitor_);
+  MonitorLocker ml(&monitor_);
   while (read_thread_starting_) {
     ml.Wait();
   }
@@ -183,7 +182,7 @@
 void Handle::WaitForReadThreadFinished() {
   HANDLE to_join = NULL;
   {
-    MonitorLocker ml(monitor_);
+    MonitorLocker ml(&monitor_);
     if (read_thread_id_ != Thread::kInvalidThreadId) {
       while (!read_thread_finished_) {
         ml.Wait();
@@ -205,7 +204,7 @@
 void Handle::ReadComplete(OverlappedBuffer* buffer) {
   WaitForReadThreadStarted();
   {
-    MonitorLocker ml(monitor_);
+    MonitorLocker ml(&monitor_);
     // Currently only one outstanding read at the time.
     ASSERT(pending_read_ == buffer);
     ASSERT(data_ready_ == NULL);
@@ -224,7 +223,7 @@
 }
 
 void Handle::WriteComplete(OverlappedBuffer* buffer) {
-  MonitorLocker ml(monitor_);
+  MonitorLocker ml(&monitor_);
   // Currently only one outstanding write at the time.
   ASSERT(pending_write_ == buffer);
   OverlappedBuffer::DisposeBuffer(buffer);
@@ -237,7 +236,7 @@
 }
 
 void Handle::NotifyReadThreadStarted() {
-  MonitorLocker ml(monitor_);
+  MonitorLocker ml(&monitor_);
   ASSERT(read_thread_starting_);
   ASSERT(read_thread_id_ == Thread::kInvalidThreadId);
   read_thread_id_ = Thread::GetCurrentThreadId();
@@ -247,7 +246,7 @@
 }
 
 void Handle::NotifyReadThreadFinished() {
-  MonitorLocker ml(monitor_);
+  MonitorLocker ml(&monitor_);
   ASSERT(!read_thread_finished_);
   ASSERT(read_thread_id_ != Thread::kInvalidThreadId);
   read_thread_finished_ = true;
@@ -315,7 +314,7 @@
 }
 
 bool Handle::IssueWrite() {
-  MonitorLocker ml(monitor_);
+  MonitorLocker ml(&monitor_);
   ASSERT(type_ != kListenSocket);
   ASSERT(completion_port_ != INVALID_HANDLE_VALUE);
   ASSERT(HasPendingWrite());
@@ -365,7 +364,7 @@
 }
 
 void FileHandle::EnsureInitialized(EventHandlerImplementation* event_handler) {
-  MonitorLocker ml(monitor_);
+  MonitorLocker ml(&monitor_);
   event_handler_ = event_handler;
   if (completion_port_ == INVALID_HANDLE_VALUE) {
     if (SupportsOverlappedIO()) {
@@ -386,7 +385,7 @@
 
 void DirectoryWatchHandle::EnsureInitialized(
     EventHandlerImplementation* event_handler) {
-  MonitorLocker ml(monitor_);
+  MonitorLocker ml(&monitor_);
   event_handler_ = event_handler;
   if (completion_port_ == INVALID_HANDLE_VALUE) {
     CreateCompletionPort(event_handler_->completion_port());
@@ -418,7 +417,7 @@
 }
 
 void DirectoryWatchHandle::Stop() {
-  MonitorLocker ml(monitor_);
+  MonitorLocker ml(&monitor_);
   // Stop the outstanding read, so we can close the handle.
 
   if (HasPendingRead()) {
@@ -450,7 +449,7 @@
 }
 
 bool ListenSocket::IssueAccept() {
-  MonitorLocker ml(monitor_);
+  MonitorLocker ml(&monitor_);
 
   // For AcceptEx there needs to be buffer storage for address
   // information for two addresses (local and remote address). The
@@ -485,7 +484,7 @@
 
 void ListenSocket::AcceptComplete(OverlappedBuffer* buffer,
                                   HANDLE completion_port) {
-  MonitorLocker ml(monitor_);
+  MonitorLocker ml(&monitor_);
   if (!IsClosing()) {
     // Update the accepted socket to support the full range of API calls.
     SOCKET s = socket();
@@ -556,12 +555,12 @@
 }
 
 bool ListenSocket::CanAccept() {
-  MonitorLocker ml(monitor_);
+  MonitorLocker ml(&monitor_);
   return accepted_head_ != NULL;
 }
 
 ClientSocket* ListenSocket::Accept() {
-  MonitorLocker ml(monitor_);
+  MonitorLocker ml(&monitor_);
 
   ClientSocket* result = NULL;
 
@@ -589,7 +588,7 @@
 
 void ListenSocket::EnsureInitialized(
     EventHandlerImplementation* event_handler) {
-  MonitorLocker ml(monitor_);
+  MonitorLocker ml(&monitor_);
   if (AcceptEx_ == NULL) {
     ASSERT(completion_port_ == INVALID_HANDLE_VALUE);
     ASSERT(event_handler_ == NULL);
@@ -604,7 +603,7 @@
 }
 
 intptr_t Handle::Available() {
-  MonitorLocker ml(monitor_);
+  MonitorLocker ml(&monitor_);
   if (data_ready_ == NULL) {
     return 0;
   }
@@ -613,7 +612,7 @@
 }
 
 intptr_t Handle::Read(void* buffer, intptr_t num_bytes) {
-  MonitorLocker ml(monitor_);
+  MonitorLocker ml(&monitor_);
   if (data_ready_ == NULL) {
     return 0;
   }
@@ -633,7 +632,7 @@
                           intptr_t num_bytes,
                           struct sockaddr* sa,
                           socklen_t sa_len) {
-  MonitorLocker ml(monitor_);
+  MonitorLocker ml(&monitor_);
   if (data_ready_ == NULL) {
     return 0;
   }
@@ -658,7 +657,7 @@
 }
 
 intptr_t Handle::Write(const void* buffer, intptr_t num_bytes) {
-  MonitorLocker ml(monitor_);
+  MonitorLocker ml(&monitor_);
   if (HasPendingWrite()) {
     return 0;
   }
@@ -682,7 +681,7 @@
                         intptr_t num_bytes,
                         struct sockaddr* sa,
                         socklen_t sa_len) {
-  MonitorLocker ml(monitor_);
+  MonitorLocker ml(&monitor_);
   if (HasPendingWrite()) {
     return 0;
   }
@@ -718,7 +717,7 @@
 }
 
 void StdHandle::RunWriteLoop() {
-  MonitorLocker ml(monitor_);
+  MonitorLocker ml(&monitor_);
   write_thread_running_ = true;
   thread_id_ = Thread::GetCurrentThreadId();
   thread_handle_ = OpenThread(SYNCHRONIZE, false, thread_id_);
@@ -757,7 +756,7 @@
 }
 
 intptr_t StdHandle::Write(const void* buffer, intptr_t num_bytes) {
-  MonitorLocker ml(monitor_);
+  MonitorLocker ml(&monitor_);
   if (HasPendingWrite()) {
     return 0;
   }
@@ -803,7 +802,7 @@
 
 void StdHandle::DoClose() {
   {
-    MonitorLocker ml(monitor_);
+    MonitorLocker ml(&monitor_);
     if (write_thread_exists_) {
       write_thread_running_ = false;
       ml.Notify();
@@ -859,7 +858,7 @@
 }
 
 bool ClientSocket::IssueRead() {
-  MonitorLocker ml(monitor_);
+  MonitorLocker ml(&monitor_);
   ASSERT(completion_port_ != INVALID_HANDLE_VALUE);
   ASSERT(!HasPendingRead());
 
@@ -882,7 +881,7 @@
 }
 
 bool ClientSocket::IssueWrite() {
-  MonitorLocker ml(monitor_);
+  MonitorLocker ml(&monitor_);
   ASSERT(completion_port_ != INVALID_HANDLE_VALUE);
   ASSERT(HasPendingWrite());
   ASSERT(pending_write_->operation() == OverlappedBuffer::kWrite);
@@ -950,7 +949,7 @@
 
 void ClientSocket::EnsureInitialized(
     EventHandlerImplementation* event_handler) {
-  MonitorLocker ml(monitor_);
+  MonitorLocker ml(&monitor_);
   if (completion_port_ == INVALID_HANDLE_VALUE) {
     ASSERT(event_handler_ == NULL);
     event_handler_ = event_handler;
@@ -963,7 +962,7 @@
 }
 
 bool DatagramSocket::IssueSendTo(struct sockaddr* sa, socklen_t sa_len) {
-  MonitorLocker ml(monitor_);
+  MonitorLocker ml(&monitor_);
   ASSERT(completion_port_ != INVALID_HANDLE_VALUE);
   ASSERT(HasPendingWrite());
   ASSERT(pending_write_->operation() == OverlappedBuffer::kSendTo);
@@ -980,7 +979,7 @@
 }
 
 bool DatagramSocket::IssueRecvFrom() {
-  MonitorLocker ml(monitor_);
+  MonitorLocker ml(&monitor_);
   ASSERT(completion_port_ != INVALID_HANDLE_VALUE);
   ASSERT(!HasPendingRead());
 
@@ -1004,7 +1003,7 @@
 
 void DatagramSocket::EnsureInitialized(
     EventHandlerImplementation* event_handler) {
-  MonitorLocker ml(monitor_);
+  MonitorLocker ml(&monitor_);
   if (completion_port_ == INVALID_HANDLE_VALUE) {
     ASSERT(event_handler_ == NULL);
     event_handler_ = event_handler;
@@ -1045,7 +1044,7 @@
       ListenSocket* listen_socket = reinterpret_cast<ListenSocket*>(handle);
       listen_socket->EnsureInitialized(this);
 
-      MonitorLocker ml(listen_socket->monitor_);
+      MonitorLocker ml(&listen_socket->monitor_);
 
       if (IS_COMMAND(msg->data, kReturnTokenCommand)) {
         listen_socket->ReturnTokens(msg->dart_port, TOKEN_COUNT(msg->data));
@@ -1077,7 +1076,7 @@
       }
     } else {
       handle->EnsureInitialized(this);
-      MonitorLocker ml(handle->monitor_);
+      MonitorLocker ml(&handle->monitor_);
 
       if (IS_COMMAND(msg->data, kReturnTokenCommand)) {
         handle->ReturnTokens(msg->dart_port, TOKEN_COUNT(msg->data));
@@ -1151,7 +1150,7 @@
   listen_socket->AcceptComplete(buffer, completion_port_);
 
   {
-    MonitorLocker ml(listen_socket->monitor_);
+    MonitorLocker ml(&listen_socket->monitor_);
     TryDispatchingPendingAccepts(listen_socket);
   }
 
@@ -1346,7 +1345,6 @@
 }
 
 EventHandlerImplementation::EventHandlerImplementation() {
-  startup_monitor_ = new Monitor();
   handler_thread_id_ = Thread::kInvalidThreadId;
   handler_thread_handle_ = NULL;
   completion_port_ =
@@ -1362,7 +1360,6 @@
   DWORD res = WaitForSingleObject(handler_thread_handle_, INFINITE);
   CloseHandle(handler_thread_handle_);
   ASSERT(res == WAIT_OBJECT_0);
-  delete startup_monitor_;
   CloseHandle(completion_port_);
 }
 
@@ -1395,7 +1392,7 @@
   ASSERT(handler_impl != NULL);
 
   {
-    MonitorLocker ml(handler_impl->startup_monitor_);
+    MonitorLocker ml(&handler_impl->startup_monitor_);
     handler_impl->handler_thread_id_ = Thread::GetCurrentThreadId();
     handler_impl->handler_thread_handle_ =
         OpenThread(SYNCHRONIZE, false, handler_impl->handler_thread_id_);
@@ -1469,7 +1466,7 @@
   }
 
   {
-    MonitorLocker ml(startup_monitor_);
+    MonitorLocker ml(&startup_monitor_);
     while (handler_thread_id_ == Thread::kInvalidThreadId) {
       ml.Wait();
     }
diff --git a/runtime/bin/eventhandler_win.h b/runtime/bin/eventhandler_win.h
index 2833f13..bbd2179 100644
--- a/runtime/bin/eventhandler_win.h
+++ b/runtime/bin/eventhandler_win.h
@@ -262,7 +262,7 @@
 
   virtual void HandleIssueError();
 
-  Monitor* monitor_;
+  Monitor monitor_;
   Type type_;
   HANDLE handle_;
   HANDLE completion_port_;
@@ -558,7 +558,7 @@
   HANDLE completion_port() { return completion_port_; }
 
  private:
-  Monitor* startup_monitor_;
+  Monitor startup_monitor_;
   ThreadId handler_thread_id_;
   HANDLE handler_thread_handle_;
 
diff --git a/runtime/bin/io_sources.gni b/runtime/bin/io_sources.gni
index 4bc7c1d..56de0e7 100644
--- a/runtime/bin/io_sources.gni
+++ b/runtime/bin/io_sources.gni
@@ -3,7 +3,7 @@
 # BSD-style license that can be found in the LICENSE file.
 
 # This file contains all sources for the dart:io library.
-io_runtime_sources = [
+io_runtime_dart_files = [
   "common_patch.dart",
   "directory_patch.dart",
   "eventhandler_patch.dart",
diff --git a/runtime/bin/loader.cc b/runtime/bin/loader.cc
index 2993e91..a56cdc2 100644
--- a/runtime/bin/loader.cc
+++ b/runtime/bin/loader.cc
@@ -33,14 +33,13 @@
     : port_(ILLEGAL_PORT),
       isolate_data_(isolate_data),
       error_(Dart_Null()),
-      monitor_(NULL),
+      monitor_(),
       pending_operations_(0),
       results_(NULL),
       results_length_(0),
       results_capacity_(0),
       payload_(NULL),
       payload_length_(0) {
-  monitor_ = new Monitor();
   ASSERT(isolate_data_ != NULL);
   port_ = Dart_NewNativePort("Loader", Loader::NativeMessageHandler, false);
   isolate_data_->set_loader(this);
@@ -51,15 +50,13 @@
   ASSERT(port_ != ILLEGAL_PORT);
   // Enter the monitor while we close the Dart port. After the Dart port is
   // closed, no more results can be queued.
-  monitor_->Enter();
+  monitor_.Enter();
   Dart_CloseNativePort(port_);
-  monitor_->Exit();
+  monitor_.Exit();
   RemoveLoader(port_);
   port_ = ILLEGAL_PORT;
   isolate_data_->set_loader(NULL);
   isolate_data_ = NULL;
-  delete monitor_;
-  monitor_ = NULL;
   for (intptr_t i = 0; i < results_length_; i++) {
     results_[i].Cleanup();
   }
@@ -182,7 +179,7 @@
   Dart_ListSetAt(request, 5, library_url);
 
   if (Dart_Post(loader_port, request)) {
-    MonitorLocker ml(monitor_);
+    MonitorLocker ml(&monitor_);
     pending_operations_++;
   }
 }
@@ -205,13 +202,13 @@
   Dart_ListSetAt(request, 5, library_url);
 
   if (Dart_Post(loader_port, request)) {
-    MonitorLocker ml(monitor_);
+    MonitorLocker ml(&monitor_);
     pending_operations_++;
   }
 }
 
 void Loader::QueueMessage(Dart_CObject* message) {
-  MonitorLocker ml(monitor_);
+  MonitorLocker ml(&monitor_);
   if (results_length_ == results_capacity_) {
     // Grow to an initial capacity or double in size.
     results_capacity_ = (results_capacity_ == 0) ? 4 : results_capacity_ * 2;
@@ -227,7 +224,7 @@
 }
 
 void Loader::BlockUntilComplete(ProcessResult process_result) {
-  MonitorLocker ml(monitor_);
+  MonitorLocker ml(&monitor_);
 
   while (true) {
     // If |ProcessQueueLocked| returns false, we've hit an error and should
diff --git a/runtime/bin/loader.h b/runtime/bin/loader.h
index 2e94033..4142c89 100644
--- a/runtime/bin/loader.h
+++ b/runtime/bin/loader.h
@@ -49,7 +49,7 @@
   Dart_Handle error_;
   // This monitor is used to protect the pending operations count and the
   // I/O result queue.
-  Monitor* monitor_;
+  Monitor monitor_;
 
   // The number of operations dispatched to the service isolate for loading.
   // Must be accessed with monitor_ held.
diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc
index 180cb3f..c9edf66 100644
--- a/runtime/bin/main.cc
+++ b/runtime/bin/main.cc
@@ -46,15 +46,6 @@
 extern const uint8_t kDartCoreIsolateSnapshotInstructions[];
 }
 
-#if defined(DART_LINK_APP_SNAPSHOT)
-extern "C" {
-extern const uint8_t _kDartVmSnapshotData[];
-extern const uint8_t _kDartVmSnapshotInstructions[];
-extern const uint8_t _kDartIsolateSnapshotData[];
-extern const uint8_t _kDartIsolateSnapshotInstructions[];
-}
-#endif
-
 namespace dart {
 namespace bin {
 
@@ -1039,13 +1030,6 @@
 
   Loader::InitOnce();
 
-#if defined(DART_LINK_APP_SNAPSHOT)
-  vm_run_app_snapshot = true;
-  vm_snapshot_data = _kDartVmSnapshotData;
-  vm_snapshot_instructions = _kDartVmSnapshotInstructions;
-  app_isolate_snapshot_data = _kDartIsolateSnapshotData;
-  app_isolate_snapshot_instructions = _kDartIsolateSnapshotInstructions;
-#else
   AppSnapshot* shared_blobs = NULL;
   if (Options::shared_blobs_filename() != NULL) {
     Syslog::PrintErr(
@@ -1068,7 +1052,6 @@
                              &app_isolate_snapshot_data,
                              &app_isolate_snapshot_instructions);
   }
-#endif
 
 #if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
   // Constant true if PRODUCT or DART_PRECOMPILED_RUNTIME.
@@ -1171,10 +1154,8 @@
   Process::ClearAllSignalHandlers();
   EventHandler::Stop();
 
-#if !defined(DART_LINK_APP_SNAPSHOT)
   delete app_snapshot;
   delete shared_blobs;
-#endif
   free(app_script_uri);
 
   // Free copied argument strings if converted.
diff --git a/runtime/bin/main_options.cc b/runtime/bin/main_options.cc
index 501b9c1..b356da5 100644
--- a/runtime/bin/main_options.cc
+++ b/runtime/bin/main_options.cc
@@ -423,9 +423,6 @@
   // The arguments to the VM are at positions 1 through i-1 in argv.
   Platform::SetExecutableArguments(i, argv);
 
-#if defined(DART_LINK_APP_SNAPSHOT)
-  *script_name = argv[0];
-#else
   // Get the script name.
   if (i < argc) {
     *script_name = argv[i];
@@ -433,7 +430,6 @@
   } else {
     return -1;
   }
-#endif
 
   // Parse out options to be passed to dart main.
   while (i < argc) {
diff --git a/runtime/bin/security_context_macos.cc b/runtime/bin/security_context_macos.cc
index 2964d67..024f1ad 100644
--- a/runtime/bin/security_context_macos.cc
+++ b/runtime/bin/security_context_macos.cc
@@ -38,8 +38,18 @@
   T* ptr() { return &obj_; }
   const T get() const { return obj_; }
 
+  DART_WARN_UNUSED_RESULT T release() {
+    T temp = obj_;
+    obj_ = NULL;
+    return temp;
+  }
+
   void set(T obj) { obj_ = obj; }
 
+  bool operator==(T other) { return other == get(); }
+
+  bool operator!=(T other) { return other != get(); }
+
  private:
   T obj_;
 
@@ -47,6 +57,20 @@
   DISALLOW_COPY_AND_ASSIGN(ScopedCFType);
 };
 
+static void releaseObjects(const void* val, void* context) {
+  CFRelease(val);
+}
+
+template <>
+ScopedCFType<CFMutableArrayRef>::~ScopedCFType() {
+  if (obj_ != NULL) {
+    CFIndex count = 0;
+    CFArrayApplyFunction(obj_, CFRangeMake(0, CFArrayGetCount(obj_)),
+                         releaseObjects, &count);
+    CFRelease(obj_);
+  }
+}
+
 typedef ScopedCFType<CFMutableArrayRef> ScopedCFMutableArrayRef;
 typedef ScopedCFType<CFDataRef> ScopedCFDataRef;
 typedef ScopedCFType<CFStringRef> ScopedCFStringRef;
@@ -60,8 +84,10 @@
   }
   int length = i2d_X509(cert, NULL);
   if (length < 0) {
-    return 0;
+    return NULL;
   }
+  // This can be `std::make_unique<unsigned char[]>(length)` in C++14
+  // But the Mac toolchain is still using C++11.
   auto deb_cert = std::unique_ptr<unsigned char[]>(new unsigned char[length]);
   unsigned char* temp = deb_cert.get();
   if (i2d_X509(cert, &temp) != length) {
@@ -72,12 +98,7 @@
   // Implementation here:
   // https://opensource.apple.com/source/libsecurity_keychain/libsecurity_keychain-55050.2/lib/SecCertificate.cpp.auto.html
   ScopedCFDataRef cert_buf(CFDataCreate(NULL, deb_cert.get(), length));
-  SecCertificateRef auth_cert =
-      SecCertificateCreateWithData(NULL, cert_buf.get());
-  if (auth_cert == NULL) {
-    return NULL;
-  }
-  return auth_cert;
+  return SecCertificateCreateWithData(NULL, cert_buf.get());
 }
 
 static int CertificateVerificationCallback(X509_STORE_CTX* ctx, void* arg) {
@@ -93,11 +114,11 @@
     cert_chain.set(CFArrayCreateMutable(NULL, num_certs, NULL));
     X509* ca;
     while ((ca = sk_X509_shift(user_provided_certs)) != NULL) {
-      SecCertificateRef cert = CreateSecCertificateFromX509(ca);
+      ScopedSecCertificateRef cert(CreateSecCertificateFromX509(ca));
       if (cert == NULL) {
         return ctx->verify_cb(0, ctx);
       }
-      CFArrayAppendValue(cert_chain.get(), cert);
+      CFArrayAppendValue(cert_chain.get(), cert.release());
       ++current_cert;
 
       if (current_cert == num_certs) {
@@ -115,11 +136,11 @@
   if (store->objs != NULL) {
     for (uintptr_t i = 0; i < sk_X509_OBJECT_num(store->objs); ++i) {
       X509* ca = sk_X509_OBJECT_value(store->objs, i)->data.x509;
-      SecCertificateRef cert = CreateSecCertificateFromX509(ca);
+      ScopedSecCertificateRef cert(CreateSecCertificateFromX509(ca));
       if (cert == NULL) {
         return ctx->verify_cb(0, ctx);
       }
-      CFArrayAppendValue(trusted_certs.get(), cert);
+      CFArrayAppendValue(trusted_certs.get(), cert.release());
     }
   }
 
diff --git a/runtime/bin/socket.cc b/runtime/bin/socket.cc
index 113ea22..b706482 100644
--- a/runtime/bin/socket.cc
+++ b/runtime/bin/socket.cc
@@ -94,7 +94,7 @@
                                                       intptr_t backlog,
                                                       bool v6_only,
                                                       bool shared) {
-  MutexLocker ml(mutex_);
+  MutexLocker ml(&mutex_);
 
   OSSocket* first_os_socket = NULL;
   intptr_t port = SocketAddress::GetAddrPort(addr);
@@ -195,7 +195,7 @@
 
 bool ListeningSocketRegistry::CloseOneSafe(OSSocket* os_socket,
                                            bool update_hash_maps) {
-  ASSERT(!mutex_->TryLock());
+  ASSERT(!mutex_.TryLock());
   ASSERT(os_socket != NULL);
   ASSERT(os_socket->ref_count > 0);
   os_socket->ref_count--;
@@ -232,7 +232,7 @@
 }
 
 void ListeningSocketRegistry::CloseAllSafe() {
-  MutexLocker ml(mutex_);
+  MutexLocker ml(&mutex_);
 
   for (SimpleHashMap::Entry* cursor = sockets_by_fd_.Start(); cursor != NULL;
        cursor = sockets_by_fd_.Next(cursor)) {
@@ -241,7 +241,7 @@
 }
 
 bool ListeningSocketRegistry::CloseSafe(Socket* socketfd) {
-  ASSERT(!mutex_->TryLock());
+  ASSERT(!mutex_.TryLock());
   OSSocket* os_socket = LookupByFd(socketfd);
   if (os_socket != NULL) {
     return CloseOneSafe(os_socket, true);
diff --git a/runtime/bin/socket.h b/runtime/bin/socket.h
index 24d95b9..a23ff65 100644
--- a/runtime/bin/socket.h
+++ b/runtime/bin/socket.h
@@ -155,12 +155,10 @@
   ListeningSocketRegistry()
       : sockets_by_port_(SameIntptrValue, kInitialSocketsCount),
         sockets_by_fd_(SameIntptrValue, kInitialSocketsCount),
-        mutex_(new Mutex()) {}
+        mutex_() {}
 
   ~ListeningSocketRegistry() {
     CloseAllSafe();
-    delete mutex_;
-    mutex_ = NULL;
   }
 
   static void Initialize();
@@ -187,7 +185,7 @@
   // this function.
   bool CloseSafe(Socket* socketfd);
 
-  Mutex* mutex() { return mutex_; }
+  Mutex* mutex() { return &mutex_; }
 
  private:
   struct OSSocket {
@@ -254,7 +252,7 @@
   SimpleHashMap sockets_by_port_;
   SimpleHashMap sockets_by_fd_;
 
-  Mutex* mutex_;
+  Mutex mutex_;
 
   DISALLOW_COPY_AND_ASSIGN(ListeningSocketRegistry);
 };
diff --git a/runtime/bin/utils_fuchsia.cc b/runtime/bin/utils_fuchsia.cc
index 4c8b208..c7bbe08 100644
--- a/runtime/bin/utils_fuchsia.cc
+++ b/runtime/bin/utils_fuchsia.cc
@@ -77,7 +77,7 @@
 }
 
 int64_t TimerUtils::GetCurrentMonotonicMicros() {
-  int64_t ticks = zx_clock_get(ZX_CLOCK_MONOTONIC);
+  zx_time_t ticks = zx_clock_get_monotonic();
   return ticks / kNanosecondsPerMicrosecond;
 }
 
diff --git a/runtime/lib/async_sources.gni b/runtime/lib/async_sources.gni
index 914aa9b..d3fef9a 100644
--- a/runtime/lib/async_sources.gni
+++ b/runtime/lib/async_sources.gni
@@ -12,5 +12,3 @@
   "schedule_microtask_patch.dart",
   "timer_patch.dart",
 ]
-
-async_runtime_sources = async_runtime_cc_files + async_runtime_dart_files
diff --git a/runtime/lib/collection_sources.gni b/runtime/lib/collection_sources.gni
index 1fa63d3..c3c15fc 100644
--- a/runtime/lib/collection_sources.gni
+++ b/runtime/lib/collection_sources.gni
@@ -10,6 +10,3 @@
   "collection_patch.dart",
   "compact_hash.dart",
 ]
-
-collection_runtime_sources =
-    collection_runtime_cc_files + collection_runtime_dart_files
diff --git a/runtime/lib/convert_sources.gni b/runtime/lib/convert_sources.gni
index e37c017..123db64 100644
--- a/runtime/lib/convert_sources.gni
+++ b/runtime/lib/convert_sources.gni
@@ -2,4 +2,4 @@
 # for details. All rights reserved. Use of this source code is governed by a
 # BSD-style license that can be found in the LICENSE file.
 
-convert_runtime_sources = [ "convert_patch.dart" ]
+convert_runtime_dart_files = [ "convert_patch.dart" ]
diff --git a/runtime/lib/core_sources.gni b/runtime/lib/core_sources.gni
index 4c57dc4..825663a 100644
--- a/runtime/lib/core_sources.gni
+++ b/runtime/lib/core_sources.gni
@@ -59,5 +59,3 @@
   "uri_patch.dart",
   "weak_property.dart",
 ]
-
-core_runtime_sources = core_runtime_cc_files + core_runtime_dart_files
diff --git a/runtime/lib/developer_sources.gni b/runtime/lib/developer_sources.gni
index 61f02f62..a613da7 100644
--- a/runtime/lib/developer_sources.gni
+++ b/runtime/lib/developer_sources.gni
@@ -16,6 +16,3 @@
   "profiler.dart",
   "timeline.dart",
 ]
-
-developer_runtime_sources =
-    developer_runtime_cc_files + developer_runtime_dart_files
diff --git a/runtime/lib/ffi.cc b/runtime/lib/ffi.cc
index 82a8262..34a5530 100644
--- a/runtime/lib/ffi.cc
+++ b/runtime/lib/ffi.cc
@@ -2,11 +2,13 @@
 // for 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/ffi.h"
+#include "lib/ffi.h"
+
 #include "include/dart_api.h"
 #include "vm/bootstrap_natives.h"
 #include "vm/class_finalizer.h"
 #include "vm/compiler/assembler/assembler.h"
+#include "vm/compiler/ffi.h"
 #include "vm/exceptions.h"
 #include "vm/log.h"
 #include "vm/native_arguments.h"
@@ -614,4 +616,113 @@
   return result.raw();
 }
 
+#if defined(TARGET_ARCH_DBC)
+
+void FfiMarshalledArguments::SetFunctionAddress(uint64_t value) const {
+  data_[kOffsetFunctionAddress] = value;
+}
+
+static intptr_t ArgumentHostRegisterIndex(host::Register reg) {
+  for (intptr_t i = 0; i < host::CallingConventions::kNumArgRegs; i++) {
+    if (host::CallingConventions::ArgumentRegisters[i] == reg) {
+      return i;
+    }
+  }
+  UNREACHABLE();
+}
+
+void FfiMarshalledArguments::SetRegister(host::Register reg,
+                                         uint64_t value) const {
+  const intptr_t reg_index = ArgumentHostRegisterIndex(reg);
+  ASSERT(host::CallingConventions::ArgumentRegisters[reg_index] == reg);
+  const intptr_t index = kOffsetRegisters + reg_index;
+  data_[index] = value;
+}
+
+void FfiMarshalledArguments::SetFpuRegister(host::FpuRegister reg,
+                                            uint64_t value) const {
+  const intptr_t fpu_index = static_cast<intptr_t>(reg);
+  ASSERT(host::CallingConventions::FpuArgumentRegisters[fpu_index] == reg);
+  const intptr_t index = kOffsetFpuRegisters + fpu_index;
+  data_[index] = value;
+}
+
+void FfiMarshalledArguments::SetNumStackSlots(intptr_t num_args) const {
+  data_[kOffsetNumStackSlots] = num_args;
+}
+
+intptr_t FfiMarshalledArguments::GetNumStackSlots() const {
+  return data_[kOffsetNumStackSlots];
+}
+
+void FfiMarshalledArguments::SetStackSlotValue(intptr_t index,
+                                               uint64_t value) const {
+  ASSERT(0 <= index && index < GetNumStackSlots());
+  data_[kOffsetStackSlotValues + index] = value;
+}
+
+uint64_t* FfiMarshalledArguments::New(
+    const compiler::ffi::FfiSignatureDescriptor& signature,
+    const uint64_t* arg_values) {
+  const intptr_t num_stack_slots = signature.num_stack_slots();
+  const intptr_t size =
+      FfiMarshalledArguments::kOffsetStackSlotValues + num_stack_slots;
+  uint64_t* data = Thread::Current()->GetFfiMarshalledArguments(size);
+  const auto& descr = FfiMarshalledArguments(data);
+
+  descr.SetFunctionAddress(arg_values[compiler::ffi::kFunctionAddressRegister]);
+  const intptr_t num_args = signature.length();
+  descr.SetNumStackSlots(num_stack_slots);
+  for (int i = 0; i < num_args; i++) {
+    uint64_t arg_value = arg_values[compiler::ffi::kFirstArgumentRegister + i];
+    HostLocation loc = signature.LocationAt(i);
+    // TODO(36809): For 32 bit, support pair locations.
+    if (loc.IsRegister()) {
+      descr.SetRegister(loc.reg(), arg_value);
+    } else if (loc.IsFpuRegister()) {
+      descr.SetFpuRegister(loc.fpu_reg(), arg_value);
+    } else {
+      ASSERT(loc.IsStackSlot());
+      ASSERT(loc.stack_index() < num_stack_slots);
+      descr.SetStackSlotValue(loc.stack_index(), arg_value);
+    }
+  }
+
+  return data;
+}
+
+#if defined(DEBUG)
+void FfiMarshalledArguments::Print() const {
+  OS::PrintErr("FfiMarshalledArguments data_ 0x%" Pp "\n",
+               reinterpret_cast<intptr_t>(data_));
+  OS::PrintErr("  00 0x%016" Px64 " (function address, int result)\n",
+               data_[0]);
+  for (intptr_t i = 0; i < host::CallingConventions::kNumArgRegs; i++) {
+    const intptr_t index = kOffsetRegisters + i;
+    const char* result_str = i == 0 ? ", float result" : "";
+    OS::PrintErr("  %02" Pd " 0x%016" Px64 " (%s%s)\n", index, data_[index],
+                 RegisterNames::RegisterName(
+                     host::CallingConventions::ArgumentRegisters[i]),
+                 result_str);
+  }
+  for (intptr_t i = 0; i < host::CallingConventions::kNumFpuArgRegs; i++) {
+    const intptr_t index = kOffsetFpuRegisters + i;
+    OS::PrintErr("  %02" Pd " 0x%016" Px64 " (%s)\n", index, data_[index],
+                 RegisterNames::FpuRegisterName(
+                     host::CallingConventions::FpuArgumentRegisters[i]));
+  }
+  const intptr_t index = kOffsetNumStackSlots;
+  const intptr_t num_stack_slots = data_[index];
+  OS::PrintErr("  %02" Pd " 0x%" Pp " (number of stack slots)\n", index,
+               num_stack_slots);
+  for (intptr_t i = 0; i < num_stack_slots; i++) {
+    const intptr_t index = kOffsetStackSlotValues + i;
+    OS::PrintErr("  %02" Pd " 0x%016" Px64 " (stack slot %" Pd ")\n", index,
+                 data_[index], i);
+  }
+}
+#endif  // defined(DEBUG)
+
+#endif  // defined(TARGET_ARCH_DBC)
+
 }  // namespace dart
diff --git a/runtime/lib/ffi.h b/runtime/lib/ffi.h
new file mode 100644
index 0000000..00c527f
--- /dev/null
+++ b/runtime/lib/ffi.h
@@ -0,0 +1,74 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#ifndef RUNTIME_LIB_FFI_H_
+#define RUNTIME_LIB_FFI_H_
+
+#if defined(TARGET_ARCH_DBC)
+
+#include <platform/globals.h>
+
+#include "vm/class_id.h"
+#include "vm/compiler/backend/locations.h"
+#include "vm/compiler/ffi.h"
+#include "vm/object.h"
+#include "vm/raw_object.h"
+
+namespace dart {
+
+// This structure contains all data required for an ffi call.
+// It consists of the function address, all calling convention argument
+// register values, argument fpu register values, number of stack arguments,
+// and stack argument values. The generic DBC trampoline reads its arguments
+// from this structure.
+//
+// Moreover, the DBC trampoline also stores the integer and floating point
+// result registers in the first two slots when returning.
+class FfiMarshalledArguments : public ValueObject {
+ public:
+  explicit FfiMarshalledArguments(uint64_t* data) : data_(data) {}
+
+  // Copies ffi trampoline arguments (including target address) from stack into
+  // a signature agnostic data structure (FfiMarshalledArguments) using the
+  // signature and the stack address of the first argument. (Note that this
+  // only works on DBC as the stack grows upwards in DBC.)
+  static uint64_t* New(const compiler::ffi::FfiSignatureDescriptor& signature,
+                       const uint64_t* arg_values);
+
+  uint64_t IntResult() const { return data_[kOffsetIntResult]; }
+  uint64_t DoubleResult() const { return data_[kOffsetDoubleResult]; }
+
+#if defined(DEBUG)
+  void Print() const;
+#endif
+
+ private:
+  void SetFunctionAddress(uint64_t value) const;
+  void SetRegister(::dart::host::Register reg, uint64_t value) const;
+  void SetFpuRegister(::dart::host::FpuRegister reg, uint64_t value) const;
+  void SetNumStackSlots(intptr_t num_args) const;
+  intptr_t GetNumStackSlots() const;
+  void SetStackSlotValue(intptr_t index, uint64_t value) const;
+
+  // TODO(36809): Replace this with uword. On 32 bit architecture,
+  // this should be 32 bits, as the DBC stack itself is 32 bits.
+  uint64_t* data_;
+
+  static const intptr_t kOffsetFunctionAddress = 0;
+  static const intptr_t kOffsetRegisters = 1;
+  static const intptr_t kOffsetFpuRegisters =
+      kOffsetRegisters + ::dart::host::CallingConventions::kNumArgRegs;
+  static const intptr_t kOffsetNumStackSlots =
+      kOffsetFpuRegisters + ::dart::host::CallingConventions::kNumFpuArgRegs;
+  static const intptr_t kOffsetStackSlotValues = kOffsetNumStackSlots + 1;
+
+  static const intptr_t kOffsetIntResult = 0;
+  static const intptr_t kOffsetDoubleResult = 1;
+};
+
+}  // namespace dart
+
+#endif  // defined(TARGET_ARCH_DBC)
+
+#endif  // RUNTIME_LIB_FFI_H_
diff --git a/runtime/lib/ffi_sources.gni b/runtime/lib/ffi_sources.gni
index fd625f4..9936dd2 100644
--- a/runtime/lib/ffi_sources.gni
+++ b/runtime/lib/ffi_sources.gni
@@ -13,5 +13,3 @@
   "ffi_dynamic_library_patch.dart",
   "ffi_native_type_patch.dart",
 ]
-
-ffi_runtime_sources = ffi_runtime_cc_files + ffi_runtime_dart_files
diff --git a/runtime/lib/internal_sources.gni b/runtime/lib/internal_sources.gni
index d5550bc..7c173ab 100644
--- a/runtime/lib/internal_sources.gni
+++ b/runtime/lib/internal_sources.gni
@@ -13,6 +13,3 @@
   "print_patch.dart",
   "symbol_patch.dart",
 ]
-
-internal_runtime_sources =
-    internal_runtime_cc_files + internal_runtime_dart_files
diff --git a/runtime/lib/isolate.cc b/runtime/lib/isolate.cc
index d666686..c6280f1 100644
--- a/runtime/lib/isolate.cc
+++ b/runtime/lib/isolate.cc
@@ -113,14 +113,22 @@
 
 class SpawnIsolateTask : public ThreadPool::Task {
  public:
-  explicit SpawnIsolateTask(IsolateSpawnState* state) : state_(state) {}
+  SpawnIsolateTask(Isolate* parent_isolate, IsolateSpawnState* state)
+      : parent_isolate_(parent_isolate), state_(state) {
+    parent_isolate->IncrementSpawnCount();
+  }
 
-  virtual void Run() {
+  ~SpawnIsolateTask() override {
+    if (parent_isolate_) {
+      parent_isolate_->DecrementSpawnCount();
+    }
+  }
+
+  void Run() override {
     // Create a new isolate.
     char* error = NULL;
     Dart_IsolateCreateCallback callback = Isolate::CreateCallback();
     if (callback == NULL) {
-      state_->DecrementSpawnCount();
       ReportError(
           "Isolate spawn is not supported by this Dart implementation\n");
       delete state_;
@@ -135,9 +143,10 @@
     ASSERT(name != NULL);
 
     Isolate* isolate = reinterpret_cast<Isolate*>((callback)(
-        state_->script_url(), name, state_->package_root(),
-        state_->package_config(), &api_flags, state_->init_data(), &error));
-    state_->DecrementSpawnCount();
+        state_->script_url(), name, nullptr, state_->package_config(),
+        &api_flags, parent_isolate_->init_callback_data(), &error));
+    parent_isolate_->DecrementSpawnCount();
+    parent_isolate_ = nullptr;
     if (isolate == NULL) {
       ReportError(error);
       delete state_;
@@ -152,7 +161,7 @@
       isolate->set_origin_id(state_->origin_id());
     }
     MutexLocker ml(isolate->mutex());
-    state_->set_isolate(reinterpret_cast<Isolate*>(isolate));
+    state_->set_isolate(isolate);
     isolate->set_spawn_state(state_);
     state_ = NULL;
     if (isolate->is_runnable()) {
@@ -171,6 +180,7 @@
     }
   }
 
+  Isolate* parent_isolate_;
   IsolateSpawnState* state_;
 
   DISALLOW_COPY_AND_ASSIGN(SpawnIsolateTask);
@@ -223,29 +233,23 @@
             message, ILLEGAL_PORT, Message::kNormalPriority));
       }
 
-      // TODO(mfairhurst) remove package_root, as it no longer does anything.
-      const char* utf8_package_root = NULL;
       const char* utf8_package_config =
           packageConfig.IsNull() ? NULL : String2UTF8(packageConfig);
       const char* utf8_debug_name =
           debugName.IsNull() ? NULL : String2UTF8(debugName);
 
       IsolateSpawnState* state = new IsolateSpawnState(
-          port.Id(), isolate->origin_id(), isolate->init_callback_data(),
-          String2UTF8(script_uri), func, &message_buffer,
-          isolate->spawn_count_monitor(), isolate->spawn_count(),
-          utf8_package_root, utf8_package_config, paused.value(), fatal_errors,
+          port.Id(), isolate->origin_id(), String2UTF8(script_uri), func,
+          &message_buffer, utf8_package_config, paused.value(), fatal_errors,
           on_exit_port, on_error_port, utf8_debug_name);
 
       // Since this is a call to Isolate.spawn, copy the parent isolate's code.
       state->isolate_flags()->copy_parent_code = true;
 
-      ThreadPool::Task* spawn_task = new SpawnIsolateTask(state);
+      ThreadPool::Task* spawn_task = new SpawnIsolateTask(isolate, state);
 
-      isolate->IncrementSpawnCount();
       if (!Dart::thread_pool()->Run(spawn_task)) {
         // Running on the thread pool failed. Clean up everything.
-        state->DecrementSpawnCount();
         delete state;
         state = NULL;
         delete spawn_task;
@@ -351,19 +355,15 @@
     ThrowIsolateSpawnException(msg);
   }
 
-  // TODO(mfairhurst) remove package_root, as it no longer does anything.
-  const char* utf8_package_root = NULL;
   const char* utf8_package_config =
       packageConfig.IsNull() ? NULL : String2UTF8(packageConfig);
   const char* utf8_debug_name =
       debugName.IsNull() ? NULL : String2UTF8(debugName);
 
   IsolateSpawnState* state = new IsolateSpawnState(
-      port.Id(), isolate->init_callback_data(), canonical_uri,
-      utf8_package_root, utf8_package_config, &arguments_buffer,
-      &message_buffer, isolate->spawn_count_monitor(), isolate->spawn_count(),
-      paused.value(), fatal_errors, on_exit_port, on_error_port,
-      utf8_debug_name);
+      port.Id(), canonical_uri, utf8_package_config, &arguments_buffer,
+      &message_buffer, paused.value(), fatal_errors, on_exit_port,
+      on_error_port, utf8_debug_name);
 
   // If we were passed a value then override the default flags state for
   // checked mode.
@@ -375,12 +375,10 @@
   // Since this is a call to Isolate.spawnUri, don't copy the parent's code.
   state->isolate_flags()->copy_parent_code = false;
 
-  ThreadPool::Task* spawn_task = new SpawnIsolateTask(state);
+  ThreadPool::Task* spawn_task = new SpawnIsolateTask(isolate, state);
 
-  isolate->IncrementSpawnCount();
   if (!Dart::thread_pool()->Run(spawn_task)) {
     // Running on the thread pool failed. Clean up everything.
-    state->DecrementSpawnCount();
     delete state;
     state = NULL;
     delete spawn_task;
diff --git a/runtime/lib/isolate_sources.gni b/runtime/lib/isolate_sources.gni
index 021e4eb..1495aaf 100644
--- a/runtime/lib/isolate_sources.gni
+++ b/runtime/lib/isolate_sources.gni
@@ -9,5 +9,3 @@
   "isolate_patch.dart",
   "timer_impl.dart",
 ]
-
-isolate_runtime_sources = isolate_runtime_cc_files + isolate_runtime_dart_files
diff --git a/runtime/lib/math_sources.gni b/runtime/lib/math_sources.gni
index 33f089e..986010d 100644
--- a/runtime/lib/math_sources.gni
+++ b/runtime/lib/math_sources.gni
@@ -5,5 +5,3 @@
 math_runtime_cc_files = [ "math.cc" ]
 
 math_runtime_dart_files = [ "math_patch.dart" ]
-
-math_runtime_sources = math_runtime_cc_files + math_runtime_dart_files
diff --git a/runtime/lib/mirrors_sources.gni b/runtime/lib/mirrors_sources.gni
index c3a51c5..e92dcf0 100644
--- a/runtime/lib/mirrors_sources.gni
+++ b/runtime/lib/mirrors_sources.gni
@@ -15,5 +15,3 @@
   "mirrors_impl.dart",
   "mirror_reference.dart",
 ]
-
-mirrors_runtime_sources = mirrors_runtime_cc_files + mirrors_runtime_dart_files
diff --git a/runtime/lib/profiler_sources.gni b/runtime/lib/profiler_sources.gni
index b27bc88..b2ff2ca 100644
--- a/runtime/lib/profiler_sources.gni
+++ b/runtime/lib/profiler_sources.gni
@@ -3,4 +3,4 @@
 # BSD-style license that can be found in the LICENSE file.
 
 # Sources list to keep vm/BUILD.gn generate_core_libraries happy.
-profiler_runtime_sources = [ "empty_source.dart" ]
+profiler_runtime_dart_files = [ "empty_source.dart" ]
diff --git a/runtime/lib/typed_data_sources.gni b/runtime/lib/typed_data_sources.gni
index 9892c8f..b10a829 100644
--- a/runtime/lib/typed_data_sources.gni
+++ b/runtime/lib/typed_data_sources.gni
@@ -9,6 +9,3 @@
 ]
 
 typed_data_runtime_dart_files = [ "typed_data_patch.dart" ]
-
-typed_data_runtime_sources =
-    typed_data_runtime_cc_files + typed_data_runtime_dart_files
diff --git a/runtime/lib/vmservice_sources.gni b/runtime/lib/vmservice_sources.gni
index a5e1131..b39e99b 100644
--- a/runtime/lib/vmservice_sources.gni
+++ b/runtime/lib/vmservice_sources.gni
@@ -3,4 +3,4 @@
 # BSD-style license that can be found in the LICENSE file.
 
 # Sources that patch the library "dart:_vmservice".
-vmservice_runtime_sources = [ "vmservice.cc" ]
+vmservice_runtime_cc_files = [ "vmservice.cc" ]
diff --git a/runtime/observatory/lib/elements.dart b/runtime/observatory/lib/elements.dart
index 25ef536..5a57241 100644
--- a/runtime/observatory/lib/elements.dart
+++ b/runtime/observatory/lib/elements.dart
@@ -1,107 +1,5 @@
 library observatory_elements;
 
-import 'dart:async';
-
-import 'package:observatory/src/elements/allocation_profile.dart';
-import 'package:observatory/src/elements/class_allocation_profile.dart';
-import 'package:observatory/src/elements/class_instances.dart';
-import 'package:observatory/src/elements/class_ref.dart';
-import 'package:observatory/src/elements/class_tree.dart';
-import 'package:observatory/src/elements/class_view.dart';
-import 'package:observatory/src/elements/code_ref.dart';
-import 'package:observatory/src/elements/code_view.dart';
-import 'package:observatory/src/elements/containers/search_bar.dart';
-import 'package:observatory/src/elements/containers/virtual_collection.dart';
-import 'package:observatory/src/elements/containers/virtual_tree.dart';
-import 'package:observatory/src/elements/context_ref.dart';
-import 'package:observatory/src/elements/context_view.dart';
-import 'package:observatory/src/elements/cpu_profile.dart';
-import 'package:observatory/src/elements/cpu_profile/virtual_tree.dart';
-import 'package:observatory/src/elements/cpu_profile_table.dart';
-import 'package:observatory/src/elements/curly_block.dart';
-import 'package:observatory/src/elements/debugger.dart';
-import 'package:observatory/src/elements/error_ref.dart';
-import 'package:observatory/src/elements/error_view.dart';
-import 'package:observatory/src/elements/eval_box.dart';
-import 'package:observatory/src/elements/field_ref.dart';
-import 'package:observatory/src/elements/field_view.dart';
-import 'package:observatory/src/elements/flag_list.dart';
-import 'package:observatory/src/elements/function_ref.dart';
-import 'package:observatory/src/elements/function_view.dart';
-import 'package:observatory/src/elements/general_error.dart';
-import 'package:observatory/src/elements/heap_map.dart';
-import 'package:observatory/src/elements/heap_snapshot.dart';
-import 'package:observatory/src/elements/icdata_ref.dart';
-import 'package:observatory/src/elements/icdata_view.dart';
-import 'package:observatory/src/elements/instance_ref.dart';
-import 'package:observatory/src/elements/instance_view.dart';
-import 'package:observatory/src/elements/isolate/counter_chart.dart';
-import 'package:observatory/src/elements/isolate/location.dart';
-import 'package:observatory/src/elements/isolate/run_state.dart';
-import 'package:observatory/src/elements/isolate/shared_summary.dart';
-import 'package:observatory/src/elements/isolate/summary.dart';
-import 'package:observatory/src/elements/isolate_reconnect.dart';
-import 'package:observatory/src/elements/isolate_ref.dart';
-import 'package:observatory/src/elements/isolate_view.dart';
-import 'package:observatory/src/elements/json_view.dart';
-import 'package:observatory/src/elements/library_ref.dart';
-import 'package:observatory/src/elements/library_view.dart';
-import 'package:observatory/src/elements/local_var_descriptors_ref.dart';
-import 'package:observatory/src/elements/logging.dart';
-import 'package:observatory/src/elements/megamorphiccache_ref.dart';
-import 'package:observatory/src/elements/megamorphiccache_view.dart';
-import 'package:observatory/src/elements/memory/dashboard.dart';
-import 'package:observatory/src/elements/memory/graph.dart';
-import 'package:observatory/src/elements/metric/details.dart';
-import 'package:observatory/src/elements/metric/graph.dart';
-import 'package:observatory/src/elements/metrics.dart';
-import 'package:observatory/src/elements/native_memory_profiler.dart';
-import 'package:observatory/src/elements/nav/class_menu.dart';
-import 'package:observatory/src/elements/nav/isolate_menu.dart';
-import 'package:observatory/src/elements/nav/library_menu.dart';
-import 'package:observatory/src/elements/nav/menu_item.dart';
-import 'package:observatory/src/elements/nav/notify.dart';
-import 'package:observatory/src/elements/nav/notify_event.dart';
-import 'package:observatory/src/elements/nav/notify_exception.dart';
-import 'package:observatory/src/elements/nav/refresh.dart';
-import 'package:observatory/src/elements/nav/top_menu.dart';
-import 'package:observatory/src/elements/nav/vm_menu.dart';
-import 'package:observatory/src/elements/object_common.dart';
-import 'package:observatory/src/elements/object_view.dart';
-import 'package:observatory/src/elements/objectpool_ref.dart';
-import 'package:observatory/src/elements/objectpool_view.dart';
-import 'package:observatory/src/elements/objectstore_view.dart';
-import 'package:observatory/src/elements/observatory_application.dart';
-import 'package:observatory/src/elements/pc_descriptors_ref.dart';
-import 'package:observatory/src/elements/persistent_handles.dart';
-import 'package:observatory/src/elements/ports.dart';
-import 'package:observatory/src/elements/sample_buffer_control.dart';
-import 'package:observatory/src/elements/script_inset.dart';
-import 'package:observatory/src/elements/script_ref.dart';
-import 'package:observatory/src/elements/script_view.dart';
-import 'package:observatory/src/elements/sentinel_value.dart';
-import 'package:observatory/src/elements/sentinel_view.dart';
-import 'package:observatory/src/elements/singletargetcache_ref.dart';
-import 'package:observatory/src/elements/singletargetcache_view.dart';
-import 'package:observatory/src/elements/source_inset.dart';
-import 'package:observatory/src/elements/source_link.dart';
-import 'package:observatory/src/elements/stack_trace_tree_config.dart';
-import 'package:observatory/src/elements/strongly_reachable_instances.dart';
-import 'package:observatory/src/elements/subtypetestcache_ref.dart';
-import 'package:observatory/src/elements/subtypetestcache_view.dart';
-import 'package:observatory/src/elements/timeline_page.dart';
-import 'package:observatory/src/elements/timeline/dashboard.dart';
-import 'package:observatory/src/elements/type_arguments_ref.dart';
-import 'package:observatory/src/elements/unknown_ref.dart';
-import 'package:observatory/src/elements/unlinkedcall_ref.dart';
-import 'package:observatory/src/elements/unlinkedcall_view.dart';
-import 'package:observatory/src/elements/view_footer.dart';
-import 'package:observatory/src/elements/vm_connect.dart';
-import 'package:observatory/src/elements/vm_connect_target.dart';
-import 'package:observatory/src/elements/vm_view.dart';
-
-export 'package:observatory/src/elements/helpers/rendering_queue.dart';
-
 export 'package:observatory/src/elements/allocation_profile.dart';
 export 'package:observatory/src/elements/class_allocation_profile.dart';
 export 'package:observatory/src/elements/class_instances.dart';
@@ -131,6 +29,7 @@
 export 'package:observatory/src/elements/general_error.dart';
 export 'package:observatory/src/elements/heap_map.dart';
 export 'package:observatory/src/elements/heap_snapshot.dart';
+export 'package:observatory/src/elements/helpers/rendering_queue.dart';
 export 'package:observatory/src/elements/icdata_ref.dart';
 export 'package:observatory/src/elements/icdata_view.dart';
 export 'package:observatory/src/elements/instance_ref.dart';
@@ -189,8 +88,8 @@
 export 'package:observatory/src/elements/strongly_reachable_instances.dart';
 export 'package:observatory/src/elements/subtypetestcache_ref.dart';
 export 'package:observatory/src/elements/subtypetestcache_view.dart';
-export 'package:observatory/src/elements/timeline_page.dart';
 export 'package:observatory/src/elements/timeline/dashboard.dart';
+export 'package:observatory/src/elements/timeline_page.dart';
 export 'package:observatory/src/elements/type_arguments_ref.dart';
 export 'package:observatory/src/elements/unknown_ref.dart';
 export 'package:observatory/src/elements/unlinkedcall_ref.dart';
@@ -199,112 +98,3 @@
 export 'package:observatory/src/elements/vm_connect.dart';
 export 'package:observatory/src/elements/vm_connect_target.dart';
 export 'package:observatory/src/elements/vm_view.dart';
-
-// Even though this function does not invoke any asynchronous operation
-// it is marked as async to allow future backward compatible changes.
-Future initElements() async {
-  AllocationProfileElement.tag.ensureRegistration();
-  ClassAllocationProfileElement.tag.ensureRegistration();
-  ClassInstancesElement.tag.ensureRegistration();
-  ClassRefElement.tag.ensureRegistration();
-  ClassTreeElement.tag.ensureRegistration();
-  ClassViewElement.tag.ensureRegistration();
-  CodeRefElement.tag.ensureRegistration();
-  CodeViewElement.tag.ensureRegistration();
-  ContextRefElement.tag.ensureRegistration();
-  ContextViewElement.tag.ensureRegistration();
-  CpuProfileElement.tag.ensureRegistration();
-  CpuProfileTableElement.tag.ensureRegistration();
-  CpuProfileVirtualTreeElement.tag.ensureRegistration();
-  CurlyBlockElement.tag.ensureRegistration();
-  DebuggerConsoleElement.tag.ensureRegistration();
-  DebuggerFrameElement.tag.ensureRegistration();
-  DebuggerInputElement.tag.ensureRegistration();
-  DebuggerMessageElement.tag.ensureRegistration();
-  DebuggerPageElement.tag.ensureRegistration();
-  DebuggerStackElement.tag.ensureRegistration();
-  ErrorRefElement.tag.ensureRegistration();
-  ErrorViewElement.tag.ensureRegistration();
-  EvalBoxElement.tag.ensureRegistration();
-  FieldRefElement.tag.ensureRegistration();
-  FieldViewElement.tag.ensureRegistration();
-  FlagListElement.tag.ensureRegistration();
-  FunctionRefElement.tag.ensureRegistration();
-  FunctionViewElement.tag.ensureRegistration();
-  GeneralErrorElement.tag.ensureRegistration();
-  HeapMapElement.tag.ensureRegistration();
-  HeapSnapshotElement.tag.ensureRegistration();
-  ICDataRefElement.tag.ensureRegistration();
-  ICDataViewElement.tag.ensureRegistration();
-  InstanceRefElement.tag.ensureRegistration();
-  InstanceViewElement.tag.ensureRegistration();
-  IsolateCounterChartElement.tag.ensureRegistration();
-  IsolateLocationElement.tag.ensureRegistration();
-  IsolateReconnectElement.tag.ensureRegistration();
-  IsolateRefElement.tag.ensureRegistration();
-  IsolateRunStateElement.tag.ensureRegistration();
-  IsolateSharedSummaryElement.tag.ensureRegistration();
-  IsolateSummaryElement.tag.ensureRegistration();
-  IsolateViewElement.tag.ensureRegistration();
-  JSONViewElement.tag.ensureRegistration();
-  LibraryRefElement.tag.ensureRegistration();
-  LibraryViewElement.tag.ensureRegistration();
-  LocalVarDescriptorsRefElement.tag.ensureRegistration();
-  LoggingPageElement.tag.ensureRegistration();
-  MegamorphicCacheRefElement.tag.ensureRegistration();
-  MegamorphicCacheViewElement.tag.ensureRegistration();
-  MemoryDashboardElement.tag.ensureRegistration();
-  MemoryGraphElement.tag.ensureRegistration();
-  MetricDetailsElement.tag.ensureRegistration();
-  MetricGraphElement.tag.ensureRegistration();
-  MetricsPageElement.tag.ensureRegistration();
-  NativeMemoryProfileElement.tag.ensureRegistration();
-  NavClassMenuElement.tag.ensureRegistration();
-  NavIsolateMenuElement.tag.ensureRegistration();
-  NavLibraryMenuElement.tag.ensureRegistration();
-  NavMenuItemElement.tag.ensureRegistration();
-  NavNotifyElement.tag.ensureRegistration();
-  NavNotifyEventElement.tag.ensureRegistration();
-  NavNotifyExceptionElement.tag.ensureRegistration();
-  NavRefreshElement.tag.ensureRegistration();
-  NavTopMenuElement.tag.ensureRegistration();
-  NavVMMenuElement.tag.ensureRegistration();
-  ObjectCommonElement.tag.ensureRegistration();
-  ObjectPoolRefElement.tag.ensureRegistration();
-  ObjectPoolViewElement.tag.ensureRegistration();
-  ObjectStoreViewElement.tag.ensureRegistration();
-  ObjectViewElement.tag.ensureRegistration();
-  ObservatoryApplicationElement.tag.ensureRegistration();
-  PcDescriptorsRefElement.tag.ensureRegistration();
-  PersistentHandlesPageElement.tag.ensureRegistration();
-  PortsElement.tag.ensureRegistration();
-  SampleBufferControlElement.tag.ensureRegistration();
-  ScriptInsetElement.tag.ensureRegistration();
-  ScriptRefElement.tag.ensureRegistration();
-  ScriptViewElement.tag.ensureRegistration();
-  SearchBarElement.tag.ensureRegistration();
-  SentinelValueElement.tag.ensureRegistration();
-  SentinelViewElement.tag.ensureRegistration();
-  SingleTargetCacheRefElement.tag.ensureRegistration();
-  SingleTargetCacheViewElement.tag.ensureRegistration();
-  SourceInsetElement.tag.ensureRegistration();
-  SourceLinkElement.tag.ensureRegistration();
-  StackTraceTreeConfigElement.tag.ensureRegistration();
-  StronglyReachableInstancesElement.tag.ensureRegistration();
-  SubtypeTestCacheRefElement.tag.ensureRegistration();
-  SubtypeTestCacheViewElement.tag.ensureRegistration();
-  TimelinePageElement.tag.ensureRegistration();
-  TimelineDashboardElement.tag.ensureRegistration();
-  TypeArgumentsRefElement.tag.ensureRegistration();
-  UnknownObjectRefElement.tag.ensureRegistration();
-  UnlinkedCallRefElement.tag.ensureRegistration();
-  UnlinkedCallViewElement.tag.ensureRegistration();
-  VMConnectElement.tag.ensureRegistration();
-  VMConnectTargetElement.tag.ensureRegistration();
-  VMViewElement.tag.ensureRegistration();
-  ViewFooterElement.tag.ensureRegistration();
-  VirtualCollectionElement.tag.ensureRegistration();
-  VirtualCollectionElement.tag.ensureRegistration();
-  VirtualTreeElement.tag.ensureRegistration();
-  VirtualTreeElement.tag.ensureRegistration();
-}
diff --git a/runtime/observatory/lib/src/app/page.dart b/runtime/observatory/lib/src/app/page.dart
index 526e182..c03847f 100644
--- a/runtime/observatory/lib/src/app/page.dart
+++ b/runtime/observatory/lib/src/app/page.dart
@@ -133,7 +133,8 @@
   void onInstall() {
     if (element == null) {
       // Lazily create page.
-      element = new GeneralErrorElement(app.notifications, queue: app.queue);
+      element =
+          new GeneralErrorElement(app.notifications, queue: app.queue).element;
     }
   }
 
@@ -173,8 +174,9 @@
       VM vm = serviceObject;
       container.children = <Element>[
         new VMViewElement(vm, _vmrepository, app.events, app.notifications,
-            new IsolateRepository(app.vm), _scriptRepository,
-            queue: app.queue)
+                new IsolateRepository(app.vm), _scriptRepository,
+                queue: app.queue)
+            .element
       ];
     }).catchError((e, stack) {
       Logger.root.severe('VMPage visit error: $e');
@@ -190,8 +192,9 @@
   @override
   onInstall() {
     element = new FlagListElement(
-        app.vm, app.events, new FlagsRepository(app.vm), app.notifications,
-        queue: app.queue);
+            app.vm, app.events, new FlagsRepository(app.vm), app.notifications,
+            queue: app.queue)
+        .element;
   }
 
   void _visit(Uri uri) {
@@ -206,8 +209,9 @@
   onInstall() {
     if (element == null) {
       element = new NativeMemoryProfileElement(app.vm, app.events,
-          app.notifications, _nativeMemorySampleProfileRepository,
-          queue: app.queue);
+              app.notifications, _nativeMemorySampleProfileRepository,
+              queue: app.queue)
+          .element;
     }
     assert(element != null);
   }
@@ -247,247 +251,261 @@
     if (obj is Class) {
       container.children = <Element>[
         new ClassViewElement(
-            app.vm,
-            obj.isolate,
-            obj,
-            app.events,
-            app.notifications,
-            _classRepository,
-            _retainedSizeRepository,
-            _reachableSizeRepository,
-            _inboundReferencesRepository,
-            _retainingPathRepository,
-            _fieldRepository,
-            _scriptRepository,
-            _objectRepository,
-            _evalRepository,
-            _stronglyReachangleInstancesRepository,
-            _topRetainingInstancesRepository,
-            _classSampleProfileRepository,
-            queue: app.queue)
+                app.vm,
+                obj.isolate,
+                obj,
+                app.events,
+                app.notifications,
+                _classRepository,
+                _retainedSizeRepository,
+                _reachableSizeRepository,
+                _inboundReferencesRepository,
+                _retainingPathRepository,
+                _fieldRepository,
+                _scriptRepository,
+                _objectRepository,
+                _evalRepository,
+                _stronglyReachangleInstancesRepository,
+                _topRetainingInstancesRepository,
+                _classSampleProfileRepository,
+                queue: app.queue)
+            .element
       ];
     } else if (obj is Code) {
       await obj.loadScript();
       container.children = <Element>[
         new CodeViewElement(
-            app.vm,
-            obj.isolate,
-            obj,
-            app.events,
-            app.notifications,
-            _retainedSizeRepository,
-            _reachableSizeRepository,
-            _inboundReferencesRepository,
-            _retainingPathRepository,
-            _objectRepository,
-            queue: app.queue)
+                app.vm,
+                obj.isolate,
+                obj,
+                app.events,
+                app.notifications,
+                _retainedSizeRepository,
+                _reachableSizeRepository,
+                _inboundReferencesRepository,
+                _retainingPathRepository,
+                _objectRepository,
+                queue: app.queue)
+            .element
       ];
     } else if (obj is Context) {
       container.children = <Element>[
         new ContextViewElement(
-            app.vm,
-            obj.isolate,
-            obj,
-            app.events,
-            app.notifications,
-            _contextRepository,
-            _retainedSizeRepository,
-            _reachableSizeRepository,
-            _inboundReferencesRepository,
-            _retainingPathRepository,
-            _objectRepository,
-            queue: app.queue)
+                app.vm,
+                obj.isolate,
+                obj,
+                app.events,
+                app.notifications,
+                _contextRepository,
+                _retainedSizeRepository,
+                _reachableSizeRepository,
+                _inboundReferencesRepository,
+                _retainingPathRepository,
+                _objectRepository,
+                queue: app.queue)
+            .element
       ];
     } else if (obj is DartError) {
       container.children = <Element>[
-        new ErrorViewElement(app.notifications, obj, queue: app.queue)
+        new ErrorViewElement(app.notifications, obj, queue: app.queue).element
       ];
     } else if (obj is Field) {
       container.children = <Element>[
         new FieldViewElement(
-            app.vm,
-            obj.isolate,
-            obj,
-            app.events,
-            app.notifications,
-            _fieldRepository,
-            _classRepository,
-            _retainedSizeRepository,
-            _reachableSizeRepository,
-            _inboundReferencesRepository,
-            _retainingPathRepository,
-            _scriptRepository,
-            _objectRepository,
-            queue: app.queue)
+                app.vm,
+                obj.isolate,
+                obj,
+                app.events,
+                app.notifications,
+                _fieldRepository,
+                _classRepository,
+                _retainedSizeRepository,
+                _reachableSizeRepository,
+                _inboundReferencesRepository,
+                _retainingPathRepository,
+                _scriptRepository,
+                _objectRepository,
+                queue: app.queue)
+            .element
       ];
     } else if (obj is Instance) {
       container.children = <Element>[
         new InstanceViewElement(
-            app.vm,
-            obj.isolate,
-            obj,
-            app.events,
-            app.notifications,
-            _objectRepository,
-            _classRepository,
-            _retainedSizeRepository,
-            _reachableSizeRepository,
-            _inboundReferencesRepository,
-            _retainingPathRepository,
-            _scriptRepository,
-            _evalRepository,
-            _typeArgumentsRepository,
-            _breakpointRepository,
-            _functionRepository,
-            queue: app.queue)
+                app.vm,
+                obj.isolate,
+                obj,
+                app.events,
+                app.notifications,
+                _objectRepository,
+                _classRepository,
+                _retainedSizeRepository,
+                _reachableSizeRepository,
+                _inboundReferencesRepository,
+                _retainingPathRepository,
+                _scriptRepository,
+                _evalRepository,
+                _typeArgumentsRepository,
+                _breakpointRepository,
+                _functionRepository,
+                queue: app.queue)
+            .element
       ];
     } else if (obj is Isolate) {
       container.children = <Element>[
         new IsolateViewElement(
-            app.vm,
-            obj,
-            app.events,
-            app.notifications,
-            new IsolateRepository(app.vm),
-            _scriptRepository,
-            _functionRepository,
-            _libraryRepository,
-            _objectRepository,
-            _evalRepository,
-            queue: app.queue)
+                app.vm,
+                obj,
+                app.events,
+                app.notifications,
+                new IsolateRepository(app.vm),
+                _scriptRepository,
+                _functionRepository,
+                _libraryRepository,
+                _objectRepository,
+                _evalRepository,
+                queue: app.queue)
+            .element
       ];
     } else if (obj is ServiceFunction) {
       container.children = <Element>[
         new FunctionViewElement(
-            app.vm,
-            obj.isolate,
-            obj,
-            app.events,
-            app.notifications,
-            _functionRepository,
-            _classRepository,
-            _retainedSizeRepository,
-            _reachableSizeRepository,
-            _inboundReferencesRepository,
-            _retainingPathRepository,
-            _scriptRepository,
-            _objectRepository,
-            queue: app.queue)
+                app.vm,
+                obj.isolate,
+                obj,
+                app.events,
+                app.notifications,
+                _functionRepository,
+                _classRepository,
+                _retainedSizeRepository,
+                _reachableSizeRepository,
+                _inboundReferencesRepository,
+                _retainingPathRepository,
+                _scriptRepository,
+                _objectRepository,
+                queue: app.queue)
+            .element
       ];
     } else if (obj is ICData) {
       container.children = <Element>[
         new ICDataViewElement(
-            app.vm,
-            obj.isolate,
-            obj,
-            app.events,
-            app.notifications,
-            _icdataRepository,
-            _retainedSizeRepository,
-            _reachableSizeRepository,
-            _inboundReferencesRepository,
-            _retainingPathRepository,
-            _objectRepository,
-            queue: app.queue)
+                app.vm,
+                obj.isolate,
+                obj,
+                app.events,
+                app.notifications,
+                _icdataRepository,
+                _retainedSizeRepository,
+                _reachableSizeRepository,
+                _inboundReferencesRepository,
+                _retainingPathRepository,
+                _objectRepository,
+                queue: app.queue)
+            .element
       ];
     } else if (obj is SingleTargetCache) {
       container.children = <Element>[
         new SingleTargetCacheViewElement(
-            app.vm,
-            obj.isolate,
-            obj,
-            app.events,
-            app.notifications,
-            _singleTargetCacheRepository,
-            _retainedSizeRepository,
-            _reachableSizeRepository,
-            _inboundReferencesRepository,
-            _retainingPathRepository,
-            _objectRepository,
-            queue: app.queue)
+                app.vm,
+                obj.isolate,
+                obj,
+                app.events,
+                app.notifications,
+                _singleTargetCacheRepository,
+                _retainedSizeRepository,
+                _reachableSizeRepository,
+                _inboundReferencesRepository,
+                _retainingPathRepository,
+                _objectRepository,
+                queue: app.queue)
+            .element
       ];
     } else if (obj is SubtypeTestCache) {
       container.children = <Element>[
         new SubtypeTestCacheViewElement(
-            app.vm,
-            obj.isolate,
-            obj,
-            app.events,
-            app.notifications,
-            _subtypeTestCacheRepository,
-            _retainedSizeRepository,
-            _reachableSizeRepository,
-            _inboundReferencesRepository,
-            _retainingPathRepository,
-            _objectRepository,
-            queue: app.queue)
+                app.vm,
+                obj.isolate,
+                obj,
+                app.events,
+                app.notifications,
+                _subtypeTestCacheRepository,
+                _retainedSizeRepository,
+                _reachableSizeRepository,
+                _inboundReferencesRepository,
+                _retainingPathRepository,
+                _objectRepository,
+                queue: app.queue)
+            .element
       ];
     } else if (obj is UnlinkedCall) {
       container.children = <Element>[
         new UnlinkedCallViewElement(
-            app.vm,
-            obj.isolate,
-            obj,
-            app.events,
-            app.notifications,
-            _unlinkedCallRepository,
-            _retainedSizeRepository,
-            _reachableSizeRepository,
-            _inboundReferencesRepository,
-            _retainingPathRepository,
-            _objectRepository,
-            queue: app.queue)
+                app.vm,
+                obj.isolate,
+                obj,
+                app.events,
+                app.notifications,
+                _unlinkedCallRepository,
+                _retainedSizeRepository,
+                _reachableSizeRepository,
+                _inboundReferencesRepository,
+                _retainingPathRepository,
+                _objectRepository,
+                queue: app.queue)
+            .element
       ];
     } else if (obj is Library) {
       container.children = <Element>[
         new LibraryViewElement(
-            app.vm,
-            obj.isolate,
-            obj,
-            app.events,
-            app.notifications,
-            _libraryRepository,
-            _fieldRepository,
-            _retainedSizeRepository,
-            _reachableSizeRepository,
-            _inboundReferencesRepository,
-            _retainingPathRepository,
-            _scriptRepository,
-            _objectRepository,
-            _evalRepository,
-            queue: app.queue)
+                app.vm,
+                obj.isolate,
+                obj,
+                app.events,
+                app.notifications,
+                _libraryRepository,
+                _fieldRepository,
+                _retainedSizeRepository,
+                _reachableSizeRepository,
+                _inboundReferencesRepository,
+                _retainingPathRepository,
+                _scriptRepository,
+                _objectRepository,
+                _evalRepository,
+                queue: app.queue)
+            .element
       ];
     } else if (obj is MegamorphicCache) {
       container.children = <Element>[
         new MegamorphicCacheViewElement(
-            app.vm,
-            obj.isolate,
-            obj,
-            app.events,
-            app.notifications,
-            _megamorphicCacheRepository,
-            _retainedSizeRepository,
-            _reachableSizeRepository,
-            _inboundReferencesRepository,
-            _retainingPathRepository,
-            _objectRepository,
-            queue: app.queue)
+                app.vm,
+                obj.isolate,
+                obj,
+                app.events,
+                app.notifications,
+                _megamorphicCacheRepository,
+                _retainedSizeRepository,
+                _reachableSizeRepository,
+                _inboundReferencesRepository,
+                _retainingPathRepository,
+                _objectRepository,
+                queue: app.queue)
+            .element
       ];
     } else if (obj is ObjectPool) {
       container.children = <Element>[
         new ObjectPoolViewElement(
-            app.vm,
-            obj.isolate,
-            obj,
-            app.events,
-            app.notifications,
-            _objectPoolRepository,
-            _retainedSizeRepository,
-            _reachableSizeRepository,
-            _inboundReferencesRepository,
-            _retainingPathRepository,
-            _objectRepository,
-            queue: app.queue)
+                app.vm,
+                obj.isolate,
+                obj,
+                app.events,
+                app.notifications,
+                _objectPoolRepository,
+                _retainedSizeRepository,
+                _reachableSizeRepository,
+                _inboundReferencesRepository,
+                _retainingPathRepository,
+                _objectRepository,
+                queue: app.queue)
+            .element
       ];
     } else if (obj is Script) {
       var pos;
@@ -498,44 +516,47 @@
       }
       container.children = <Element>[
         new ScriptViewElement(
-            app.vm,
-            obj.isolate,
-            obj,
-            app.events,
-            app.notifications,
-            _scriptRepository,
-            _retainedSizeRepository,
-            _reachableSizeRepository,
-            _inboundReferencesRepository,
-            _retainingPathRepository,
-            _objectRepository,
-            pos: pos,
-            queue: app.queue)
+                app.vm,
+                obj.isolate,
+                obj,
+                app.events,
+                app.notifications,
+                _scriptRepository,
+                _retainedSizeRepository,
+                _reachableSizeRepository,
+                _inboundReferencesRepository,
+                _retainingPathRepository,
+                _objectRepository,
+                pos: pos,
+                queue: app.queue)
+            .element
       ];
     } else if (obj is HeapObject) {
       container.children = <Element>[
         new ObjectViewElement(
-            app.vm,
-            obj.isolate,
-            obj,
-            app.events,
-            app.notifications,
-            _objectRepository,
-            _retainedSizeRepository,
-            _reachableSizeRepository,
-            _inboundReferencesRepository,
-            _retainingPathRepository,
-            queue: app.queue)
+                app.vm,
+                obj.isolate,
+                obj,
+                app.events,
+                app.notifications,
+                _objectRepository,
+                _retainedSizeRepository,
+                _reachableSizeRepository,
+                _inboundReferencesRepository,
+                _retainingPathRepository,
+                queue: app.queue)
+            .element
       ];
     } else if (obj is Sentinel) {
       container.children = <Element>[
         new SentinelViewElement(
-            app.vm, obj.isolate, obj, app.events, app.notifications,
-            queue: app.queue)
+                app.vm, obj.isolate, obj, app.events, app.notifications,
+                queue: app.queue)
+            .element
       ];
     } else {
       container.children = <Element>[
-        new JSONViewElement(obj, app.notifications, queue: app.queue)
+        new JSONViewElement(obj, app.notifications, queue: app.queue).element
       ];
     }
   }
@@ -556,8 +577,9 @@
     super._visit(uri);
     getIsolate(uri).then((isolate) {
       container.children = <Element>[
-        new ClassTreeElement(
-            app.vm, isolate, app.events, app.notifications, _classRepository)
+        new ClassTreeElement(app.vm, isolate, app.events, app.notifications,
+                _classRepository)
+            .element
       ];
     });
   }
@@ -573,7 +595,8 @@
     getIsolate(uri).then((isolate) async {
       container.children = <Element>[
         new DebuggerPageElement(
-            isolate, _objectRepository, _scriptRepository, app.events)
+                isolate, _objectRepository, _scriptRepository, app.events)
+            .element
       ];
     });
   }
@@ -602,7 +625,8 @@
     getIsolate(uri).then((isolate) async {
       container.children = <Element>[
         new ObjectStoreViewElement(isolate.vm, isolate, app.events,
-            app.notifications, _objectstoreRepository, _objectRepository)
+                app.notifications, _objectstoreRepository, _objectRepository)
+            .element
       ];
     });
   }
@@ -625,7 +649,8 @@
     getIsolate(uri).then((isolate) {
       container.children = <Element>[
         new CpuProfileElement(isolate.vm, isolate, app.events,
-            app.notifications, _isolateSampleProfileRepository)
+                app.notifications, _isolateSampleProfileRepository)
+            .element
       ];
     });
   }
@@ -648,7 +673,8 @@
     getIsolate(uri).then((isolate) {
       container.children = <Element>[
         new CpuProfileTableElement(isolate.vm, isolate, app.events,
-            app.notifications, _isolateSampleProfileRepository)
+                app.notifications, _isolateSampleProfileRepository)
+            .element
       ];
     });
   }
@@ -671,8 +697,9 @@
     getIsolate(uri).then((isolate) {
       container.children = <Element>[
         new AllocationProfileElement(isolate.vm, isolate, app.events,
-            app.notifications, _allocationProfileRepository,
-            queue: app.queue)
+                app.notifications, _allocationProfileRepository,
+                queue: app.queue)
+            .element
       ];
     });
   }
@@ -712,16 +739,17 @@
       await Future.wait(vm.isolates.map((i) => i.load()));
       container.children = <Element>[
         new MemoryDashboardElement(
-            vm,
-            _vmrepository,
-            new IsolateRepository(vm),
-            editor,
-            _allocationProfileRepository,
-            _heapSnapshotRepository,
-            _objectRepository,
-            app.events,
-            app.notifications,
-            queue: app.queue)
+                vm,
+                _vmrepository,
+                new IsolateRepository(vm),
+                editor,
+                _allocationProfileRepository,
+                _heapSnapshotRepository,
+                _objectRepository,
+                app.events,
+                app.notifications,
+                queue: app.queue)
+            .element
       ];
     }).catchError((e, stack) {
       Logger.root.severe('MemoryDashboard visit error: $e');
@@ -755,8 +783,9 @@
     getIsolate(uri).then((isolate) {
       container.children = <Element>[
         new PortsElement(isolate.vm, isolate, app.events, app.notifications,
-            _portsRepository, _objectRepository,
-            queue: app.queue)
+                _portsRepository, _objectRepository,
+                queue: app.queue)
+            .element
       ];
     });
   }
@@ -777,9 +806,15 @@
     super._visit(uri);
     getIsolate(uri).then((isolate) {
       container.children = <Element>[
-        new PersistentHandlesPageElement(isolate.vm, isolate, app.events,
-            app.notifications, _persistentHandlesRepository, _objectRepository,
-            queue: app.queue)
+        new PersistentHandlesPageElement(
+                isolate.vm,
+                isolate,
+                app.events,
+                app.notifications,
+                _persistentHandlesRepository,
+                _objectRepository,
+                queue: app.queue)
+            .element
       ];
     });
   }
@@ -801,7 +836,8 @@
     getIsolate(uri).then((isolate) {
       container.children = <Element>[
         new HeapMapElement(isolate.vm, isolate, app.events, app.notifications,
-            queue: app.queue)
+                queue: app.queue)
+            .element
       ];
     });
   }
@@ -823,8 +859,9 @@
     getIsolate(uri).then((isolate) {
       container.children = <Element>[
         new HeapSnapshotElement(isolate.vm, isolate, app.events,
-            app.notifications, _heapSnapshotRepository, _objectRepository,
-            queue: app.queue)
+                app.notifications, _heapSnapshotRepository, _objectRepository,
+                queue: app.queue)
+            .element
       ];
     });
   }
@@ -861,7 +898,8 @@
     getIsolate(uri).then((isolate) {
       container.children = <Element>[
         new LoggingPageElement(app.vm, isolate, app.events, app.notifications,
-            queue: app.queue)
+                queue: app.queue)
+            .element
       ];
     });
   }
@@ -872,8 +910,9 @@
 
   void onInstall() {
     element = new ErrorViewElement(
-        app.notifications, app.lastErrorOrException as DartError,
-        queue: app.queue);
+            app.notifications, app.lastErrorOrException as DartError,
+            queue: app.queue)
+        .element;
   }
 
   void _visit(Uri uri) {
@@ -891,8 +930,9 @@
   void onInstall() {
     if (element == null) {
       element = new VMConnectElement(ObservatoryApplication.app.targets,
-          ObservatoryApplication.app.notifications,
-          queue: ObservatoryApplication.app.queue);
+              ObservatoryApplication.app.notifications,
+              queue: ObservatoryApplication.app.queue)
+          .element;
     }
     assert(element != null);
   }
@@ -918,11 +958,12 @@
     app.vm.reload();
     container.children = <Element>[
       new IsolateReconnectElement(
-          app.vm,
-          app.events,
-          app.notifications,
-          uri.queryParameters['isolateId'],
-          Uri.parse(uri.queryParameters['originalUri']))
+              app.vm,
+              app.events,
+              app.notifications,
+              uri.queryParameters['isolateId'],
+              Uri.parse(uri.queryParameters['originalUri']))
+          .element
     ];
     assert(element != null);
     assert(canVisit(uri));
@@ -946,8 +987,9 @@
       await _metricRepository.startSampling(isolate);
       container.children = <Element>[
         new MetricsPageElement(isolate.vm, isolate, app.events,
-            app.notifications, _metricRepository,
-            queue: app.queue)
+                app.notifications, _metricRepository,
+                queue: app.queue)
+            .element
       ];
     });
   }
@@ -971,8 +1013,9 @@
 
   void onInstall() {
     element = new TimelinePageElement(
-        app.vm, _timelineRepository, app.events, app.notifications,
-        queue: app.queue);
+            app.vm, _timelineRepository, app.events, app.notifications,
+            queue: app.queue)
+        .element;
   }
 
   void _visit(Uri uri) {
@@ -998,8 +1041,9 @@
     app.vm.load().then((_) {
       container.children = <Element>[
         new TimelineDashboardElement(
-            app.vm, _timelineRepository, app.notifications,
-            queue: app.queue)
+                app.vm, _timelineRepository, app.notifications,
+                queue: app.queue)
+            .element
       ];
     });
   }
diff --git a/runtime/observatory/lib/src/elements/allocation_profile.dart b/runtime/observatory/lib/src/elements/allocation_profile.dart
index d1e4f86..b4ddc92 100644
--- a/runtime/observatory/lib/src/elements/allocation_profile.dart
+++ b/runtime/observatory/lib/src/elements/allocation_profile.dart
@@ -38,7 +38,7 @@
 
 enum _SortingDirection { ascending, descending }
 
-class AllocationProfileElement extends HtmlElement implements Renderable {
+class AllocationProfileElement extends CustomElement implements Renderable {
   static const tag = const Tag<AllocationProfileElement>('allocation-profile',
       dependencies: const [
         ClassRefElement.tag,
@@ -83,7 +83,7 @@
     assert(events != null);
     assert(notifications != null);
     assert(repository != null);
-    AllocationProfileElement e = document.createElement(tag.name);
+    AllocationProfileElement e = new AllocationProfileElement.created();
     e._r = new RenderingScheduler<AllocationProfileElement>(e, queue: queue);
     e._vm = vm;
     e._isolate = isolate;
@@ -93,7 +93,7 @@
     return e;
   }
 
-  AllocationProfileElement.created() : super.created();
+  AllocationProfileElement.created() : super.created(tag);
 
   @override
   attached() {
@@ -118,19 +118,23 @@
   void render() {
     children = <Element>[
       navBar(<Element>[
-        new NavTopMenuElement(queue: _r.queue),
-        new NavVMMenuElement(_vm, _events, queue: _r.queue),
-        new NavIsolateMenuElement(_isolate, _events, queue: _r.queue),
+        new NavTopMenuElement(queue: _r.queue).element,
+        new NavVMMenuElement(_vm, _events, queue: _r.queue).element,
+        new NavIsolateMenuElement(_isolate, _events, queue: _r.queue).element,
         navMenu('allocation profile'),
-        new NavRefreshElement(
-            label: 'Download', disabled: _profile == null, queue: _r.queue)
-          ..onRefresh.listen((_) => _downloadCSV()),
-        new NavRefreshElement(label: 'Reset Accumulator', queue: _r.queue)
-          ..onRefresh.listen((_) => _refresh(reset: true)),
-        new NavRefreshElement(label: 'GC', queue: _r.queue)
-          ..onRefresh.listen((_) => _refresh(gc: true)),
-        new NavRefreshElement(queue: _r.queue)
-          ..onRefresh.listen((_) => _refresh()),
+        (new NavRefreshElement(
+                label: 'Download', disabled: _profile == null, queue: _r.queue)
+              ..onRefresh.listen((_) => _downloadCSV()))
+            .element,
+        (new NavRefreshElement(label: 'Reset Accumulator', queue: _r.queue)
+              ..onRefresh.listen((_) => _refresh(reset: true)))
+            .element,
+        (new NavRefreshElement(label: 'GC', queue: _r.queue)
+              ..onRefresh.listen((_) => _refresh(gc: true)))
+            .element,
+        (new NavRefreshElement(queue: _r.queue)
+              ..onRefresh.listen((_) => _refresh()))
+            .element,
         new DivElement()
           ..classes = ['nav-option']
           ..children = <Element>[
@@ -142,7 +146,7 @@
               ..htmlFor = 'allocation-profile-auto-refresh'
               ..text = 'Auto-refresh on GC'
           ],
-        new NavNotifyElement(_notifications, queue: _r.queue)
+        new NavNotifyElement(_notifications, queue: _r.queue).element
       ]),
       new DivElement()
         ..classes = ['content-centered-big']
@@ -252,11 +256,12 @@
           ..classes = _isCompacted ? ['collection', 'expanded'] : ['collection']
           ..children = <Element>[
             new VirtualCollectionElement(
-                _createCollectionLine, _updateCollectionLine,
-                createHeader: _createCollectionHeader,
-                search: _search,
-                items: _profile.members.toList()..sort(_createSorter()),
-                queue: _r.queue)
+                    _createCollectionLine, _updateCollectionLine,
+                    createHeader: _createCollectionHeader,
+                    search: _search,
+                    items: _profile.members.toList()..sort(_createSorter()),
+                    queue: _r.queue)
+                .element
           ]
       ]);
       _renderGraph(newChartHost, newChartLegend, _profile.newSpace);
@@ -476,6 +481,7 @@
     e.children[10].text = Utils.formatSize(_getOldCurrentSize(item));
     e.children[11].text = '${_getOldCurrentInstances(item)}';
     e.children[12] = new ClassRefElement(_isolate, item.clazz, queue: _r.queue)
+        .element
       ..classes = ['name'];
   }
 
diff --git a/runtime/observatory/lib/src/elements/class_allocation_profile.dart b/runtime/observatory/lib/src/elements/class_allocation_profile.dart
index 60dadc3..f9d3e2e 100644
--- a/runtime/observatory/lib/src/elements/class_allocation_profile.dart
+++ b/runtime/observatory/lib/src/elements/class_allocation_profile.dart
@@ -11,7 +11,8 @@
 import 'package:observatory/src/elements/sample_buffer_control.dart';
 import 'package:observatory/src/elements/stack_trace_tree_config.dart';
 
-class ClassAllocationProfileElement extends HtmlElement implements Renderable {
+class ClassAllocationProfileElement extends CustomElement
+    implements Renderable {
   static const tag = const Tag<ClassAllocationProfileElement>(
       'class-allocation-profile',
       dependencies: const [
@@ -45,7 +46,8 @@
     assert(isolate != null);
     assert(cls != null);
     assert(profiles != null);
-    ClassAllocationProfileElement e = document.createElement(tag.name);
+    ClassAllocationProfileElement e =
+        new ClassAllocationProfileElement.created();
     e._r =
         new RenderingScheduler<ClassAllocationProfileElement>(e, queue: queue);
     e._vm = vm;
@@ -55,7 +57,7 @@
     return e;
   }
 
-  ClassAllocationProfileElement.created() : super.created();
+  ClassAllocationProfileElement.created() : super.created(tag);
 
   @override
   void attached() {
@@ -77,31 +79,34 @@
       return;
     }
     final content = <HtmlElement>[
-      new SampleBufferControlElement(_vm, _progress, _progressStream,
-          selectedTag: _tag, queue: _r.queue)
-        ..onTagChange.listen((e) {
-          _tag = e.element.selectedTag;
-          _request(forceFetch: true);
-        })
+      (new SampleBufferControlElement(_vm, _progress, _progressStream,
+              selectedTag: _tag, queue: _r.queue)
+            ..onTagChange.listen((e) {
+              _tag = e.element.selectedTag;
+              _request(forceFetch: true);
+            }))
+          .element
     ];
     if (_progress.status == M.SampleProfileLoadingStatus.loaded) {
       CpuProfileVirtualTreeElement tree;
       content.addAll([
         new BRElement(),
-        new StackTraceTreeConfigElement(
-            mode: _mode,
-            direction: _direction,
-            showFilter: false,
-            queue: _r.queue)
-          ..onModeChange.listen((e) {
-            _mode = tree.mode = e.element.mode;
-          })
-          ..onDirectionChange.listen((e) {
-            _direction = tree.direction = e.element.direction;
-          }),
+        (new StackTraceTreeConfigElement(
+                mode: _mode,
+                direction: _direction,
+                showFilter: false,
+                queue: _r.queue)
+              ..onModeChange.listen((e) {
+                _mode = tree.mode = e.element.mode;
+              })
+              ..onDirectionChange.listen((e) {
+                _direction = tree.direction = e.element.direction;
+              }))
+            .element,
         new BRElement(),
-        tree = new CpuProfileVirtualTreeElement(_isolate, _progress.profile,
-            queue: _r.queue)
+        (tree = new CpuProfileVirtualTreeElement(_isolate, _progress.profile,
+                queue: _r.queue))
+            .element
       ]);
     }
     children = content;
diff --git a/runtime/observatory/lib/src/elements/class_instances.dart b/runtime/observatory/lib/src/elements/class_instances.dart
index beb1049..0ddb4e0 100644
--- a/runtime/observatory/lib/src/elements/class_instances.dart
+++ b/runtime/observatory/lib/src/elements/class_instances.dart
@@ -15,7 +15,7 @@
 import 'package:observatory/src/elements/top_retaining_instances.dart';
 import 'package:observatory/utils.dart';
 
-class ClassInstancesElement extends HtmlElement implements Renderable {
+class ClassInstancesElement extends CustomElement implements Renderable {
   static const tag =
       const Tag<ClassInstancesElement>('class-instances', dependencies: const [
     ClassRefElement.tag,
@@ -59,7 +59,7 @@
     assert(stronglyReachableInstances != null);
     assert(topRetainingInstances != null);
     assert(objects != null);
-    ClassInstancesElement e = document.createElement(tag.name);
+    ClassInstancesElement e = new ClassInstancesElement.created();
     e._r = new RenderingScheduler<ClassInstancesElement>(e, queue: queue);
     e._isolate = isolate;
     e._cls = cls;
@@ -71,7 +71,7 @@
     return e;
   }
 
-  ClassInstancesElement.created() : super.created();
+  ClassInstancesElement.created() : super.created(tag);
 
   @override
   void attached() {
@@ -100,8 +100,8 @@
             queue: _r.queue);
     final instanceCount =
         _cls.newSpace.current.instances + _cls.oldSpace.current.instances;
-    final size = Utils
-        .formatSize(_cls.newSpace.current.bytes + _cls.oldSpace.current.bytes);
+    final size = Utils.formatSize(
+        _cls.newSpace.current.bytes + _cls.oldSpace.current.bytes);
     children = <Element>[
       new DivElement()
         ..classes = ['memberList']
@@ -124,7 +124,7 @@
                 ..text = 'strongly reachable ',
               new DivElement()
                 ..classes = ['memberValue']
-                ..children = <Element>[_strong]
+                ..children = <Element>[_strong.element]
             ],
           new DivElement()
             ..classes = ['memberItem']
@@ -158,7 +158,7 @@
                 ..text = 'toplist by retained memory ',
               new DivElement()
                 ..classes = ['memberValue']
-                ..children = <Element>[_topRetainig]
+                ..children = <Element>[_topRetainig.element]
             ]
         ]
     ];
@@ -168,12 +168,13 @@
     final content = <Element>[];
     if (_reachableSize != null) {
       if (_reachableSize.isSentinel) {
-        content.add(new SentinelValueElement(_reachableSize.asSentinel,
-            queue: _r.queue));
+        content.add(
+            new SentinelValueElement(_reachableSize.asSentinel, queue: _r.queue)
+                .element);
       } else {
         content.add(new SpanElement()
-          ..text = Utils
-              .formatSize(int.parse(_reachableSize.asValue.valueAsString)));
+          ..text = Utils.formatSize(
+              int.parse(_reachableSize.asValue.valueAsString)));
       }
     } else {
       content.add(new SpanElement()..text = '...');
@@ -196,8 +197,9 @@
     final content = <Element>[];
     if (_retainedSize != null) {
       if (_retainedSize.isSentinel) {
-        content.add(new SentinelValueElement(_retainedSize.asSentinel,
-            queue: _r.queue));
+        content.add(
+            new SentinelValueElement(_retainedSize.asSentinel, queue: _r.queue)
+                .element);
       } else {
         content.add(new SpanElement()
           ..text =
diff --git a/runtime/observatory/lib/src/elements/class_ref.dart b/runtime/observatory/lib/src/elements/class_ref.dart
index eee3cb6..409dddb 100644
--- a/runtime/observatory/lib/src/elements/class_ref.dart
+++ b/runtime/observatory/lib/src/elements/class_ref.dart
@@ -9,7 +9,7 @@
 import 'package:observatory/src/elements/helpers/tag.dart';
 import 'package:observatory/src/elements/helpers/uris.dart';
 
-class ClassRefElement extends HtmlElement implements Renderable {
+class ClassRefElement extends CustomElement implements Renderable {
   static const tag = const Tag<ClassRefElement>('class-ref');
 
   RenderingScheduler<ClassRefElement> _r;
@@ -25,14 +25,14 @@
   factory ClassRefElement(M.IsolateRef isolate, M.ClassRef cls,
       {RenderingQueue queue}) {
     assert(cls != null);
-    ClassRefElement e = document.createElement(tag.name);
+    ClassRefElement e = new ClassRefElement.created();
     e._r = new RenderingScheduler<ClassRefElement>(e, queue: queue);
     e._isolate = isolate;
     e._class = cls;
     return e;
   }
 
-  ClassRefElement.created() : super.created();
+  ClassRefElement.created() : super.created(tag);
 
   @override
   void attached() {
diff --git a/runtime/observatory/lib/src/elements/class_tree.dart b/runtime/observatory/lib/src/elements/class_tree.dart
index 505eef9..83c3182 100644
--- a/runtime/observatory/lib/src/elements/class_tree.dart
+++ b/runtime/observatory/lib/src/elements/class_tree.dart
@@ -18,7 +18,7 @@
 import 'package:observatory/src/elements/nav/top_menu.dart';
 import 'package:observatory/src/elements/nav/vm_menu.dart';
 
-class ClassTreeElement extends HtmlElement implements Renderable {
+class ClassTreeElement extends CustomElement implements Renderable {
   static const tag =
       const Tag<ClassTreeElement>('class-tree', dependencies: const [
     ClassRefElement.tag,
@@ -54,7 +54,7 @@
     assert(events != null);
     assert(notifications != null);
     assert(classes != null);
-    ClassTreeElement e = document.createElement(tag.name);
+    ClassTreeElement e = new ClassTreeElement.created();
     e._r = new RenderingScheduler<ClassTreeElement>(e, queue: queue);
     e._vm = vm;
     e._isolate = isolate;
@@ -64,7 +64,7 @@
     return e;
   }
 
-  ClassTreeElement.created() : super.created();
+  ClassTreeElement.created() : super.created(tag);
 
   @override
   void attached() {
@@ -85,11 +85,11 @@
   void render() {
     children = <Element>[
       navBar(<Element>[
-        new NavTopMenuElement(queue: _r.queue),
-        new NavVMMenuElement(_vm, _events, queue: _r.queue),
-        new NavIsolateMenuElement(_isolate, _events, queue: _r.queue),
+        new NavTopMenuElement(queue: _r.queue).element,
+        new NavVMMenuElement(_vm, _events, queue: _r.queue).element,
+        new NavIsolateMenuElement(_isolate, _events, queue: _r.queue).element,
         navMenu('class hierarchy'),
-        new NavNotifyElement(_notifications, queue: _r.queue)
+        new NavNotifyElement(_notifications, queue: _r.queue).element
       ]),
       new DivElement()
         ..classes = ['content-centered']
@@ -109,7 +109,7 @@
     _tree = new VirtualTreeElement(_create, _update, _children,
         items: [_object], search: _search, queue: _r.queue);
     _tree.expand(_object, autoExpandSingleChildNodes: true);
-    return _tree;
+    return _tree.element;
   }
 
   Future _refresh() async {
@@ -164,7 +164,7 @@
       el.children[1].text = _tree.isExpanded(cls) ? 'â–¼' : 'â–º';
     }
     el.children[2].children = <Element>[
-      new ClassRefElement(_isolate, cls, queue: _r.queue)
+      new ClassRefElement(_isolate, cls, queue: _r.queue).element
     ];
     if (_mixins[cls.id] != null) {
       el.children[2].children.addAll(_createMixins(_mixins[cls.id]));
@@ -183,7 +183,8 @@
               type.typeClass == null
                   ? (new SpanElement()..text = type.name.split('<').first)
                   : new ClassRefElement(_isolate, type.typeClass,
-                      queue: _r.queue)
+                          queue: _r.queue)
+                      .element
             ])
         .toList();
     children.first.text = ' with ';
diff --git a/runtime/observatory/lib/src/elements/class_view.dart b/runtime/observatory/lib/src/elements/class_view.dart
index f2ceec0..fc8254e 100644
--- a/runtime/observatory/lib/src/elements/class_view.dart
+++ b/runtime/observatory/lib/src/elements/class_view.dart
@@ -32,7 +32,7 @@
 import 'package:observatory/src/elements/source_link.dart';
 import 'package:observatory/src/elements/view_footer.dart';
 
-class ClassViewElement extends HtmlElement implements Renderable {
+class ClassViewElement extends CustomElement implements Renderable {
   static const tag =
       const Tag<ClassViewElement>('class-view', dependencies: const [
     ClassInstancesElement.tag,
@@ -120,7 +120,7 @@
     assert(stronglyReachable != null);
     assert(topRetained != null);
     assert(profiles != null);
-    ClassViewElement e = document.createElement(tag.name);
+    ClassViewElement e = new ClassViewElement.created();
     e._r = new RenderingScheduler<ClassViewElement>(e, queue: queue);
     e._vm = vm;
     e._isolate = isolate;
@@ -142,7 +142,7 @@
     return e;
   }
 
-  ClassViewElement.created() : super.created();
+  ClassViewElement.created() : super.created(tag);
 
   @override
   attached() {
@@ -186,34 +186,36 @@
     }
     children = <Element>[
       navBar(<Element>[
-        new NavTopMenuElement(queue: _r.queue),
-        new NavVMMenuElement(_vm, _events, queue: _r.queue),
-        new NavIsolateMenuElement(_isolate, _events, queue: _r.queue),
-        new NavClassMenuElement(_isolate, _cls, queue: _r.queue),
-        new NavRefreshElement(
-            label: 'Refresh Allocation Profile', queue: _r.queue)
-          ..onRefresh.listen((e) {
-            e.element.disabled = true;
-            _loadProfile = true;
-            _r.dirty();
-          }),
-        new NavRefreshElement(queue: _r.queue)
-          ..onRefresh.listen((e) {
-            e.element.disabled = true;
-            _common = null;
-            _classInstances = null;
-            _fieldsExpanded = null;
-            _functionsExpanded = null;
-            _refresh();
-          }),
-        new NavNotifyElement(_notifications, queue: _r.queue)
+        new NavTopMenuElement(queue: _r.queue).element,
+        new NavVMMenuElement(_vm, _events, queue: _r.queue).element,
+        new NavIsolateMenuElement(_isolate, _events, queue: _r.queue).element,
+        new NavClassMenuElement(_isolate, _cls, queue: _r.queue).element,
+        (new NavRefreshElement(
+                label: 'Refresh Allocation Profile', queue: _r.queue)
+              ..onRefresh.listen((e) {
+                e.element.disabled = true;
+                _loadProfile = true;
+                _r.dirty();
+              }))
+            .element,
+        (new NavRefreshElement(queue: _r.queue)
+              ..onRefresh.listen((e) {
+                e.element.disabled = true;
+                _common = null;
+                _classInstances = null;
+                _fieldsExpanded = null;
+                _functionsExpanded = null;
+                _refresh();
+              }))
+            .element,
+        new NavNotifyElement(_notifications, queue: _r.queue).element
       ]),
       new DivElement()
         ..classes = ['content-centered-big']
         ..children = <Element>[
           new HeadingElement.h2()..text = '$header class ${_cls.name}',
           new HRElement(),
-          _common,
+          _common.element,
           new BRElement(),
           new DivElement()
             ..classes = ['memberList']
@@ -223,10 +225,11 @@
                 ? const []
                 : [
                     new HRElement(),
-                    new ErrorRefElement(_cls.error, queue: _r.queue)
+                    new ErrorRefElement(_cls.error, queue: _r.queue).element
                   ],
           new HRElement(),
-          new EvalBoxElement(_isolate, _cls, _objects, _eval, queue: _r.queue),
+          new EvalBoxElement(_isolate, _cls, _objects, _eval, queue: _r.queue)
+              .element,
           new HRElement(),
           new HeadingElement.h2()..text = 'Fields & Functions',
           new DivElement()
@@ -235,7 +238,8 @@
           new HRElement(),
           new HeadingElement.h2()..text = 'Instances',
           new DivElement()
-            ..children = _cls.hasAllocations ? [_classInstances] : const [],
+            ..children =
+                _cls.hasAllocations ? [_classInstances.element] : const [],
           new HRElement(),
           new HeadingElement.h2()..text = 'Allocations',
           new DivElement()
@@ -273,21 +277,23 @@
             ..children = _loadProfile
                 ? [
                     new ClassAllocationProfileElement(
-                        _vm, _isolate, _cls, _profiles,
-                        queue: _r.queue)
+                            _vm, _isolate, _cls, _profiles,
+                            queue: _r.queue)
+                        .element
                   ]
                 : const [],
           new DivElement()
             ..children = _cls.location != null
                 ? [
                     new HRElement(),
-                    new SourceInsetElement(
-                        _isolate, _cls.location, _scripts, _objects, _events,
-                        queue: _r.queue)
+                    new SourceInsetElement(_isolate, _cls.location, _scripts,
+                            _objects, _events,
+                            queue: _r.queue)
+                        .element
                   ]
                 : const [],
           new HRElement(),
-          new ViewFooterElement(queue: _r.queue)
+          new ViewFooterElement(queue: _r.queue).element
         ]
     ];
   }
@@ -308,6 +314,7 @@
             ..classes = ['memberValue']
             ..children = <Element>[
               new LibraryRefElement(_isolate, _cls.library, queue: _r.queue)
+                  .element
             ]
         ]);
     }
@@ -322,7 +329,8 @@
             ..classes = ['memberValue']
             ..children = <Element>[
               new SourceLinkElement(_isolate, _cls.location, _scripts,
-                  queue: _r.queue)
+                      queue: _r.queue)
+                  .element
             ]
         ]);
     }
@@ -337,6 +345,7 @@
             ..classes = ['memberValue']
             ..children = <Element>[
               new ClassRefElement(_isolate, _cls.superclass, queue: _r.queue)
+                  .element
             ]
         ]);
     }
@@ -351,7 +360,8 @@
             ..classes = ['memberValue']
             ..children = <Element>[
               new InstanceRefElement(_isolate, _cls.superType, _objects,
-                  queue: _r.queue)
+                      queue: _r.queue)
+                  .element
             ]
         ]);
     }
@@ -366,7 +376,8 @@
             ..classes = ['memberValue']
             ..children = <Element>[
               new InstanceRefElement(_isolate, _cls.mixin, _objects,
-                  queue: _r.queue)
+                      queue: _r.queue)
+                  .element
             ]
         ]);
     }
@@ -381,7 +392,8 @@
             ..classes = ['memberValue']
             ..children = (_cls.subclasses
                 .expand((subcls) => <Element>[
-                      new ClassRefElement(_isolate, subcls, queue: _r.queue),
+                      new ClassRefElement(_isolate, subcls, queue: _r.queue)
+                          .element,
                       new SpanElement()..text = ', '
                     ])
                 .toList()
@@ -403,7 +415,8 @@
             ..children = (_cls.interfaces
                 .expand((interf) => <Element>[
                       new InstanceRefElement(_isolate, interf, _objects,
-                          queue: _r.queue),
+                              queue: _r.queue)
+                          .element,
                       new SpanElement()..text = ', '
                     ])
                 .toList()
@@ -439,32 +452,36 @@
           new DivElement()
             ..classes = ['memberValue']
             ..children = <Element>[
-              new CurlyBlockElement(expanded: _fieldsExpanded)
-                ..onToggle.listen((e) => _fieldsExpanded = e.control.expanded)
-                ..content = <Element>[
-                  new DivElement()
-                    ..classes = ['memberList']
-                    ..children = (fields
-                        .map<Element>((f) => new DivElement()
-                          ..classes = ['memberItem']
-                          ..children = <Element>[
-                            new DivElement()
-                              ..classes = ['memberName']
+              (new CurlyBlockElement(expanded: _fieldsExpanded)
+                    ..onToggle
+                        .listen((e) => _fieldsExpanded = e.control.expanded)
+                    ..content = <Element>[
+                      new DivElement()
+                        ..classes = ['memberList']
+                        ..children = (fields
+                            .map<Element>((f) => new DivElement()
+                              ..classes = ['memberItem']
                               ..children = <Element>[
-                                new FieldRefElement(_isolate, f, _objects,
-                                    queue: _r.queue)
-                              ],
-                            new DivElement()
-                              ..classes = ['memberValue']
-                              ..children = f.staticValue == null
-                                  ? const []
-                                  : [
-                                      anyRef(_isolate, f.staticValue, _objects,
-                                          queue: _r.queue)
-                                    ]
-                          ])
-                        .toList())
-                ]
+                                new DivElement()
+                                  ..classes = ['memberName']
+                                  ..children = <Element>[
+                                    new FieldRefElement(_isolate, f, _objects,
+                                            queue: _r.queue)
+                                        .element
+                                  ],
+                                new DivElement()
+                                  ..classes = ['memberValue']
+                                  ..children = f.staticValue == null
+                                      ? const []
+                                      : [
+                                          anyRef(
+                                              _isolate, f.staticValue, _objects,
+                                              queue: _r.queue)
+                                        ]
+                              ])
+                            .toList())
+                    ])
+                  .element
             ]
         ]);
     }
@@ -481,16 +498,18 @@
           new DivElement()
             ..classes = ['memberValue']
             ..children = <Element>[
-              new CurlyBlockElement(expanded: _functionsExpanded)
-                ..onToggle
-                    .listen((e) => _functionsExpanded = e.control.expanded)
-                ..content = (functions
-                    .map<Element>((f) => new DivElement()
-                      ..classes = ['indent']
-                      ..children = <Element>[
-                        new FunctionRefElement(_isolate, f, queue: _r.queue)
-                      ])
-                    .toList())
+              (new CurlyBlockElement(expanded: _functionsExpanded)
+                    ..onToggle
+                        .listen((e) => _functionsExpanded = e.control.expanded)
+                    ..content = (functions
+                        .map<Element>((f) => new DivElement()
+                          ..classes = ['indent']
+                          ..children = <Element>[
+                            new FunctionRefElement(_isolate, f, queue: _r.queue)
+                                .element
+                          ])
+                        .toList()))
+                  .element
             ]
         ]);
     }
diff --git a/runtime/observatory/lib/src/elements/code_ref.dart b/runtime/observatory/lib/src/elements/code_ref.dart
index fc35ef8..f6c7f03 100644
--- a/runtime/observatory/lib/src/elements/code_ref.dart
+++ b/runtime/observatory/lib/src/elements/code_ref.dart
@@ -12,7 +12,7 @@
 import 'package:observatory/src/elements/helpers/tag.dart';
 import 'package:observatory/src/elements/helpers/uris.dart';
 
-class CodeRefElement extends HtmlElement implements Renderable {
+class CodeRefElement extends CustomElement implements Renderable {
   static const tag = const Tag<CodeRefElement>('code-ref');
 
   RenderingScheduler<CodeRefElement> _r;
@@ -28,14 +28,14 @@
   factory CodeRefElement(M.IsolateRef isolate, M.CodeRef code,
       {RenderingQueue queue}) {
     assert(code != null);
-    CodeRefElement e = document.createElement(tag.name);
+    CodeRefElement e = new CodeRefElement.created();
     e._r = new RenderingScheduler<CodeRefElement>(e, queue: queue);
     e._isolate = isolate;
     e._code = code;
     return e;
   }
 
-  CodeRefElement.created() : super.created();
+  CodeRefElement.created() : super.created(tag);
 
   @override
   void attached() {
diff --git a/runtime/observatory/lib/src/elements/code_view.dart b/runtime/observatory/lib/src/elements/code_view.dart
index b943be5..c5061ad 100644
--- a/runtime/observatory/lib/src/elements/code_view.dart
+++ b/runtime/observatory/lib/src/elements/code_view.dart
@@ -36,7 +36,7 @@
   InlineTable(columns) : super(columns);
 }
 
-class CodeViewElement extends HtmlElement implements Renderable {
+class CodeViewElement extends CustomElement implements Renderable {
   static const tag =
       const Tag<CodeViewElement>('code-view', dependencies: const [
     CurlyBlockElement.tag,
@@ -97,7 +97,7 @@
     assert(reachableSizes != null);
     assert(references != null);
     assert(retainingPaths != null);
-    CodeViewElement e = document.createElement(tag.name);
+    CodeViewElement e = new CodeViewElement.created();
     e._r = new RenderingScheduler<CodeViewElement>(e, queue: queue);
     e._vm = vm;
     e._isolate = isolate;
@@ -112,7 +112,7 @@
     return e;
   }
 
-  CodeViewElement.created() : super.created() {
+  CodeViewElement.created() : super.created(tag) {
     var columns = [
       new SortedTableColumn('Address'),
       new SortedTableColumn('Inclusive'),
@@ -200,21 +200,23 @@
     final S.Code code = _code as S.Code;
     children = <Element>[
       navBar(<Element>[
-        new NavTopMenuElement(queue: _r.queue),
-        new NavVMMenuElement(_vm, _events, queue: _r.queue),
-        new NavIsolateMenuElement(_isolate, _events, queue: _r.queue),
+        new NavTopMenuElement(queue: _r.queue).element,
+        new NavVMMenuElement(_vm, _events, queue: _r.queue).element,
+        new NavIsolateMenuElement(_isolate, _events, queue: _r.queue).element,
         navMenu(_code.name),
-        new NavRefreshElement(queue: _r.queue)
-          ..onRefresh.listen((e) async {
-            e.element.disabled = true;
-            _refresh();
-          }),
-        new NavRefreshElement(label: 'refresh ticks', queue: _r.queue)
-          ..onRefresh.listen((e) async {
-            e.element.disabled = true;
-            _refreshTicks();
-          }),
-        new NavNotifyElement(_notifications, queue: _r.queue)
+        (new NavRefreshElement(queue: _r.queue)
+              ..onRefresh.listen((e) async {
+                e.element.disabled = true;
+                _refresh();
+              }))
+            .element,
+        (new NavRefreshElement(label: 'refresh ticks', queue: _r.queue)
+              ..onRefresh.listen((e) async {
+                e.element.disabled = true;
+                _refreshTicks();
+              }))
+            .element,
+        new NavNotifyElement(_notifications, queue: _r.queue).element
       ]),
       new DivElement()
         ..classes = ['content-centered-big']
@@ -225,8 +227,9 @@
                 : 'Code for ${_code.name}',
           new HRElement(),
           new ObjectCommonElement(_isolate, _code, _retainedSizes,
-              _reachableSizes, _references, _retainingPaths, _objects,
-              queue: _r.queue),
+                  _reachableSizes, _references, _retainingPaths, _objects,
+                  queue: _r.queue)
+              .element,
           new BRElement(),
           new DivElement()
             ..classes = ['memberList']
@@ -263,7 +266,8 @@
                     ..classes = ['memberValue']
                     ..children = <Element>[
                       new FunctionRefElement(_isolate, _code.function,
-                          queue: _r.queue)
+                              queue: _r.queue)
+                          .element
                     ]
                 ],
               new DivElement()
@@ -300,7 +304,8 @@
                     ..classes = ['memberValue']
                     ..children = <Element>[
                       new ObjectPoolRefElement(_isolate, _code.objectPool,
-                          queue: _r.queue)
+                              queue: _r.queue)
+                          .element
                     ]
                 ],
               new DivElement()
@@ -315,14 +320,16 @@
                         new DivElement()
                           ..classes = ['memberValue']
                           ..children = <Element>[
-                            new CurlyBlockElement(
-                                expanded: inlinedFunctions.length < 8,
-                                queue: _r.queue)
-                              ..content = inlinedFunctions
-                                  .map<Element>((f) => new FunctionRefElement(
-                                      _isolate, f,
-                                      queue: _r.queue))
-                                  .toList()
+                            (new CurlyBlockElement(
+                                    expanded: inlinedFunctions.length < 8,
+                                    queue: _r.queue)
+                                  ..content = inlinedFunctions
+                                      .map<Element>((f) =>
+                                          new FunctionRefElement(_isolate, f,
+                                                  queue: _r.queue)
+                                              .element)
+                                      .toList())
+                                .element
                           ]
                       ]
             ],
@@ -593,7 +600,7 @@
     functionsCell.children.clear();
     for (var func in functions) {
       functionsCell.children
-          .add(new FunctionRefElement(_isolate, func, queue: _r.queue));
+          .add(new FunctionRefElement(_isolate, func, queue: _r.queue).element);
       var gap = new SpanElement();
       gap.style.minWidth = '1em';
       gap.text = ' ';
diff --git a/runtime/observatory/lib/src/elements/containers/search_bar.dart b/runtime/observatory/lib/src/elements/containers/search_bar.dart
index c07c495..593956a 100644
--- a/runtime/observatory/lib/src/elements/containers/search_bar.dart
+++ b/runtime/observatory/lib/src/elements/containers/search_bar.dart
@@ -16,7 +16,7 @@
 
 typedef Iterable<dynamic> SearchBarSearchCallback(Pattern pattern);
 
-class SearchBarElement extends HtmlElement implements Renderable {
+class SearchBarElement extends CustomElement implements Renderable {
   static const tag = const Tag<SearchBarElement>('search-bar');
 
   RenderingScheduler<SearchBarElement> _r;
@@ -58,7 +58,7 @@
       {bool isOpen: false, Element workspace, RenderingQueue queue}) {
     assert(search != null);
     assert(isOpen != null);
-    SearchBarElement e = document.createElement(tag.name);
+    SearchBarElement e = new SearchBarElement.created();
     e._r = new RenderingScheduler<SearchBarElement>(e, queue: queue);
     e._search = search;
     e._isOpen = isOpen;
@@ -66,7 +66,7 @@
     return e;
   }
 
-  SearchBarElement.created() : super.created();
+  SearchBarElement.created() : super.created(tag);
 
   @override
   attached() {
diff --git a/runtime/observatory/lib/src/elements/containers/virtual_collection.dart b/runtime/observatory/lib/src/elements/containers/virtual_collection.dart
index b1a9169..f921c44 100644
--- a/runtime/observatory/lib/src/elements/containers/virtual_collection.dart
+++ b/runtime/observatory/lib/src/elements/containers/virtual_collection.dart
@@ -15,7 +15,7 @@
     HtmlElement el, dynamic item, int index);
 typedef bool VirtualCollectionSearchCallback(Pattern pattern, dynamic item);
 
-class VirtualCollectionElement extends HtmlElement implements Renderable {
+class VirtualCollectionElement extends CustomElement implements Renderable {
   static const tag = const Tag<VirtualCollectionElement>('virtual-collection',
       dependencies: const [SearchBarElement.tag]);
 
@@ -53,7 +53,7 @@
     assert(create != null);
     assert(update != null);
     assert(items != null);
-    VirtualCollectionElement e = document.createElement(tag.name);
+    VirtualCollectionElement e = new VirtualCollectionElement.created();
     e._r = new RenderingScheduler<VirtualCollectionElement>(e, queue: queue);
     e._create = create;
     e._createHeader = createHeader;
@@ -63,7 +63,7 @@
     return e;
   }
 
-  VirtualCollectionElement.created() : super.created();
+  VirtualCollectionElement.created() : super.created(tag);
 
   @override
   attached() {
@@ -91,13 +91,23 @@
   final DivElement _spacer = new DivElement()..classes = ['spacer'];
   final DivElement _buffer = new DivElement()..classes = ['buffer'];
 
+  static int safeFloor(double x) {
+    if (x.isNaN) return 0;
+    return x.floor();
+  }
+
+  static int safeCeil(double x) {
+    if (x.isNaN) return 0;
+    return x.ceil();
+  }
+
   dynamic getItemFromElement(HtmlElement element) {
     final el_index = _buffer.children.indexOf(element);
     if (el_index < 0) {
       return null;
     }
     final item_index =
-        _top + el_index - (_buffer.children.length * _inverse_preload).floor();
+        _top + el_index - safeFloor(_buffer.children.length * _inverse_preload);
     if (0 <= item_index && item_index < items.length) {
       return _items[item_index];
     }
@@ -141,7 +151,7 @@
               ..onSearchResultSelected.listen((e) {
                 takeIntoView(e.item);
               });
-        children.insert(0, _searcher);
+        children.insert(0, _searcher.element);
       }
       if (_createHeader != null) {
         _header = new DivElement()
@@ -164,15 +174,15 @@
         final minScrollTop = _itemHeight * (index + 1) - _height;
         final maxScrollTop = _itemHeight * index;
         _viewport.scrollTop =
-            ((maxScrollTop - minScrollTop) / 2 + minScrollTop).floor();
+            safeFloor((maxScrollTop - minScrollTop) / 2 + minScrollTop);
       }
       _takeIntoView = null;
     }
 
-    final top = (_viewport.scrollTop / _itemHeight).floor();
+    final top = safeFloor(_viewport.scrollTop / _itemHeight);
 
-    _spacer.style.height = '${_itemHeight*(_items.length)}px';
-    final tail_length = (_height / _itemHeight / _preload).ceil();
+    _spacer.style.height = '${_itemHeight * (_items.length)}px';
+    final tail_length = safeCeil(_height / _itemHeight / _preload);
     final length = tail_length * 2 + tail_length * _preload;
 
     if (_buffer.children.length < length) {
@@ -185,7 +195,7 @@
     }
 
     if ((_top == null) || ((top - _top).abs() >= tail_length)) {
-      _buffer.style.top = '${_itemHeight*(top-tail_length)}px';
+      _buffer.style.top = '${_itemHeight * (top - tail_length)}px';
       int i = top - tail_length;
       for (final HtmlElement e in _buffer.children) {
         if (0 <= i && i < _items.length) {
diff --git a/runtime/observatory/lib/src/elements/containers/virtual_tree.dart b/runtime/observatory/lib/src/elements/containers/virtual_tree.dart
index 0c9b38b..09690d6 100644
--- a/runtime/observatory/lib/src/elements/containers/virtual_tree.dart
+++ b/runtime/observatory/lib/src/elements/containers/virtual_tree.dart
@@ -26,7 +26,7 @@
   }
 }
 
-class VirtualTreeElement extends HtmlElement implements Renderable {
+class VirtualTreeElement extends CustomElement implements Renderable {
   static const tag = const Tag<VirtualTreeElement>('virtual-tree',
       dependencies: const [VirtualCollectionElement.tag]);
 
@@ -56,7 +56,7 @@
     assert(update != null);
     assert(children != null);
     assert(items != null);
-    VirtualTreeElement e = document.createElement(tag.name);
+    VirtualTreeElement e = new VirtualTreeElement.created();
     e._r = new RenderingScheduler<VirtualTreeElement>(e, queue: queue);
     e._children = children;
     e._collection = new VirtualCollectionElement(() {
@@ -82,7 +82,7 @@
     return e;
   }
 
-  VirtualTreeElement.created() : super.created();
+  VirtualTreeElement.created() : super.created(tag);
 
   bool isExpanded(item) {
     return _expanded.contains(item);
@@ -151,7 +151,7 @@
 
   void render() {
     if (children.length == 0) {
-      children = <Element>[_collection];
+      children = <Element>[_collection.element];
     }
 
     final items = [];
diff --git a/runtime/observatory/lib/src/elements/context_ref.dart b/runtime/observatory/lib/src/elements/context_ref.dart
index c4c06b2..1f92a48 100644
--- a/runtime/observatory/lib/src/elements/context_ref.dart
+++ b/runtime/observatory/lib/src/elements/context_ref.dart
@@ -11,7 +11,7 @@
 import 'package:observatory/src/elements/helpers/tag.dart';
 import 'package:observatory/src/elements/helpers/uris.dart';
 
-class ContextRefElement extends HtmlElement implements Renderable {
+class ContextRefElement extends CustomElement implements Renderable {
   static const tag = const Tag<ContextRefElement>('context-ref',
       dependencies: const [CurlyBlockElement.tag]);
 
@@ -35,7 +35,7 @@
     assert(isolate != null);
     assert(context != null);
     assert(objects != null);
-    ContextRefElement e = document.createElement(tag.name);
+    ContextRefElement e = new ContextRefElement.created();
     e._r = new RenderingScheduler<ContextRefElement>(e, queue: queue);
     e._isolate = isolate;
     e._context = context;
@@ -44,7 +44,7 @@
     return e;
   }
 
-  ContextRefElement.created() : super.created();
+  ContextRefElement.created() : super.created(tag);
 
   @override
   void attached() {
@@ -77,20 +77,21 @@
     if (_expandable) {
       children.addAll([
         new SpanElement()..text = ' ',
-        new CurlyBlockElement(expanded: _expanded, queue: _r.queue)
-          ..content = <Element>[
-            new DivElement()
-              ..classes = ['indent']
-              ..children = _createValue()
-          ]
-          ..onToggle.listen((e) async {
-            _expanded = e.control.expanded;
-            if (_expanded) {
-              e.control.disabled = true;
-              await _refresh();
-              e.control.disabled = false;
-            }
-          })
+        (new CurlyBlockElement(expanded: _expanded, queue: _r.queue)
+              ..content = <Element>[
+                new DivElement()
+                  ..classes = ['indent']
+                  ..children = _createValue()
+              ]
+              ..onToggle.listen((e) async {
+                _expanded = e.control.expanded;
+                if (_expanded) {
+                  e.control.disabled = true;
+                  await _refresh();
+                  e.control.disabled = false;
+                }
+              }))
+            .element
       ]);
     }
     this.children = children;
@@ -112,8 +113,9 @@
             ..classes = ['memberName']
             ..children = <Element>[
               new ContextRefElement(
-                  _isolate, _loadedContext.parentContext, _objects,
-                  queue: _r.queue)
+                      _isolate, _loadedContext.parentContext, _objects,
+                      queue: _r.queue)
+                  .element
             ]
         ]);
     }
diff --git a/runtime/observatory/lib/src/elements/context_view.dart b/runtime/observatory/lib/src/elements/context_view.dart
index 15dd1a6..b85b315 100644
--- a/runtime/observatory/lib/src/elements/context_view.dart
+++ b/runtime/observatory/lib/src/elements/context_view.dart
@@ -21,7 +21,7 @@
 import 'package:observatory/src/elements/object_common.dart';
 import 'package:observatory/src/elements/view_footer.dart';
 
-class ContextViewElement extends HtmlElement implements Renderable {
+class ContextViewElement extends CustomElement implements Renderable {
   static const tag =
       const Tag<ContextViewElement>('context-view', dependencies: const [
     ContextRefElement.tag,
@@ -81,7 +81,7 @@
     assert(references != null);
     assert(retainingPaths != null);
     assert(objects != null);
-    ContextViewElement e = document.createElement(tag.name);
+    ContextViewElement e = new ContextViewElement.created();
     e._r = new RenderingScheduler<ContextViewElement>(e, queue: queue);
     e._vm = vm;
     e._isolate = isolate;
@@ -97,7 +97,7 @@
     return e;
   }
 
-  ContextViewElement.created() : super.created();
+  ContextViewElement.created() : super.created(tag);
 
   @override
   attached() {
@@ -115,18 +115,20 @@
   void render() {
     var content = <Element>[
       navBar(<Element>[
-        new NavTopMenuElement(queue: _r.queue),
-        new NavVMMenuElement(_vm, _events, queue: _r.queue),
-        new NavIsolateMenuElement(_isolate, _events, queue: _r.queue),
-        new NavClassMenuElement(_isolate, _context.clazz, queue: _r.queue),
+        new NavTopMenuElement(queue: _r.queue).element,
+        new NavVMMenuElement(_vm, _events, queue: _r.queue).element,
+        new NavIsolateMenuElement(_isolate, _events, queue: _r.queue).element,
+        new NavClassMenuElement(_isolate, _context.clazz, queue: _r.queue)
+            .element,
         navMenu('instance'),
-        new NavRefreshElement(queue: _r.queue)
-          ..onRefresh.listen((e) async {
-            e.element.disabled = true;
-            _context = await _contexts.get(_isolate, _context.id);
-            _r.dirty();
-          }),
-        new NavNotifyElement(_notifications, queue: _r.queue)
+        (new NavRefreshElement(queue: _r.queue)
+              ..onRefresh.listen((e) async {
+                e.element.disabled = true;
+                _context = await _contexts.get(_isolate, _context.id);
+                _r.dirty();
+              }))
+            .element,
+        new NavNotifyElement(_notifications, queue: _r.queue).element
       ]),
       new DivElement()
         ..classes = ['content-centered-big']
@@ -134,8 +136,9 @@
           new HeadingElement.h2()..text = 'Context',
           new HRElement(),
           new ObjectCommonElement(_isolate, _context, _retainedSizes,
-              _reachableSizes, _references, _retainingPaths, _objects,
-              queue: _r.queue)
+                  _reachableSizes, _references, _retainingPaths, _objects,
+                  queue: _r.queue)
+              .element
         ]
     ];
     if (_context.parentContext != null) {
@@ -157,8 +160,9 @@
                       ..classes = ['memberName']
                       ..children = <Element>[
                         new ContextRefElement(
-                            _isolate, _context.parentContext, _objects,
-                            queue: _r.queue)
+                                _isolate, _context.parentContext, _objects,
+                                queue: _r.queue)
+                            .element
                       ]
                   ]
               ]
@@ -173,32 +177,33 @@
           ..classes = ['content-centered-big']
           ..children = <Element>[
             new SpanElement()..text = 'Variables ',
-            new CurlyBlockElement(expanded: true, queue: _r.queue)
-              ..content = <Element>[
-                new DivElement()
-                  ..classes = ['memberList']
-                  ..children = _context.variables
-                      .map<Element>((variable) => new DivElement()
-                        ..classes = ['memberItem']
-                        ..children = <Element>[
-                          new DivElement()
-                            ..classes = ['memberName']
-                            ..text = '[ ${++index} ]',
-                          new DivElement()
-                            ..classes = ['memberName']
+            (new CurlyBlockElement(expanded: true, queue: _r.queue)
+                  ..content = <Element>[
+                    new DivElement()
+                      ..classes = ['memberList']
+                      ..children = _context.variables
+                          .map<Element>((variable) => new DivElement()
+                            ..classes = ['memberItem']
                             ..children = <Element>[
-                              anyRef(_isolate, variable.value, _objects,
-                                  queue: _r.queue)
-                            ]
-                        ])
-                      .toList()
-              ]
+                              new DivElement()
+                                ..classes = ['memberName']
+                                ..text = '[ ${++index} ]',
+                              new DivElement()
+                                ..classes = ['memberName']
+                                ..children = <Element>[
+                                  anyRef(_isolate, variable.value, _objects,
+                                      queue: _r.queue)
+                                ]
+                            ])
+                          .toList()
+                  ])
+                .element
           ]
       ]);
     }
     content.add(new DivElement()
       ..classes = ['content-centered-big']
-      ..children = <Element>[new ViewFooterElement(queue: _r.queue)]);
+      ..children = <Element>[new ViewFooterElement(queue: _r.queue).element]);
     children = content;
   }
 }
diff --git a/runtime/observatory/lib/src/elements/cpu_profile.dart b/runtime/observatory/lib/src/elements/cpu_profile.dart
index 4c8bc31..320a7603 100644
--- a/runtime/observatory/lib/src/elements/cpu_profile.dart
+++ b/runtime/observatory/lib/src/elements/cpu_profile.dart
@@ -21,7 +21,7 @@
 import 'package:observatory/src/elements/sample_buffer_control.dart';
 import 'package:observatory/src/elements/stack_trace_tree_config.dart';
 
-class CpuProfileElement extends HtmlElement implements Renderable {
+class CpuProfileElement extends CustomElement implements Renderable {
   static const tag =
       const Tag<CpuProfileElement>('cpu-profile', dependencies: const [
     NavTopMenuElement.tag,
@@ -67,7 +67,7 @@
     assert(events != null);
     assert(notifications != null);
     assert(profiles != null);
-    CpuProfileElement e = document.createElement(tag.name);
+    CpuProfileElement e = new CpuProfileElement.created();
     e._r = new RenderingScheduler<CpuProfileElement>(e, queue: queue);
     e._vm = vm;
     e._isolate = isolate;
@@ -77,7 +77,7 @@
     return e;
   }
 
-  CpuProfileElement.created() : super.created();
+  CpuProfileElement.created() : super.created(tag);
 
   @override
   attached() {
@@ -96,54 +96,59 @@
   void render() {
     var content = <Element>[
       navBar(<Element>[
-        new NavTopMenuElement(queue: _r.queue),
-        new NavVMMenuElement(_vm, _events, queue: _r.queue),
-        new NavIsolateMenuElement(_isolate, _events, queue: _r.queue),
+        new NavTopMenuElement(queue: _r.queue).element,
+        new NavVMMenuElement(_vm, _events, queue: _r.queue).element,
+        new NavIsolateMenuElement(_isolate, _events, queue: _r.queue).element,
         navMenu('cpu profile', link: Uris.cpuProfiler(_isolate)),
-        new NavRefreshElement(queue: _r.queue)..onRefresh.listen(_refresh),
-        new NavRefreshElement(label: 'Clear', queue: _r.queue)
-          ..onRefresh.listen(_clearCpuProfile),
-        new NavNotifyElement(_notifications, queue: _r.queue)
+        (new NavRefreshElement(queue: _r.queue)..onRefresh.listen(_refresh))
+            .element,
+        (new NavRefreshElement(label: 'Clear', queue: _r.queue)
+              ..onRefresh.listen(_clearCpuProfile))
+            .element,
+        new NavNotifyElement(_notifications, queue: _r.queue).element
       ]),
     ];
     if (_progress == null) {
       children = content;
       return;
     }
-    content.add(new SampleBufferControlElement(_vm, _progress, _progressStream,
-        selectedTag: _tag, queue: _r.queue)
-      ..onTagChange.listen((e) {
-        _tag = e.element.selectedTag;
-        _request(forceFetch: true);
-      }));
+    content.add((new SampleBufferControlElement(_vm, _progress, _progressStream,
+            selectedTag: _tag, queue: _r.queue)
+          ..onTagChange.listen((e) {
+            _tag = e.element.selectedTag;
+            _request(forceFetch: true);
+          }))
+        .element);
     if (_progress.status == M.SampleProfileLoadingStatus.loaded) {
       CpuProfileVirtualTreeElement tree;
       content.addAll([
         new BRElement(),
-        new StackTraceTreeConfigElement(
-            mode: _mode,
-            direction: _direction,
-            filter: _filter,
-            queue: _r.queue)
-          ..onModeChange.listen((e) {
-            _mode = tree.mode = e.element.mode;
-          })
-          ..onFilterChange.listen((e) {
-            _filter = e.element.filter.trim();
-            tree.filters = _filter.isNotEmpty
-                ? [
-                    (node) {
-                      return node.name.contains(_filter);
-                    }
-                  ]
-                : const [];
-          })
-          ..onDirectionChange.listen((e) {
-            _direction = tree.direction = e.element.direction;
-          }),
+        (new StackTraceTreeConfigElement(
+                mode: _mode,
+                direction: _direction,
+                filter: _filter,
+                queue: _r.queue)
+              ..onModeChange.listen((e) {
+                _mode = tree.mode = e.element.mode;
+              })
+              ..onFilterChange.listen((e) {
+                _filter = e.element.filter.trim();
+                tree.filters = _filter.isNotEmpty
+                    ? [
+                        (node) {
+                          return node.name.contains(_filter);
+                        }
+                      ]
+                    : const [];
+              })
+              ..onDirectionChange.listen((e) {
+                _direction = tree.direction = e.element.direction;
+              }))
+            .element,
         new BRElement(),
-        tree = new CpuProfileVirtualTreeElement(_isolate, _progress.profile,
-            queue: _r.queue)
+        (tree = new CpuProfileVirtualTreeElement(_isolate, _progress.profile,
+                queue: _r.queue))
+            .element
       ]);
     }
     children = content;
diff --git a/runtime/observatory/lib/src/elements/cpu_profile/virtual_tree.dart b/runtime/observatory/lib/src/elements/cpu_profile/virtual_tree.dart
index 3ee7325..77de515 100644
--- a/runtime/observatory/lib/src/elements/cpu_profile/virtual_tree.dart
+++ b/runtime/observatory/lib/src/elements/cpu_profile/virtual_tree.dart
@@ -18,7 +18,7 @@
 export 'package:observatory/src/elements/stack_trace_tree_config.dart'
     show ProfileTreeMode;
 
-class CpuProfileVirtualTreeElement extends HtmlElement implements Renderable {
+class CpuProfileVirtualTreeElement extends CustomElement implements Renderable {
   static const tag =
       const Tag<CpuProfileVirtualTreeElement>('cpu-profile-virtual-tree');
 
@@ -57,8 +57,9 @@
     assert(profile != null);
     assert(mode != null);
     assert(direction != null);
-    CpuProfileVirtualTreeElement e = document.createElement(tag.name);
-    e._r = new RenderingScheduler<CpuProfileVirtualTreeElement>(e, queue: queue);
+    CpuProfileVirtualTreeElement e = new CpuProfileVirtualTreeElement.created();
+    e._r =
+        new RenderingScheduler<CpuProfileVirtualTreeElement>(e, queue: queue);
     e._isolate = owner;
     e._profile = profile;
     e._mode = mode;
@@ -67,7 +68,7 @@
     return e;
   }
 
-  CpuProfileVirtualTreeElement.created() : super.created();
+  CpuProfileVirtualTreeElement.created() : super.created(tag);
 
   @override
   attached() {
@@ -143,7 +144,7 @@
     } else if (tree.root.children.length == 1) {
       _tree.expand(tree.root.children.first, autoExpandSingleChildNodes: true);
     }
-    children = <Element>[_tree];
+    children = <Element>[_tree.element];
   }
 
   static HtmlElement _createCpuRow(toggle) {
@@ -196,13 +197,12 @@
   static const String _expandedIcon = 'â–¼';
   static const String _collapsedIcon = 'â–º';
 
-  void _updateCpuFunctionRow(
-      HtmlElement element, itemDynamic, int depth) {
+  void _updateCpuFunctionRow(HtmlElement element, itemDynamic, int depth) {
     M.FunctionCallTreeNode item = itemDynamic;
-    element.children[0].text = Utils
-        .formatPercentNormalized(item.profileFunction.normalizedInclusiveTicks);
-    element.children[1].text = Utils
-        .formatPercentNormalized(item.profileFunction.normalizedExclusiveTicks);
+    element.children[0].text = Utils.formatPercentNormalized(
+        item.profileFunction.normalizedInclusiveTicks);
+    element.children[1].text = Utils.formatPercentNormalized(
+        item.profileFunction.normalizedExclusiveTicks);
     _updateLines(element.children[2].children, depth);
     if (item.children.isNotEmpty) {
       element.children[3].text =
@@ -211,14 +211,14 @@
       element.children[3].text = '';
     }
     element.children[4].text = Utils.formatPercentNormalized(item.percentage);
-    element.children[5] = new FunctionRefElement(
-        _isolate, item.profileFunction.function,
-        queue: _r.queue)
-      ..classes = ['name'];
+    element.children[5] = (new FunctionRefElement(
+            _isolate, item.profileFunction.function,
+            queue: _r.queue)
+          ..classes = ['name'])
+        .element;
   }
 
-  void _updateMemoryFunctionRow(
-      HtmlElement element, itemDynamic, int depth) {
+  void _updateMemoryFunctionRow(HtmlElement element, itemDynamic, int depth) {
     M.FunctionCallTreeNode item = itemDynamic;
     element.children[0].text =
         Utils.formatSize(item.inclusiveNativeAllocations);
@@ -236,24 +236,26 @@
       element.children[3].text = '';
     }
     element.children[4].text = Utils.formatPercentNormalized(item.percentage);
-    element.children[5] = new FunctionRefElement(
-        null, item.profileFunction.function,
-        queue: _r.queue)
-      ..classes = ['name'];
+    element.children[5] = (new FunctionRefElement(
+            null, item.profileFunction.function,
+            queue: _r.queue)
+          ..classes = ['name'])
+        .element;
   }
 
   bool _searchFunction(Pattern pattern, itemDynamic) {
     M.FunctionCallTreeNode item = itemDynamic;
-    return M.getFunctionFullName(item.profileFunction.function).contains(pattern);
+    return M
+        .getFunctionFullName(item.profileFunction.function)
+        .contains(pattern);
   }
 
-  void _updateCpuCodeRow(
-      HtmlElement element, itemDynamic, int depth) {
+  void _updateCpuCodeRow(HtmlElement element, itemDynamic, int depth) {
     M.CodeCallTreeNode item = itemDynamic;
-    element.children[0].text = Utils
-        .formatPercentNormalized(item.profileCode.normalizedInclusiveTicks);
-    element.children[1].text = Utils
-        .formatPercentNormalized(item.profileCode.normalizedExclusiveTicks);
+    element.children[0].text = Utils.formatPercentNormalized(
+        item.profileCode.normalizedInclusiveTicks);
+    element.children[1].text = Utils.formatPercentNormalized(
+        item.profileCode.normalizedExclusiveTicks);
     _updateLines(element.children[2].children, depth);
     if (item.children.isNotEmpty) {
       element.children[3].text =
@@ -263,12 +265,12 @@
     }
     element.children[4].text = Utils.formatPercentNormalized(item.percentage);
     element.children[5] =
-        new CodeRefElement(_isolate, item.profileCode.code, queue: _r.queue)
-          ..classes = ['name'];
+        (new CodeRefElement(_isolate, item.profileCode.code, queue: _r.queue)
+              ..classes = ['name'])
+            .element;
   }
 
-  void _updateMemoryCodeRow(
-      HtmlElement element, itemDynamic, int depth) {
+  void _updateMemoryCodeRow(HtmlElement element, itemDynamic, int depth) {
     M.CodeCallTreeNode item = itemDynamic;
     element.children[0].text =
         Utils.formatSize(item.inclusiveNativeAllocations);
@@ -287,8 +289,9 @@
     }
     element.children[4].text = Utils.formatPercentNormalized(item.percentage);
     element.children[5] =
-        new CodeRefElement(null, item.profileCode.code, queue: _r.queue)
-          ..classes = ['name'];
+        (new CodeRefElement(null, item.profileCode.code, queue: _r.queue)
+              ..classes = ['name'])
+            .element;
   }
 
   bool _searchCode(Pattern pattern, itemDynamic) {
diff --git a/runtime/observatory/lib/src/elements/cpu_profile_table.dart b/runtime/observatory/lib/src/elements/cpu_profile_table.dart
index b1a9160..cd07545 100644
--- a/runtime/observatory/lib/src/elements/cpu_profile_table.dart
+++ b/runtime/observatory/lib/src/elements/cpu_profile_table.dart
@@ -29,7 +29,7 @@
 
 enum _SortingDirection { ascending, descending }
 
-class CpuProfileTableElement extends HtmlElement implements Renderable {
+class CpuProfileTableElement extends CustomElement implements Renderable {
   static const tag = const Tag<CpuProfileTableElement>('cpu-profile-table',
       dependencies: const [
         FunctionRefElement.tag,
@@ -84,7 +84,7 @@
     assert(events != null);
     assert(notifications != null);
     assert(profiles != null);
-    CpuProfileTableElement e = document.createElement(tag.name);
+    CpuProfileTableElement e = new CpuProfileTableElement.created();
     e._r = new RenderingScheduler<CpuProfileTableElement>(e, queue: queue);
     e._vm = vm;
     e._isolate = isolate;
@@ -94,7 +94,7 @@
     return e;
   }
 
-  CpuProfileTableElement.created() : super.created();
+  CpuProfileTableElement.created() : super.created(tag);
 
   @override
   attached() {
@@ -113,14 +113,16 @@
   void render() {
     var content = <Element>[
       navBar(<Element>[
-        new NavTopMenuElement(queue: _r.queue),
-        new NavVMMenuElement(_vm, _events, queue: _r.queue),
-        new NavIsolateMenuElement(_isolate, _events, queue: _r.queue),
+        new NavTopMenuElement(queue: _r.queue).element,
+        new NavVMMenuElement(_vm, _events, queue: _r.queue).element,
+        new NavIsolateMenuElement(_isolate, _events, queue: _r.queue).element,
         navMenu('cpu profile (table)'),
-        new NavRefreshElement(queue: _r.queue)..onRefresh.listen(_refresh),
-        new NavRefreshElement(label: 'Clear', queue: _r.queue)
-          ..onRefresh.listen(_clearCpuProfile),
-        new NavNotifyElement(_notifications, queue: _r.queue)
+        (new NavRefreshElement(queue: _r.queue)..onRefresh.listen(_refresh))
+            .element,
+        (new NavRefreshElement(label: 'Clear', queue: _r.queue)
+              ..onRefresh.listen(_clearCpuProfile))
+            .element,
+        new NavNotifyElement(_notifications, queue: _r.queue).element
       ]),
     ];
     if (_progress == null) {
@@ -128,7 +130,8 @@
       return;
     }
     content.add(new SampleBufferControlElement(_vm, _progress, _progressStream,
-        showTag: false, queue: _r.queue));
+            showTag: false, queue: _r.queue)
+        .element);
     if (_progress.status == M.SampleProfileLoadingStatus.loaded) {
       content.add(new BRElement());
       content.addAll(_createTables());
@@ -177,24 +180,25 @@
         ..children = <Element>[
           new DivElement()
             ..classes = ['profile-trees-all']
-            ..children = <Element>[_functions],
+            ..children = <Element>[_functions.element],
           new DivElement()
             ..classes = ['profile-trees-current']
             ..children = <Element>[
               new DivElement()
                 ..classes = ['profile-trees-caller']
-                ..children = <Element>[_callers],
+                ..children = <Element>[_callers.element],
               new DivElement()
                 ..classes = ['profile-trees-selected']
                 ..children = _selected == null
                     ? [new SpanElement()..text = 'No element selected']
                     : [
                         new FunctionRefElement(_isolate, _selected.function,
-                            queue: _r.queue)
+                                queue: _r.queue)
+                            .element
                       ],
               new DivElement()
                 ..classes = ['profile-trees-callee']
-                ..children = <Element>[_callees]
+                ..children = <Element>[_callees.element]
             ]
         ]
     ];
@@ -370,37 +374,39 @@
   List<Element> _createTree() {
     CpuProfileVirtualTreeElement tree;
     return [
-      new StackTraceTreeConfigElement(
-          showMode: false,
-          showDirection: false,
-          mode: ProfileTreeMode.function,
-          direction: M.ProfileTreeDirection.exclusive,
-          filter: _filter,
-          queue: _r.queue)
-        ..onFilterChange.listen((e) {
-          _filter = e.element.filter.trim();
-          tree.filters = _filter.isNotEmpty
-              ? [
-                  _filterTree,
-                  (node) {
-                    return node.name.contains(_filter);
-                  }
-                ]
-              : [_filterTree];
-        }),
+      (new StackTraceTreeConfigElement(
+              showMode: false,
+              showDirection: false,
+              mode: ProfileTreeMode.function,
+              direction: M.ProfileTreeDirection.exclusive,
+              filter: _filter,
+              queue: _r.queue)
+            ..onFilterChange.listen((e) {
+              _filter = e.element.filter.trim();
+              tree.filters = _filter.isNotEmpty
+                  ? [
+                      _filterTree,
+                      (node) {
+                        return node.name.contains(_filter);
+                      }
+                    ]
+                  : [_filterTree];
+            }))
+          .element,
       new BRElement(),
-      tree = new CpuProfileVirtualTreeElement(_isolate, _progress.profile,
-          mode: ProfileTreeMode.function,
-          direction: M.ProfileTreeDirection.exclusive,
-          queue: _r.queue)
-        ..filters = _filter.isNotEmpty
-            ? [
-                _filterTree,
-                (node) {
-                  return node.name.contains(_filter);
-                }
-              ]
-            : [_filterTree]
+      (tree = new CpuProfileVirtualTreeElement(_isolate, _progress.profile,
+              mode: ProfileTreeMode.function,
+              direction: M.ProfileTreeDirection.exclusive,
+              queue: _r.queue)
+            ..filters = _filter.isNotEmpty
+                ? [
+                    _filterTree,
+                    (node) {
+                      return node.name.contains(_filter);
+                    }
+                  ]
+                : [_filterTree])
+          .element
     ];
   }
 
diff --git a/runtime/observatory/lib/src/elements/css/shared.css b/runtime/observatory/lib/src/elements/css/shared.css
index 397de98..218cc7f 100644
--- a/runtime/observatory/lib/src/elements/css/shared.css
+++ b/runtime/observatory/lib/src/elements/css/shared.css
@@ -397,22 +397,22 @@
 
 /* allocation-profile */
 
-allocation-profile .heap-space {
+.allocation-profile .heap-space {
   display: inline-block;
   width: 50%;
 }
 
-allocation-profile .heap-space.right,
-allocation-profile .heap-space.right .memberList,
-allocation-profile .heap-space.right .legend * {
+.allocation-profile .heap-space.right,
+.allocation-profile .heap-space.right .memberList,
+.allocation-profile .heap-space.right .legend * {
   direction: rtl;
 }
 
-allocation-profile .compactable {
+.allocation-profile .compactable {
   position: relative;
 }
 
-allocation-profile .compact {
+.allocation-profile .compact {
   position: absolute;
   bottom: 20px;
   left: 50%;
@@ -420,45 +420,45 @@
   margin-left: -4em;
 }
 
-allocation-profile .heap-space.right * {
+.allocation-profile .heap-space.right * {
   direction: ltr;
   text-align: right;
 }
 
-allocation-profile div.chart {
+.allocation-profile div.chart {
   display: block;
   position: relative;
   height: 150px;
 }
-allocation-profile div.chart > div.host {
+.allocation-profile div.chart > div.host {
   display: inline-block;
   position: absolute;
   bottom: 0px;
   top: 0;
 }
-allocation-profile div.chart > div.legend {
+.allocation-profile div.chart > div.legend {
   position: absolute;
   width: 150px;
   top: 25px;
   bottom: 0;
   overflow-y: auto;
 }
-allocation-profile .heap-space.left div.host {
+.allocation-profile .heap-space.left div.host {
   left: 200px;
   width: 180px;
 }
-allocation-profile .heap-space.right div.host {
+.allocation-profile .heap-space.right div.host {
   right: 150px;
   width: 180px;
 }
-allocation-profile .heap-space.left div.legend {
+.allocation-profile .heap-space.left div.legend {
   left: 0;
 }
-allocation-profile .heap-space.right div.legend {
+.allocation-profile .heap-space.right div.legend {
   right: 0;
 }
 
-allocation-profile .collection {
+.allocation-profile .collection {
   position: absolute;
   bottom: 0;
   left: 0;
@@ -466,63 +466,63 @@
   top: 560px;
 }
 
-allocation-profile .collection.expanded {
+.allocation-profile .collection.expanded {
   top: 160px;
 }
 
-allocation-profile .container {
+.allocation-profile .container {
   padding-left: 5%;
   padding-right: 5%;
 }
 
-allocation-profile .collection-item {
+.allocation-profile .collection-item {
   background-color: #FFFFFF;
   box-sizing: border-box;
   line-height: 20px;
 }
 
-allocation-profile .collection-item:hover {
+.allocation-profile .collection-item:hover {
   background-color: #d2e7fe;
 }
 
-allocation-profile .header .collection-item:hover {
+.allocation-profile .header .collection-item:hover {
   background-color: #FFFFFF;
 }
 
-allocation-profile .header .collection-item:last-child {
+.allocation-profile .header .collection-item:last-child {
   margin-bottom: -3px;
   border-bottom: solid 1px #AAAAAA;
 }
 
-allocation-profile .header .collection-item span {
+.allocation-profile .header .collection-item span {
   font-weight: bolder;
 }
 
-allocation-profile .collection-item :nth-child(2n+2).group,
-allocation-profile .collection-item :nth-child(4n+3),
-allocation-profile .collection-item :nth-child(4n+4) {
+.allocation-profile .collection-item :nth-child(2n+2).group,
+.allocation-profile .collection-item :nth-child(4n+3),
+.allocation-profile .collection-item :nth-child(4n+4) {
   background-color: #EEEEEE;
 }
 
-allocation-profile .collection-item:hover :nth-child(2n+2).group,
-allocation-profile .collection-item:hover :nth-child(4n+3),
-allocation-profile .collection-item:hover :nth-child(4n+4) {
+.allocation-profile .collection-item:hover :nth-child(2n+2).group,
+.allocation-profile .collection-item:hover :nth-child(4n+3),
+.allocation-profile .collection-item:hover :nth-child(4n+4) {
   background-color: #afd5fd;
 }
 
-allocation-profile .header .collection-item :nth-child(2n+1).group,
-allocation-profile .header .collection-item :nth-child(4n+1),
-allocation-profile .header .collection-item :nth-child(4n+2) {
+.allocation-profile .header .collection-item :nth-child(2n+1).group,
+.allocation-profile .header .collection-item :nth-child(4n+1),
+.allocation-profile .header .collection-item :nth-child(4n+2) {
   background-color: #FFFFFF;
 }
 
-allocation-profile .header .collection-item :nth-child(2n+2).group,
-allocation-profile .header .collection-item :nth-child(4n+3),
-allocation-profile .header .collection-item :nth-child(4n+4) {
+.allocation-profile .header .collection-item :nth-child(2n+2).group,
+.allocation-profile .header .collection-item :nth-child(4n+3),
+.allocation-profile .header .collection-item :nth-child(4n+4) {
   background-color: #DDDDDD;
 }
 
-allocation-profile .collection-item .group {
+.allocation-profile .collection-item .group {
   display: inline-block;
   width: 12em;
   text-align: right;
@@ -531,7 +531,7 @@
   border-right: solid 1px #AAAAAA;
 }
 
-allocation-profile .collection-item .bytes {
+.allocation-profile .collection-item .bytes {
   display: inline-block;
   width: 6em;
   text-align: right;
@@ -539,7 +539,7 @@
   padding-right: 0.5em;
 }
 
-allocation-profile .collection-item .instances {
+.allocation-profile .collection-item .instances {
   display: inline-block;
   width: 6em;
   text-align: right;
@@ -548,56 +548,56 @@
   border-right: solid 1px #AAAAAA;
 }
 
-allocation-profile .collection-item .name {
+.allocation-profile .collection-item .name {
   padding-left: 0.5em;
   padding-right: 0.5em;
   display: inline-block;
 }
 
-allocation-profile .collection-item > button,
-allocation-profile .collection-item > button:active {
+.allocation-profile .collection-item > button,
+.allocation-profile .collection-item > button:active {
   background-color: transparent;
   color: #0489c3;
   border-style: none;
 }
 
-allocation-profile .collection-item > button:hover {
+.allocation-profile .collection-item > button:hover {
   text-decoration: underline;
 }
 
 /* class-ref */
 
-class-ref > a[href]:hover {
+.class-ref > a[href]:hover {
     text-decoration: underline;
 }
-class-ref > a[href] {
+.class-ref > a[href] {
     color: #0489c3;
     text-decoration: none;
 }
 
 /* code-ref */
 
-code-ref > a[href]:hover {
+.code-ref > a[href]:hover {
   text-decoration: underline;
 }
-code-ref > a[href] {
+.code-ref > a[href] {
   color: #0489c3;
   text-decoration: none;
 }
-code-ref .emphasize {
+.code-ref .emphasize {
   font-style: italic;
 }
 
 
 /* class-tree */
 
-class-tree {
+.class-tree {
   position: relative;
   display: block;
   height: 100%;
 }
 
-class-tree virtual-tree {
+.class-tree .virtual-tree {
   position: absolute;
   height: auto;
   top: 60px;
@@ -606,47 +606,47 @@
   right: 0;
 }
 
-class-tree virtual-tree .container {
+.class-tree .virtual-tree .container {
   padding-left: 10%;
   padding-right: 10%;
 }
 
-class-tree virtual-tree .class-tree-item {
+.class-tree .virtual-tree .class-tree-item {
   line-height: 25px;
   height: 25px;
 }
 
-class-tree virtual-tree .class-tree-item .name {
+.class-tree .virtual-tree .class-tree-item .name {
   margin-left: 0.5em;
   margin-right: 0.5em;
 }
 
 /* code-view */
 
-code-view .table {
+.code-view .table {
   table-layout: fixed;
 }
 
-code-view th:nth-of-type(1),
-code-view td:nth-of-type(1) {
+.code-view th:nth-of-type(1),
+.code-view td:nth-of-type(1) {
   min-width: 10em;
   text-align: left;
 }
 
-code-view th:nth-of-type(2),
-code-view td:nth-of-type(2) {
+.code-view th:nth-of-type(2),
+.code-view td:nth-of-type(2) {
   min-width: 8em;
   text-align: left;
 }
 
-code-view th:nth-of-type(3),
-code-view td:nth-of-type(3) {
+.code-view th:nth-of-type(3),
+.code-view td:nth-of-type(3) {
   min-width: 8em;
   text-align: left;
 }
 
-code-view th:nth-of-type(4),
-code-view td:nth-of-type(4) {
+.code-view th:nth-of-type(4),
+.code-view td:nth-of-type(4) {
   text-align: left;
   overflow: visible;
   white-space: pre;
@@ -654,47 +654,47 @@
   width: 1px;
 }
 
-code-view th:nth-of-type(5),
-code-view td:nth-of-type(5) {
+.code-view th:nth-of-type(5),
+.code-view td:nth-of-type(5) {
   text-align: left;
   overflow: visible;
 }
 
-code-view tr:hover > td {
+.code-view tr:hover > td {
   background-color: #F4C7C3;
 }
 
-code-view .code-comment {
+.code-view .code-comment {
   color: grey;
   font-style: italic;
 }
 
 /* context-ref */
 
-context-ref > a[href]:hover {
+.context-ref > a[href]:hover {
   text-decoration: underline;
 }
-context-ref > a[href] {
+.context-ref > a[href] {
   color: #0489c3;
   text-decoration: none;
 }
-context-ref > a[href] * {
+.context-ref > a[href] * {
   color: inherit;
 }
-context-ref .emphasize {
+.context-ref .emphasize {
   font-style: italic;
 }
 
 
 /* cpu-profile */
 
-cpu-profile {
+.cpu-profile {
   position: relative;
   display: block;
   height: 100%;
 }
 
-cpu-profile > cpu-profile-virtual-tree {
+.cpu-profile > .cpu-profile-virtual-tree {
   position: absolute;
   height: auto;
   top: 320px;
@@ -705,18 +705,18 @@
 
 /* cpu-profile-table */
 
-cpu-profile-table {
+.cpu-profile-table {
   position: relative;
   display: block;
   height: 100%;
 }
-cpu-profile-table cpu-profile-virtual-tree {
+.cpu-profile-table .cpu-profile-virtual-tree {
   height: 100%;
   min-height: 600px;
   padding-top: 250px;
   margin-top: -250px;
 }
-cpu-profile-table .profile-trees {
+.cpu-profile-table .profile-trees {
   vertical-align: text-top;
   min-width: 100%;
   height: 100%;
@@ -728,26 +728,26 @@
   padding-right: 5%;
   min-height: 600px;
 }
-cpu-profile-table .profile-trees virtual-collection {
+.cpu-profile-table .profile-trees .virtual-collection {
   height: 100%;
   width: 100%;
   border: solid 1px #888888;
   box-shadow: 2px 2px 5px #888888;
 }
-cpu-profile-table .profile-trees > .profile-trees-all {
+.cpu-profile-table .profile-trees > .profile-trees-all {
   vertical-align: text-top;
   display: inline-block;
   width: 50%;
   height: 100%;
   padding: 5px;
 }
-cpu-profile-table .profile-trees > .profile-trees-current {
+.cpu-profile-table .profile-trees > .profile-trees-current {
   vertical-align: text-top;
   display: inline-block;
   width: 50%;
   height: 100%;
 }
-cpu-profile-table .profile-trees .profile-trees-caller {
+.cpu-profile-table .profile-trees .profile-trees-caller {
   vertical-align: text-top;
   display: inline-block;
   width: 100%;
@@ -756,7 +756,7 @@
   margin-top: -17px;
   padding-top: 22px;
 }
-cpu-profile-table .profile-trees .profile-trees-selected {
+.cpu-profile-table .profile-trees .profile-trees-selected {
   vertical-align: text-top;
   display: block;
   height: 24px;
@@ -767,14 +767,14 @@
   padding-left: 5px;
   padding-right: 5px;
 }
-cpu-profile-table .profile-trees .profile-trees-selected > * {
+.cpu-profile-table .profile-trees .profile-trees-selected > * {
   white-space: nowrap;
   text-overflow: ellipsis;
   overflow: hidden;
   display: inline-block;
   width: 100%;
 }
-cpu-profile-table .profile-trees .profile-trees-callee {
+.cpu-profile-table .profile-trees .profile-trees-callee {
   vertical-align: text-top;
   display: inline-block;
   width: 100%;
@@ -783,68 +783,68 @@
   margin-bottom: -17px;
   padding-bottom: 22px;
 }
-cpu-profile-table .function-item {
+.cpu-profile-table .function-item {
   box-sizing: border-box;
   line-height: 20px;
 }
-cpu-profile-table .header {
+.cpu-profile-table .header {
   box-sizing: border-box;
   line-height: 20px;
 }
-cpu-profile-table .header .function-item:last-child {
+.cpu-profile-table .header .function-item:last-child {
   margin-bottom: -3px;
   border-bottom: solid 1px #AAAAAA;
 }
-cpu-profile-table .function-item .inclusive,
-cpu-profile-table .function-item .exclusive {
+.cpu-profile-table .function-item .inclusive,
+.cpu-profile-table .function-item .exclusive {
   display: inline-block;
   width: 7em;
   text-align: right;
   padding-right: 0.5em;
   line-height: 20px;
 }
-cpu-profile-table .buffer .function-item .inclusive {
+.cpu-profile-table .buffer .function-item .inclusive {
   background-color: #EEEEEE;
 }
-cpu-profile-table .buffer .function-item.selected .inclusive {
+.cpu-profile-table .buffer .function-item.selected .inclusive {
   background-color: #51a3fb;
 }
-cpu-profile-table .buffer .function-item:hover .inclusive {
+.cpu-profile-table .buffer .function-item:hover .inclusive {
   background-color: #afd5fd;
 }
-cpu-profile-table .header .function-item .inclusive {
+.cpu-profile-table .header .function-item .inclusive {
   background-color: #DDDDDD;
 }
-cpu-profile-table .buffer .function-item.selected {
+.cpu-profile-table .buffer .function-item.selected {
   background-color: #60abfb;
 }
-cpu-profile-table .buffer .function-item:hover {
+.cpu-profile-table .buffer .function-item:hover {
   background-color: #d2e7fe;
 }
-cpu-profile-table .function-item .exclusive {
+.cpu-profile-table .function-item .exclusive {
 }
-cpu-profile-table .function-item .name {
+.cpu-profile-table .function-item .name {
   padding-left: 0.5em;
   padding-left: 0.5em;
 }
-cpu-profile-table .function-item > button,
-cpu-profile-table .function-item > button:active {
+.cpu-profile-table .function-item > button,
+.cpu-profile-table .function-item > button:active {
   background-color: transparent;
   color: #0489c3;
   border-style: none;
 }
-cpu-profile-table .function-item > button:hover {
+.cpu-profile-table .function-item > button:hover {
   text-decoration: underline;
 }
 
 /* cpu-profile-virtual-tree */
 
-cpu-profile-virtual-tree {
+.cpu-profile-virtual-tree {
   display: block;
   height: 600px;
 }
 
-cpu-profile-virtual-tree .tree-item {
+.cpu-profile-virtual-tree .tree-item {
   box-sizing: border-box;
   line-height: 30px;
   height: 30px;
@@ -852,9 +852,9 @@
   padding-right: 5%;
 }
 
-cpu-profile-virtual-tree .tree-item > .inclusive,
-cpu-profile-virtual-tree .tree-item > .exclusive,
-cpu-profile-virtual-tree .tree-item > .percentage {
+.cpu-profile-virtual-tree .tree-item > .inclusive,
+.cpu-profile-virtual-tree .tree-item > .exclusive,
+.cpu-profile-virtual-tree .tree-item > .percentage {
   display: inline-block;
   text-align: right;
   width: 4em;
@@ -862,11 +862,11 @@
   margin-right: 0.25em;
 }
 
-cpu-profile-virtual-tree .tree-item > .exclusive {
+.cpu-profile-virtual-tree .tree-item > .exclusive {
   margin-right: 1.5em;
 }
 
-cpu-profile-virtual-tree .tree-item > .name {
+.cpu-profile-virtual-tree .tree-item > .name {
   display: inline;
   margin-left: 0.5em;
   margin-right: 0.5em;
@@ -874,116 +874,116 @@
 
 /* curly-block */
 
-curly-block span.curly-block {
+.curly-block span.curly-block {
   color: #0489c3;
   cursor: pointer;
 }
-curly-block span.curly-block.disabled {
+.curly-block span.curly-block.disabled {
   color: white;
   cursor: wait;
 }
 
 /* debugger-console */
 
-debugger-console {
+.debugger-console {
   display: block;
   margin: 0px 20px 10px 20px;
 }
-debugger-console .normal {
+.debugger-console .normal {
   font: normal 14px consolas, courier, monospace;
   white-space: pre;
   line-height: 125%;
 }
-debugger-console .bold {
+.debugger-console .bold {
   font: bold 14px consolas, courier, monospace;
   white-space: pre;
   line-height: 125%;
 }
-debugger-console .red {
+.debugger-console .red {
   font: normal 14px consolas, courier, monospace;
   white-space: pre;
   line-height: 125%;
   color: red;
 }
-debugger-console .green {
+.debugger-console .green {
   font: normal 14px consolas, courier, monospace;
   white-space: pre;
   line-height: 125%;
   color: green;
 }
-debugger-console .spacer {
+.debugger-console .spacer {
   height: 20px;
 }
 
 /* debugger-frame */
 
-debugger-frame {
+.debugger-frame {
   display: block;
   position: relative;
   padding: 5px;
   border: 1px solid white;
 }
-debugger-frame:hover {
+.debugger-frame:hover {
   border: 1px solid #e0e0e0;
 }
-debugger-frame.shadow {
+.debugger-frame.shadow {
   box-shadow:  0 2px 10px 0 rgba(0, 0, 0, 0.16),
                0 2px 5px 0 rgba(0, 0, 0, 0.26);
 }
-debugger-frame.causalFrame {
+.debugger-frame.causalFrame {
   background-color: #D7CCC8;
 }
-debugger-frame.current {
+.debugger-frame.current {
   box-shadow:  0 2px 10px 0 rgba(0, 0, 0, 0.26),
                0 2px 5px 0 rgba(0, 0, 0, 0.46);
   border: 1px solid #444;
 }
-debugger-frame > button {
+.debugger-frame > button {
   display: block;
   width: 100%;
   text-align: left;
   background-color: transparent;
   border: none;
 }
-debugger-frame .frameSummaryText {
+.debugger-frame .frameSummaryText {
   display: inline-block;
   padding: 5px;
 }
-debugger-frame .frameId {
+.debugger-frame .frameId {
   display: inline-block;
   width: 60px;
 }
-debugger-frame .frameExpander {
+.debugger-frame .frameExpander {
   position: absolute;
   right: 5px;
   top: 5px;
   display: none;
 }
-debugger-frame:hover .frameExpander{
+.debugger-frame:hover .frameExpander{
   display: inline-block;
 }
-debugger-frame .frameContractor {
+.debugger-frame .frameContractor {
   position: absolute;
   right: 5px;
   bottom: 5px;
   display: inline-block;
 }
-debugger-frame .frameContractor > button {
+.debugger-frame .frameContractor > button {
   background-color: transparent;
   border: none;
 }
-debugger-frame .flex-item-script {
+.debugger-frame .flex-item-script {
   flex-grow: 1;
   flex-shrink: 1;
   flex-basis: 765px;
 }
-debugger-frame .flex-item-vars {
+.debugger-frame .flex-item-vars {
   flex-grow: 5;
   flex-shrink: 0;
   flex-basis: 250px;
   overflow-x: hidden;
 }
-debugger-frame .frameVars {
+.debugger-frame .frameVars {
   position: relative;
   top: 5px;
   padding-left:2em;
@@ -992,20 +992,20 @@
 
 /* debugger-input */
 
-debugger-input .container {
+.debugger-input .container {
   height: 100%;
   display: flex;
   flex-direction: row;
   justify-content: space-between;
 }
-debugger-input .textBox {
+.debugger-input .textBox {
   flex: 1 1 auto;
   margin: 20px;
   padding: 5px;
   font: 400 16px consolas, courier, monospace;
   width: 95%;
 }
-debugger-input .modalPrompt {
+.debugger-input .modalPrompt {
   flex: 0 0 auto;
   margin-top: 20px;
   margin-left: 20px;
@@ -1013,70 +1013,70 @@
   font: 400 16px consolas, courier, monospace;
   color: red;
 }
-debugger-input .modalPrompt.hidden {
+.debugger-input .modalPrompt.hidden {
   display: none;
 }
 
 /* debugger-message */
 
-debugger-message {
+.debugger-message {
   display: block;
   position: relative;
   padding: 5px;
   border: 1px solid white;
 }
-debugger-message:hover {
+.debugger-message:hover {
   border: 1px solid #e0e0e0;
 }
-debugger-message.shadow {
+.debugger-message.shadow {
   box-shadow:  0 2px 10px 0 rgba(0, 0, 0, 0.16),
   0 2px 5px 0 rgba(0, 0, 0, 0.26);
 }
-debugger-message.current {
+.debugger-message.current {
   box-shadow:  0 2px 10px 0 rgba(0, 0, 0, 0.26),
   0 2px 5px 0 rgba(0, 0, 0, 0.46);
   border: 1px solid #444;
 }
-debugger-message > button {
+.debugger-message > button {
   display: block;
   width: 100%;
   text-align: left;
   background-color: transparent;
   border: none;
 }
-debugger-message .messageSummaryText {
+.debugger-message .messageSummaryText {
   display: inline-block;
   padding: 5px;
 }
-debugger-message .messageId {
+.debugger-message .messageId {
   display: inline-block;
   font-weight: bold;
   width: 100px;
 }
-debugger-message .messageExpander {
+.debugger-message .messageExpander {
   position: absolute;
   right: 5px;
   top: 5px;
   display: none;
 }
-debugger-message:hover .messageExpander {
+.debugger-message:hover .messageExpander {
   display: inline-block;
 }
-debugger-message.shadow:hover .messageExpander {
+.debugger-message.shadow:hover .messageExpander {
   display: none;
 }
-debugger-message .messageContractor {
+.debugger-message .messageContractor {
   position: absolute;
   right: 5px;
   bottom: 5px;
   display: inline-block;
 }
-debugger-message .flex-item-script {
+.debugger-message .flex-item-script {
   flex-grow: 1;
   flex-shrink: 1;
   flex-basis: 765px;
 }
-debugger-message .flex-item-vars {
+.debugger-message .flex-item-vars {
   flex-grow: 5;
   flex-shrink: 0;
   flex-basis: 225px;
@@ -1084,77 +1084,77 @@
 
 /* debugger-page */
 
-debugger-page {
+.debugger-page {
   height: 100%;
 }
-debugger-page .variable {
+.debugger-page .variable {
   height: 100%;
   margin-bottom: -75px;
   padding-bottom: 75px;
 }
-debugger-page .stack {
+.debugger-page .stack {
   flex: 0 0 auto;
   overflow-y: auto;
   height: 62%;
 }
-debugger-page .splitter {
+.debugger-page .splitter {
   height: 0px;
   margin: 0px;
   font-size: 1px;
   border-bottom: 1px solid #888;
 }
-debugger-page .console {
+.debugger-page .console {
   flex: 1 1 auto;
   overflow-x: auto;
   overflow-y: auto;
   height: 38%;
 }
-debugger-page .commandline {
+.debugger-page .commandline {
   flex: 0 0 auto;
 }
 
 /* debugger-stack */
 
-debugger-stack {
+.debugger-stack {
   position: relative;
 }
-debugger-stack .sampledMessage {
+.debugger-stack .sampledMessage {
   margin: 0px 20px 10px 20px;
   font: 400 14px 'Montserrat', sans-serif;
   line-height: 125%;
 }
-debugger-stack .sampledMessage > button {
+.debugger-stack .sampledMessage > button {
   background-color: transparent;
   border: none;
   color: #0489c3;
   text-decoration: none;
   margin-right: 1em;
 }
-debugger-stack .sampledMessage > button:hover {
+.debugger-stack .sampledMessage > button:hover {
     text-decoration: underline;
 }
-debugger-stack .splitter {
+.debugger-stack .splitter {
   height: 0px;
   margin: 0px;
   font-size: 1px;
   border-bottom: 1px dashed #888;
 }
-debugger-stack .noMessages,
-debugger-stack .noStack {
+.debugger-stack .noMessages,
+.debugger-stack .noStack {
   margin: 10px 0px 10px 25px;
   font: bold 14px 'Montserrat', sans-serif;
   line-height: 125%;
 }
 
-debugger-stack .sampledMessage.hidden,
-debugger-stack .noMessages.hidden,
-debugger-stack .noStack.hidden {
+.debugger-stack .sampledMessage.hidden,
+.debugger-stack .noMessages.hidden,
+.debugger-stack .noStack.hidden {
   display: none;
 }
 
 /* error-ref */
 
-error-ref > pre {
+.error-ref > pre {
   background-color: #f5f5f5;
   border: 1px solid #ccc;
   padding-left: 10px;
@@ -1167,19 +1167,19 @@
 
 /* eval-box */
 
-eval-box a[href]:hover {
+.eval-box a[href]:hover {
     text-decoration: underline;
 }
-eval-box a[href] {
+.eval-box a[href] {
     color: #0489c3;
     text-decoration: none;
 }
-eval-box .quicks > button:hover {
+.eval-box .quicks > button:hover {
   background-color: transparent;
   border: none;
   text-decoration: underline;
 }
-eval-box .quicks > button {
+.eval-box .quicks > button {
   background-color: transparent;
   border: none;
   color: #0489c3;
@@ -1187,15 +1187,15 @@
   margin-right: 1em;
   text-decoration: none;
 }
-eval-box .emphasize {
+.eval-box .emphasize {
   font-style: italic;
 }
-eval-box .indent {
+.eval-box .indent {
   margin-left: 1.5em;
   font: 400 14px 'Montserrat', sans-serif;
   line-height: 150%;
 }
-eval-box .stackTraceBox {
+.eval-box .stackTraceBox {
   margin-left: 1.5em;
   background-color: #f5f5f5;
   border: 1px solid #ccc;
@@ -1205,7 +1205,7 @@
   white-space: pre;
   overflow-x: auto;
 }
-eval-box .heading {
+.eval-box .heading {
   line-height: 30px;
   position: relative;
   box-sizing: border-box;
@@ -1213,24 +1213,24 @@
   min-width: 450px;
   padding-right: 150px;
 }
-eval-box .heading .textbox {
+.eval-box .heading .textbox {
   width: 100%;
   min-width: 300px;
 }
-eval-box .heading .buttons {
+.eval-box .heading .buttons {
   position: absolute;
   top: 0;
   right: 0px;
 }
-eval-box .heading .buttons button{
+.eval-box .heading .buttons button{
   margin-right: 1em;
 }
-eval-box.historyExpr,
-eval-box .historyValue {
+.eval-box.historyExpr,
+.eval-box .historyValue {
   vertical-align: text-top;
   font: 400 14px 'Montserrat', sans-serif;
 }
-eval-box .historyExpr button {
+.eval-box .historyExpr button {
   display: block;
   color: black;
   border: none;
@@ -1240,14 +1240,14 @@
   cursor: pointer;
   white-space: pre-line;
 }
-eval-box .historyExpr button:hover {
+.eval-box .historyExpr button:hover {
   background-color: #fff3e3;
 }
-eval-box .historyValue {
+.eval-box .historyValue {
   display: block;
   padding: 6px 6px;
 }
-eval-box .historyDelete button {
+.eval-box .historyDelete button {
   border: none;
   background: none;
 }
@@ -1257,48 +1257,48 @@
 
 /* flag-list */
 
-flag-list .comment {
+.flag-list .comment {
   color: #aaa;
 }
 
-flag-list .flag {
+.flag-list .flag {
   padding: 3px 0;
 }
 
-flag-list .name {
+.flag-list .name {
   font-weight: bold;
   margin-right: 0.7em;
 }
 
-flag-list .value {
+.flag-list .value {
   margin-left: 0.7em;
 }
 
 /* function-ref */
 
-function-ref > a[href]:hover {
+.function-ref > a[href]:hover {
   text-decoration: underline;
 }
-function-ref > a[href] {
+.function-ref > a[href] {
   color: #0489c3;
   text-decoration: none;
 }
-function-ref .emphasize {
+.function-ref .emphasize {
   font-style: italic;
 }
 
 
 /* heap-snapshot */
 
-heap-snapshot .statusMessage {
+.heap-snapshot .statusMessage {
   font-size: 150%;
   font-weight: bold;
 }
-heap-snapshot .statusBox {
+.heap-snapshot .statusBox {
   height: 100%;
   padding: 1em;
 }
-heap-snapshot .explanation {
+.heap-snapshot .explanation {
   display: block;
   display: -webkit-box;
   -webkit-line-clamp: 4;
@@ -1307,7 +1307,7 @@
   overflow: hidden;
   text-overflow: ellipsis;
 }
-heap-snapshot virtual-tree {
+.heap-snapshot .virtual-tree {
   position: absolute;
   height: auto;
   top: 250px;
@@ -1315,15 +1315,15 @@
   left: 0;
   right: 0;
 }
-heap-snapshot .tree-item {
+.heap-snapshot .tree-item {
   box-sizing: border-box;
   line-height: 30px;
   height: 30px;
   padding-left: 5%;
   padding-right: 5%;
 }
-heap-snapshot .tree-item > .size,
-heap-snapshot .tree-item > .percentage {
+.heap-snapshot .tree-item > .size,
+.heap-snapshot .tree-item > .percentage {
   display: inline-block;
   text-align: right;
   width: 4em;
@@ -1331,7 +1331,7 @@
   margin-right: 0.25em;
 }
 
-heap-snapshot .tree-item > .name {
+.heap-snapshot .tree-item > .name {
   display: inline;
   margin-left: 0.5em;
   margin-right: 0.5em;
@@ -1340,37 +1340,37 @@
 
 /* icdata-ref */
 
-icdata-ref > a[href]:hover {
+.icdata-ref > a[href]:hover {
   text-decoration: underline;
 }
-icdata-ref > a[href] {
+.icdata-ref > a[href] {
   color: #0489c3;
   text-decoration: none;
 }
-icdata-ref > a[href] * {
+.icdata-ref > a[href] * {
   color: inherit;
 }
-icdata-ref .emphasize {
+.icdata-ref .emphasize {
   font-style: italic;
 }
 
 
 /* inbound-reference */
 
-inbound-reference > a[href]:hover {
+.inbound-reference > a[href]:hover {
   text-decoration: underline;
 }
-inbound-reference > a[href] {
+.inbound-reference > a[href] {
   color: #0489c3;
   text-decoration: none;
 }
 
-inbound-reference .indent {
+.inbound-reference .indent {
   margin-left: 1.5em;
   font: 400 14px 'Montserrat', sans-serif;
   line-height: 150%;
 }
-inbound-reference .stackTraceBox {
+.inbound-reference .stackTraceBox {
   margin-left: 1.5em;
   background-color: #f5f5f5;
   border: 1px solid #ccc;
@@ -1383,25 +1383,25 @@
 
 /* instance-ref */
 
-instance-ref > a[href]:hover {
+.instance-ref > a[href]:hover {
   text-decoration: underline;
 }
-instance-ref > a[href] {
+.instance-ref > a[href] {
   color: #0489c3;
   text-decoration: none;
 }
-instance-ref > a[href] * {
+.instance-ref > a[href] * {
   color: inherit;
 }
-instance-ref .emphasize {
+.instance-ref .emphasize {
   font-style: italic;
 }
-instance-ref .indent {
+.instance-ref .indent {
   margin-left: 1.5em;
   font: 400 14px 'Montserrat', sans-serif;
   line-height: 150%;
 }
-instance-ref .stackTraceBox {
+.instance-ref .stackTraceBox {
   margin-left: 1.5em;
   background-color: #f5f5f5;
   border: 1px solid #ccc;
@@ -1414,20 +1414,20 @@
 
 /* isolate-counter-chart */
 
-isolate-counter-chart {
+.isolate-counter-chart {
   display: block;
   position: relative;
   height: 300px;
   min-width: 350px;
 }
-isolate-counter-chart > div.host {
+.isolate-counter-chart > div.host {
   position: absolute;
   left: 0;
   bottom: 20px;
   top: 5px;
   right: 250px;
 }
-isolate-counter-chart > div.legend {
+.isolate-counter-chart > div.legend {
   position: absolute;
   width: 250px;
   top: 0;
@@ -1438,42 +1438,42 @@
 
 /* isolate-location */
 
-isolate-location > span {
+.isolate-location > span {
   font-weight: bold;
 }
-isolate-location > a[href] {
+.isolate-location > a[href] {
   color: #0489c3;
   text-decoration: none;
 }
-isolate-location > a[href]:hover {
+.isolate-location > a[href]:hover {
   text-decoration: underline;
 }
 
 /* isolate-reconnect */
 
-isolate-reconnect div.doubleSpaced {
+.isolate-reconnect div.doubleSpaced {
   line-height: 2em;
 }
 
 /* isolate-ref */
 
-isolate-ref > a[href]:hover {
+.isolate-ref > a[href]:hover {
   text-decoration: underline;
 }
-isolate-ref > a[href] {
+.isolate-ref > a[href] {
   color: #0489c3;
   text-decoration: none;
 }
 
 /* isolate-run-state */
 
-isolate-run-state > span {
+.isolate-run-state > span {
   font-weight: bold;
 }
 
 /* isolate-shared-summary */
 
-isolate-shared-summary {
+.isolate-shared-summary {
   display: block;
 }
 
@@ -1487,23 +1487,23 @@
   min-width: 18ex;
 }
 
-isolate-shared-summary > .summary {
+.isolate-shared-summary > .summary {
   height: 300px;
   position: relative;
 }
-isolate-shared-summary .menu {
+.isolate-shared-summary .menu {
   float: right;
   top: 0;
   right: 0;
 }
-isolate-shared-summary isolate-counter-chart {
+.isolate-shared-summary .isolate-counter-chart {
   position: absolute;
   left: 0;
   top: 0;
   right: 230px;
   clear: both;
 }
-isolate-shared-summary .errorBox {
+.isolate-shared-summary .errorBox {
   background-color: #f5f5f5;
   border: 1px solid #ccc;
   padding: 2em;
@@ -1515,14 +1515,14 @@
 
 /* library-ref */
 
-library-ref > a[href]:hover {
+.library-ref > a[href]:hover {
   text-decoration: underline;
 }
-library-ref > a[href] {
+.library-ref > a[href] {
   color: #0489c3;
   text-decoration: none;
 }
-library-ref .emphasize {
+.library-ref .emphasize {
   font-style: italic;
 }
 
@@ -1539,103 +1539,103 @@
 
 /* logging-list */
 
-logging-list .outlined {
+.logging-list .outlined {
   -webkit-box-shadow: 0px 0px 2px 1px rgba(0,0,0,0.75);
   -moz-box-shadow: 0px 0px 2px 1px rgba(0,0,0,0.75);
   box-shadow: 0px 0px 2px 1px rgba(0,0,0,0.75);
   margin: 4px;
 }
-logging-list .logItem {
+.logging-list .logItem {
   display: inline-block;
   font: normal 14px consolas, courier, monospace;
   white-space: pre;
   line-height: 125%;
   width: 100%;
 }
-logging-list .level {
+.logging-list .level {
   display: inline-block;
   width: 5em;
 }
-logging-list .time {
+.logging-list .time {
   display: inline-block;
   width: 12em;
 }
-logging-list .FINEST {
+.logging-list .FINEST {
   background-color: #FAFAFA;
 }
-logging-list .FINER {
+.logging-list .FINER {
   background-color: #ECEFF1;
 }
-logging-list .FINE {
+.logging-list .FINE {
   background-color: #EFEBE9;
 }
-logging-list .CONFIG {
+.logging-list .CONFIG {
   background-color: #FFF3E0;
 }
-logging-list .INFO {
+.logging-list .INFO {
   background-color: #F1F8E9;
 }
-logging-list .WARNING {
+.logging-list .WARNING {
   background-color: #FFE0B2;
 }
-logging-list .SEVERE {
+.logging-list .SEVERE {
   background-color: #FFCCBC;
 }
-logging-list .SHOUT {
+.logging-list .SHOUT {
   background-color: #FFCDD2;
 }
 
 /* memory-graph */
 
-memory-graph .chart-legend-row,
-memory-graph .chart-legend-row div {
+.memory-graph .chart-legend-row,
+.memory-graph .chart-legend-row div {
   display: inline;
 }
 
-memory-graph .chart-legend-row div.chart-legend-color {
+.memory-graph .chart-legend-row div.chart-legend-color {
   display: inline-block;
   margin: auto 8px;
 }
 
-memory-graph .chart-legend-row:nth-child(2n) div.chart-legend-color {
+.memory-graph .chart-legend-row:nth-child(2n) div.chart-legend-color {
   display: none;
 }
 
 /* megamorphic-cache-ref */
 
-megamorphic-cache-ref > a[href]:hover {
+.megamorphic-cache-ref > a[href]:hover {
     text-decoration: underline;
 }
-megamorphic-cache-ref > a[href] {
+.megamorphic-cache-ref > a[href] {
     color: #0489c3;
     text-decoration: none;
 }
-megamorphic-cache-ref > a[href] * {
+.megamorphic-cache-ref > a[href] * {
     color: inherit;
 }
-megamorphic-ref .emphasize {
+.megamorphic-ref .emphasize {
   font-style: italic;
 }
 
 /* dashboards common */
 
-memory-dashboard,
-timeline-dashboard {
+.memory-dashboard,
+.timeline-dashboard {
   display: block;
   height: 100%;
   margin-top: -30px;
 }
 
-memory-profile > div > h1,
-timeline-dashboard > div > h1 {
+.memory-profile > div > h1,
+.timeline-dashboard > div > h1 {
   overflow: hidden;
   border-bottom: 1px solid #d5d5d5;
 }
 
-memory-dashboard button:disabled,
-timeline-dashboard button:disabled,
-memory-dashboard button:disabled:hover,
-timeline-dashboard button:disabled:hover {
+.memory-dashboard button:disabled,
+.timeline-dashboard button:disabled,
+.memory-dashboard button:disabled:hover,
+.timeline-dashboard button:disabled:hover {
   text-decoration: none;
   background-color: #eee;
   background-image: linear-gradient(#eee, #eee);
@@ -1644,14 +1644,14 @@
   cursor: default;
 }
 
-timeline-dashboard p {
+.timeline-dashboard p {
   margin-top: 0.4em;
 }
 
-memory-dashboard button,
-timeline-dashboard button,
-memory-dashboard button:active,
-timeline-dashboard button:active {
+.memory-dashboard button,
+.timeline-dashboard button,
+.memory-dashboard button:active,
+.timeline-dashboard button:active {
   text-decoration: none;
   background-color: #ddd;
   background-image: linear-gradient(#eee, #ddd);
@@ -1660,23 +1660,23 @@
   cursor: pointer;
 }
 
-memory-dashboard button:hover,
-timeline-dashboard button:hover {
+.memory-dashboard button:hover,
+.timeline-dashboard button:hover {
   text-decoration: none;
   background-color: #ccc;
   background-image: linear-gradient(#ddd, #ccc);
   border-color: #c7c7c7;
 }
 
-memory-profile .header_button,
-timeline-dashboard .header_button {
+.memory-profile .header_button,
+.timeline-dashboard .header_button {
   padding: 3px 5px;
   margin: 0px 1px;
   min-width: 130px;
 }
 
-memory-profile .header_button,
-timeline-dashboard .header_button {
+.memory-profile .header_button,
+.timeline-dashboard .header_button {
   margin-left: 6px;
 }
 
@@ -1684,32 +1684,32 @@
   margin-left: 75px;
 }
 
-memory-profile .header_button:first-child,
-timeline-dashboard .header_button:first-child {
+.memory-profile .header_button:first-child,
+.timeline-dashboard .header_button:first-child {
   margin-left: 30px;
 }
 
-memory-profile .tab_buttons,
-timeline-dashboard .tab_buttons {
+.memory-profile .tab_buttons,
+.timeline-dashboard .tab_buttons {
   position: relative;
   top: 1px;
   float: right;
 }
 
-memory-profile .tab_buttons button,
-timeline-dashboard .tab_buttons button {
+.memory-profile .tab_buttons button,
+.timeline-dashboard .tab_buttons button {
   padding: 5px 5px;
   min-width: 100px
 }
 
-memory-profile .tab_buttons button:not(:first-child),
-timeline-dashboard .tab_buttons button:not(:first-child) {
+.memory-profile .tab_buttons button:not(:first-child),
+.timeline-dashboard .tab_buttons button:not(:first-child) {
   border-top-left-radius: 0px;
   border-bottom-left-radius: 0px;
 }
 
-memory-profile .tab_buttons button:not(:last-child),
-timeline-dashboard  .tab_buttons button:not(:last-child) {
+.memory-profile .tab_buttons button:not(:last-child),
+.timeline-dashboard  .tab_buttons button:not(:last-child) {
   border-top-right-radius: 0px;
   border-bottom-right-radius: 0px;
 }
@@ -1717,11 +1717,11 @@
 
 /* memory-dashboard */
 
-memory-dashboard memory-graph {
+.memory-dashboard .memory-graph {
   height: 350px;
 }
 
-memory-dashboard memory-profile {
+.memory-dashboard .memory-profile {
   position: absolute;
   bottom: 20px;
   left: 0;
@@ -1729,7 +1729,7 @@
   top: 300px;
 }
 
-memory-dashboard memory-profile memory-allocations {
+.memory-dashboard .memory-profile .memory-allocations {
   position: absolute;
   bottom: 0;
   left: 0;
@@ -1737,7 +1737,7 @@
   top: 39px;
 }
 
-memory-dashboard memory-profile memory-snapshot {
+.memory-dashboard .memory-profile .memory-snapshot {
   position: absolute;
   bottom: 0;
   left: 0;
@@ -1747,76 +1747,76 @@
 
 /* metric-graph */
 
-metric-graph {
+.metric-graph {
   display: block;
 }
 
-metric-graph .graph {
+.metric-graph .graph {
   height: 100%;
   margin-top: -30px;
   padding: 20px;
   padding-top: 60px;
 }
 
-metric-graph .graph > div {
+.metric-graph .graph > div {
   height: 100%;
 }
 
 /* memory-allocations */
 
-memory-allocations .container {
+.memory-allocations .container {
   padding-left: 5%;
   padding-right: 5%;
 }
 
-memory-allocations .collection-item {
+.memory-allocations .collection-item {
   background-color: #FFFFFF;
   box-sizing: border-box;
   line-height: 20px;
 }
 
-memory-allocations .collection-item:hover {
+.memory-allocations .collection-item:hover {
   background-color: #d2e7fe;
 }
 
-memory-allocations .header .collection-item:hover {
+.memory-allocations .header .collection-item:hover {
   background-color: #FFFFFF;
 }
 
-memory-allocations .header .collection-item:last-child {
+.memory-allocations .header .collection-item:last-child {
   margin-bottom: -3px;
   border-bottom: solid 1px #AAAAAA;
 }
 
-memory-allocations .header .collection-item span {
+.memory-allocations .header .collection-item span {
   font-weight: bolder;
 }
 
-memory-allocations .collection-item :nth-child(2n+2).group,
-memory-allocations .collection-item :nth-child(4n+3),
-memory-allocations .collection-item :nth-child(4n+4) {
+.memory-allocations .collection-item :nth-child(2n+2).group,
+.memory-allocations .collection-item :nth-child(4n+3),
+.memory-allocations .collection-item :nth-child(4n+4) {
   background-color: #EEEEEE;
 }
 
-memory-allocations .collection-item:hover :nth-child(2n+2).group,
-memory-allocations .collection-item:hover :nth-child(4n+3),
-memory-allocations .collection-item:hover :nth-child(4n+4) {
+.memory-allocations .collection-item:hover :nth-child(2n+2).group,
+.memory-allocations .collection-item:hover :nth-child(4n+3),
+.memory-allocations .collection-item:hover :nth-child(4n+4) {
   background-color: #afd5fd;
 }
 
-memory-allocations .header .collection-item :nth-child(2n+1).group,
-memory-allocations .header .collection-item :nth-child(4n+1),
-memory-allocations .header .collection-item :nth-child(4n+2) {
+.memory-allocations .header .collection-item :nth-child(2n+1).group,
+.memory-allocations .header .collection-item :nth-child(4n+1),
+.memory-allocations .header .collection-item :nth-child(4n+2) {
   background-color: #FFFFFF;
 }
 
-memory-allocations .header .collection-item :nth-child(2n+2).group,
-memory-allocations .header .collection-item :nth-child(4n+3),
-memory-allocations .header .collection-item :nth-child(4n+4) {
+.memory-allocations .header .collection-item :nth-child(2n+2).group,
+.memory-allocations .header .collection-item :nth-child(4n+3),
+.memory-allocations .header .collection-item :nth-child(4n+4) {
   background-color: #DDDDDD;
 }
 
-memory-allocations .collection-item .group {
+.memory-allocations .collection-item .group {
   display: inline-block;
   width: 12em;
   text-align: right;
@@ -1825,7 +1825,7 @@
   border-right: solid 1px #AAAAAA;
 }
 
-memory-allocations .collection-item .bytes {
+.memory-allocations .collection-item .bytes {
   display: inline-block;
   width: 6em;
   text-align: right;
@@ -1833,7 +1833,7 @@
   padding-right: 0.5em;
 }
 
-memory-allocations .collection-item .instances {
+.memory-allocations .collection-item .instances {
   display: inline-block;
   width: 6em;
   text-align: right;
@@ -1842,16 +1842,16 @@
   border-right: solid 1px #AAAAAA;
 }
 
-memory-allocations .collection-item .name {
+.memory-allocations .collection-item .name {
   padding-left: 0.5em;
   padding-right: 0.5em;
   display: inline-block;
 }
 
-memory-allocations .collection-item > button,
-memory-allocations .collection-item > button:active,
-memory-allocations .collection-item .group button,
-memory-allocations .collection-item .group button:active {
+.memory-allocations .collection-item > button,
+.memory-allocations .collection-item > button:active,
+.memory-allocations .collection-item .group button,
+.memory-allocations .collection-item .group button:active {
   background: transparent;
   color: #0489c3;
   border: 0px none;
@@ -1859,8 +1859,8 @@
   padding: 0;
 }
 
-memory-allocations .collection-item > button:hover,
-memory-allocations .collection-item .group button:hover {
+.memory-allocations .collection-item > button:hover,
+.memory-allocations .collection-item .group button:hover {
   text-decoration: underline;
   border-radius: 0px;
 }
@@ -1868,15 +1868,15 @@
 
 /* memory-snapshot */
 
-memory-snapshot .statusMessage {
+.memory-snapshot .statusMessage {
   font-size: 150%;
   font-weight: bold;
 }
-memory-snapshot .statusBox {
+.memory-snapshot .statusBox {
   height: 100%;
   padding: 1em;
 }
-memory-snapshot .explanation {
+.memory-snapshot .explanation {
   display: block;
   display: -webkit-box;
   -webkit-line-clamp: 4;
@@ -1885,7 +1885,7 @@
   overflow: hidden;
   text-overflow: ellipsis;
 }
-memory-snapshot virtual-tree {
+.memory-snapshot .virtual-tree {
   position: absolute;
   height: auto;
   top: 50px;
@@ -1893,15 +1893,15 @@
   left: 0;
   right: 0;
 }
-memory-snapshot .tree-item {
+.memory-snapshot .tree-item {
   box-sizing: border-box;
   line-height: 30px;
   height: 30px;
   padding-left: 5%;
   padding-right: 5%;
 }
-memory-snapshot .tree-item > .size,
-memory-snapshot .tree-item > .percentage {
+.memory-snapshot .tree-item > .size,
+.memory-snapshot .tree-item > .percentage {
   display: inline-block;
   text-align: right;
   width: 4em;
@@ -1909,19 +1909,19 @@
   margin-right: 0.25em;
 }
 
-memory-snapshot .tree-item > .name {
+.memory-snapshot .tree-item > .name {
   display: inline;
   margin-left: 0.5em;
 }
 
 /* metric-graph */
 
-metrics-page > div {
+.metrics-page > div {
   display: block;
   height: 100%;
 }
 
-metrics-page > div > .graph {
+.metrics-page > div > .graph {
   display: block;
   height: 100%;
   margin-top: -300px;
@@ -1958,7 +1958,7 @@
   margin-right: 0.5em;
 }
 nav.nav-bar > ul *:first-child li.nav-menu:before,
-nav.nav-bar > ul nav-reload > li:before {
+nav.nav-bar > ul .nav-reload > li:before {
   content: '';
   margin-left: 0;
   margin-right: 0;
@@ -1997,21 +1997,21 @@
 
 /* nav-menu-item */
 
-nav-menu-item li.nav-menu-item {
+.nav-menu-item li.nav-menu-item {
   float: none;
   border-top: 1px solid #677;
   border-bottom: 1px solid #556; position: relative;
 }
-nav-menu-item li.nav-menu-item:hover {
+.nav-menu-item li.nav-menu-item:hover {
   background: #455;
 }
-nav-menu-item li.nav-menu-item > a {
+.nav-menu-item li.nav-menu-item > a {
   display: block;
   padding: 12px 12px;
   color: white;
   text-decoration: none;
 }
-nav-menu-item li.nav-menu-item > ul {
+.nav-menu-item li.nav-menu-item > ul {
   display: none;
   position: absolute;
   top:0;
@@ -2025,19 +2025,19 @@
   color: white;
   background: #567;
 }
-nav-menu-item li.nav-menu-item > ul:after {
+.nav-menu-item li.nav-menu-item > ul:after {
   content: ""; clear: both; display: block;
 }
-nav-menu-item li.nav-menu-item:hover > ul {
+.nav-menu-item li.nav-menu-item:hover > ul {
   display: block;
 }
 
 /* nav-notify */
 
-nav-notify > div {
+.nav-notify > div {
   float: right;
 }
-nav-notify > div > div {
+.nav-notify > div > div {
   display: block;
   position: absolute;
   top: 98%;
@@ -2051,7 +2051,7 @@
 
 /* nav-exception & nav-event */
 
-nav-exception > div, nav-event > div {
+.nav-exception > div, .nav-event > div {
   position: relative;
   padding: 16px;
   margin-top: 10px;
@@ -2066,28 +2066,28 @@
   animation: fadein 1s;
 }
 
-nav-exception *, nav-event * {
+.nav-exception *, .nav-event * {
   color: #ddd;
   font-size: 12px;
 }
 
-nav-exception > div > a[href],
-nav-event > div > a[href] {
+.nav-exception > div > a[href],
+.nav-event > div > a[href] {
   color: white;
   text-decoration: none;
 }
 
-nav-exception > div > a[href]:hover,
-nav-event > div > a[href]:hover {
+.nav-exception > div > a[href]:hover,
+.nav-event > div > a[href]:hover {
   text-decoration: underline;
 }
 
-nav-exception > div > div {
+.nav-exception > div > div {
   margin-left:20px;
   white-space: pre
 }
 
-nav-exception > div > button, nav-event > div > button {
+.nav-exception > div > button, .nav-event > div > button {
   background: transparent;
   border: none;
   position: absolute;
@@ -2104,13 +2104,13 @@
   text-align: center;
 }
 
-nav-exception > div > button:hover, nav-event > div > button:hover {
+.nav-exception > div > button:hover, .nav-event > div > button:hover {
   background: rgba(255,255,255,0.5);
 }
 
 /* nav-refresh */
 
-nav-refresh > li > button {
+.nav-refresh > li > button {
   color: #000;
   margin: 3px;
   padding: 8px;
@@ -2119,18 +2119,18 @@
   font-size: 13px;
   font: 400 'Montserrat', sans-serif;
 }
-nav-refresh > li > button[disabled] {
+.nav-refresh > li > button[disabled] {
   color: #aaa;
   cursor: wait;
 }
-nav-refresh > li {
+.nav-refresh > li {
   float: right;
   margin: 0;
 }
 
 /* nav-refresh */
 
-nav-reload > li > button {
+.nav-reload > li > button {
   color: #000;
   margin: 3px;
   padding: 8px;
@@ -2139,36 +2139,36 @@
   font-size: 13px;
   font: 400 'Montserrat', sans-serif;
 }
-nav-reload ul > li {
+.nav-reload ul > li {
   display: block;
   width: 100%;
   padding: 2px;
 }
-nav-reload ul > li > button {
+.nav-reload ul > li > button {
   display: inline-block;
   padding: 8px;
   width: 100%;
 }
-nav-reload > li > button[disabled],
-nav-reload ul > li > button[disabled] {
+.nav-reload > li > button[disabled],
+.nav-reload ul > li > button[disabled] {
   color: #aaa;
   cursor: wait;
 }
-nav-reload > li {
+.nav-reload > li {
   float: right;
   margin: 0;
 }
 
 /* object-common && class-instances */
 
-class-instances button:hover,
-object-common button:hover {
+.class-instances button:hover,
+.object-common button:hover {
   background-color: transparent;
   border: none;
   text-decoration: underline;
 }
-class-instances button,
-object-common button {
+.class-instances button,
+.object-common button {
   background-color: transparent;
   border: none;
   color: #0489c3;
@@ -2180,126 +2180,126 @@
 
 /* object-pool-ref */
 
-object-pool-ref > a[href]:hover {
+.object-pool-ref > a[href]:hover {
   text-decoration: underline;
 }
 
-object-pool-ref > a[href] {
+.object-pool-ref > a[href] {
   color: #0489c3;
   text-decoration: none;
 }
-object-pool-ref > a[href] * {
+.object-pool-ref > a[href] * {
   color: inherit;
 }
-object-pool-ref .emphasize {
+.object-pool-ref .emphasize {
   font-style: italic;
 }
 
 /* object-pool-view */
 
-object-pool-view .hexadecimal {
+.object-pool-view .hexadecimal {
   font-family: monospace;
 }
 
 /* observatory-application */
 
-observatory-application {
+.observatory-application {
   display: block;
   height: 100%;
 }
 
-observatory-application > div {
+.observatory-application > div {
   display: block;
   height: 100%;
 }
 
 /* persistent-handles-page */
 
-persistent-handles-page {
+.persistent-handles-page {
   display: block;
   height: 100%;
 }
-persistent-handles-page .persistent-handles,
-persistent-handles-page .weak-persistent-handles {
+.persistent-handles-page .persistent-handles,
+.persistent-handles-page .weak-persistent-handles {
   margin-top: -70px;
   padding-top: 70px;
   height: 50%;
 }
-persistent-handles-page .weak-item,
-persistent-handles-page .collection-item {
+.persistent-handles-page .weak-item,
+.persistent-handles-page .collection-item {
   box-sizing: border-box;
   line-height: 20px;
   padding-left: 5%;
   padding-right: 5%;
 }
-persistent-handles-page .header {
+.persistent-handles-page .header {
   box-sizing: border-box;
   line-height: 20px;
 }
-persistent-handles-page .header .weak-item:last-child {
+.persistent-handles-page .header .weak-item:last-child {
   margin-bottom: -3px;
   border-bottom: solid 1px #AAAAAA;
 }
-persistent-handles-page .weak-item .external-size,
-persistent-handles-page .weak-item .peer,
-persistent-handles-page .weak-item .object {
+.persistent-handles-page .weak-item .external-size,
+.persistent-handles-page .weak-item .peer,
+.persistent-handles-page .weak-item .object {
   display: inline-block;
   width: 7em;
   text-align: right;
   padding-right: 0.5em;
   line-height: 20px;
 }
-persistent-handles-page .weak-item .peer {
+.persistent-handles-page .weak-item .peer {
   width: 11em;
   font-family: monospace;
 }
-persistent-handles-page .weak-item .object {
+.persistent-handles-page .weak-item .object {
   text-align: left;
   width: 25em;
 }
-persistent-handles-page .buffer .weak-item:hover {
+.persistent-handles-page .buffer .weak-item:hover {
   background-color: #d2e7fe;
 }
-persistent-handles-page .weak-item .finalizer {
+.persistent-handles-page .weak-item .finalizer {
   padding-left: 0.5em;
 }
-persistent-handles-page .weak-item > button,
-persistent-handles-page .weak-item > button:active {
+.persistent-handles-page .weak-item > button,
+.persistent-handles-page .weak-item > button:active {
   background-color: transparent;
   color: #0489c3;
   border-style: none;
 }
-persistent-handles-page .weak-item > button:hover {
+.persistent-handles-page .weak-item > button:hover {
   text-decoration: underline;
 }
 
 /* ports-page */
 
-ports-page .port-number {
+.ports-page .port-number {
   font-weight: bold;
 }
 
 /* script-ref */
 
-script-ref > a[href]:hover {
+.script-ref > a[href]:hover {
   text-decoration: underline;
 }
-script-ref > a[href] {
+.script-ref > a[href] {
   color: #0489c3;
   text-decoration: none;
 }
-script-ref .emphasize {
+.script-ref .emphasize {
   font-style: italic;
 }
 
 
 /* source-link */
 
-source-link > a[href]:hover {
+.source-link > a[href]:hover {
     text-decoration: underline;
 }
 
-source-link > a[href] {
+.source-link > a[href] {
     color: #0489c3;
     text-decoration: none;
 }
@@ -2307,57 +2307,57 @@
 
 /* observatory-application */
 
-observatory-application {
+.observatory-application {
   display: block;
   height: 100%;
 }
 
-observatory-application > div {
+.observatory-application > div {
   display: block;
   height: 100%;
 }
 
 /* sample-buffer-control */
 
-sample-buffer-control {
+.sample-buffer-control {
   white-space: nowrap;
 }
 
-sample-buffer-control .statusMessage {
+.sample-buffer-control .statusMessage {
   font-size: 150%;
   font-weight: bold;
 }
 
-sample-buffer-control .statusBox {
+.sample-buffer-control .statusBox {
   height: 100%;
   padding: 1em;
 }
 
-sample-buffer-control .center {
+.sample-buffer-control .center {
   align-items: center;
   justify-content: center;
 }
 
-sample-buffer-control .notice {
+.sample-buffer-control .notice {
   background-color: #fcf8e3;
 }
 
-sample-buffer-control .red {
+.sample-buffer-control .red {
   background-color: #f2dede;
 }
 
-sample-buffer-control .shadow {
+.sample-buffer-control .shadow {
   box-shadow: 0 2px 10px 0 rgba(0, 0, 0, 0.16),
               0 2px 5px 0 rgba(0, 0, 0, 0.26);
 }
 
 /* script-inset */
 
-script-inset {
+.script-inset {
   position: relative;
 }
-script-inset button.refresh,
-script-inset button.toggle-profile {
+.script-inset button.refresh,
+.script-inset button.toggle-profile {
   background-color: transparent;
   padding: 0;
   margin: 0;
@@ -2366,29 +2366,29 @@
   display: inline-block;
   top: 5px;
 }
-script-inset button.refresh > svg,
-script-inset button.toggle-profile > svg {
+.script-inset button.refresh > svg,
+.script-inset button.toggle-profile > svg {
   fill: #888888;
 }
-script-inset button.refresh {
+.script-inset button.refresh {
   right: 5px;
 }
-script-inset button.toggle-profile {
+.script-inset button.toggle-profile {
   right: 30px;
 }
-script-inset button.toggle-profile.enabled > svg {
+.script-inset button.toggle-profile.enabled > svg {
   fill: #BB3322;
 }
-script-inset a {
+.script-inset a {
   color: #0489c3;
   text-decoration: none;
 }
-script-inset a:hover {
+.script-inset a:hover {
   text-decoration: underline;
 }
-script-inset .sourceInset {
+.script-inset .sourceInset {
 }
-script-inset .sourceTable {
+.script-inset .sourceTable {
   position: relative;
   background-color: #f5f5f5;
   border: 1px solid #ccc;
@@ -2397,31 +2397,31 @@
   box-sizing: border-box;
   overflow-x: scroll;
 }
-script-inset .sourceRow {
+.script-inset .sourceRow {
   display: flex;
   flex-direction: row;
   width: 100%;
 }
-script-inset .sourceItem,
-script-inset .sourceItemCurrent {
+.script-inset .sourceItem,
+.script-inset .sourceItemCurrent {
   vertical-align: top;
   font: 400 14px consolas, courier, monospace;
   line-height: 125%;
   white-space: pre;
   max-width: 0;
 }
-script-inset .currentLine {
+.script-inset .currentLine {
   background-color: #fff;
 }
-script-inset .currentCol {
+.script-inset .currentCol {
   background-color: #6cf;
 }
-script-inset .hitsCurrent,
-script-inset .hitsNone,
-script-inset .hitsNotExecuted,
-script-inset .hitsExecuted,
-script-inset .hitsCompiled,
-script-inset .hitsNotCompiled {
+.script-inset .hitsCurrent,
+.script-inset .hitsNone,
+.script-inset .hitsNotExecuted,
+.script-inset .hitsExecuted,
+.script-inset .hitsCompiled,
+.script-inset .hitsNotCompiled {
   display: table-cell;
   vertical-align: top;
   font: 400 14px consolas, courier, monospace;
@@ -2430,28 +2430,28 @@
   text-align: right;
   color: #a8a8a8;
 }
-script-inset .hitsCurrent {
+.script-inset .hitsCurrent {
   background-color: #6cf;
   color: black;
 }
-script-inset .hitsNotExecuted {
+.script-inset .hitsNotExecuted {
   background-color: #faa;
 }
-script-inset .hitsExecuted {
+.script-inset .hitsExecuted {
   background-color: #aea;
 }
-script-inset .hitsCompiled {
+.script-inset .hitsCompiled {
   background-color: #e0e0e0;
 }
-script-inset .hitsNotCompiled {
+.script-inset .hitsNotCompiled {
   background-color: #f0c5c5;
 }
-script-inset .noCopy {}
-script-inset .emptyBreakpoint,
-script-inset .possibleBreakpoint,
-script-inset .busyBreakpoint,
-script-inset .unresolvedBreakpoint,
-script-inset .resolvedBreakpoint  {
+.script-inset .noCopy {}
+.script-inset .emptyBreakpoint,
+.script-inset .possibleBreakpoint,
+.script-inset .busyBreakpoint,
+.script-inset .unresolvedBreakpoint,
+.script-inset .resolvedBreakpoint  {
   display: table-cell;
   vertical-align: top;
   font: 400 14px consolas, courier, monospace;
@@ -2459,39 +2459,39 @@
   text-align: center;
   cursor: pointer;
 }
-script-inset .possibleBreakpoint {
+.script-inset .possibleBreakpoint {
   color: #e0e0e0;
 }
-script-inset .possibleBreakpoint:hover {
+.script-inset .possibleBreakpoint:hover {
   color: white;
   background-color: #777;
 }
-script-inset .busyBreakpoint {
+.script-inset .busyBreakpoint {
   color: white;
   background-color: black;
   cursor: wait;
 }
-script-inset .unresolvedBreakpoint {
+.script-inset .unresolvedBreakpoint {
   color: white;
   background-color: #cac;
 }
-script-inset .resolvedBreakpoint {
+.script-inset .resolvedBreakpoint {
   color: white;
   background-color: #e66;
 }
-script-inset .unresolvedBreakAnnotation {
+.script-inset .unresolvedBreakAnnotation {
   color: white;
   background-color: #cac;
 }
-script-inset .resolvedBreakAnnotation {
+.script-inset .resolvedBreakAnnotation {
   color: white;
   background-color: #e66;
 }
-script-inset .notSourceProfile,
-script-inset .noProfile,
-script-inset .coldProfile,
-script-inset .mediumProfile,
-script-inset .hotProfile {
+.script-inset .notSourceProfile,
+.script-inset .noProfile,
+.script-inset .coldProfile,
+.script-inset .mediumProfile,
+.script-inset .hotProfile {
   display: table-cell;
   vertical-align: top;
   font: 400 14px consolas, courier, monospace;
@@ -2501,28 +2501,28 @@
   margin-left: 5px;
   margin-right: 5px;
 }
-script-inset .notSourceProfile {
+.script-inset .notSourceProfile {
 }
-script-inset .noProfile {
+.script-inset .noProfile {
   background-color: #e0e0e0;
 }
-script-inset .coldProfile {
+.script-inset .coldProfile {
   background-color: #aea;
 }
-script-inset .mediumProfile {
+.script-inset .mediumProfile {
   background-color: #fe9;
 }
-script-inset .hotProfile {
+.script-inset .hotProfile {
   background-color: #faa;
 }
 
 /* search-bar */
 
-search-bar {
+.search-bar {
   background: white;
   padding: 5px;
 }
-search-bar > input {
+.search-bar > input {
   width: 300px;
   line-height: 20px;
   border-color: #DDDDDD;
@@ -2530,11 +2530,11 @@
   padding-right: 2px;
 }
 
-search-bar button:enabled,
-search-bar button:enabled:hover,
-search-bar button:disabled,
-search-bar button:disabled:hover,
-search-bar button:active {
+.search-bar button:enabled,
+.search-bar button:enabled:hover,
+.search-bar button:disabled,
+.search-bar button:disabled:hover,
+.search-bar button:active {
   border: none;
   background: none;
   background-color: transparent;
@@ -2544,40 +2544,40 @@
   outline: none;
 }
 
-search-bar button:disabled,
-search-bar button:disabled:hover {
+.search-bar button:disabled,
+.search-bar button:disabled:hover {
   color: #DDDDDD;
 }
 
-search-bar button:enabled,
-search-bar button:enabled:active {
+.search-bar button:enabled,
+.search-bar button:enabled:active {
   color: #BBBBBB;
 }
 
-search-bar button:enabled:hover {
+.search-bar button:enabled:hover {
   color: #AAAAAA;
   text-shadow: 1px 1px 2px #dddddd;
 }
 
 /* stack-trace-tree-config */
 
-stack-trace-tree-config {
+.stack-trace-tree-config {
   white-space: nowrap;
 }
 
 /* timeline-dashboard */
 
-timeline-dashboard .iframe {
+.timeline-dashboard .iframe {
   position: absolute;
   top: 90px;
   bottom: 0;
   left: 0;
   right: 0;
 }
-timeline-dashboard h1 {
+.timeline-dashboard h1 {
   margin-bottom: 5px;
 }
-timeline-dashboard .iframe iframe {
+.timeline-dashboard .iframe iframe {
   width: 100%;
   height: 100%;
   border: none;
@@ -2585,13 +2585,13 @@
 
 /* timeline-page */
 
-timeline-page .iframe {
+.timeline-page .iframe {
   height: 100%;
   width: 100%;
   margin-top: -120px;
   padding-top: 120px;
 }
-timeline-page .iframe iframe {
+.timeline-page .iframe iframe {
   width: 100%;
   height: 100%;
   border: none;
@@ -2599,59 +2599,59 @@
 
 /* type-arguments-ref */
 
-type-arguments-ref a[href]:hover {
+.type-arguments-ref a[href]:hover {
   text-decoration: underline;
 }
-type-arguments-ref a[href] {
+.type-arguments-ref a[href] {
   color: #0489c3;
   text-decoration: none;
 }
-type-arguments-ref .emphasize {
+.type-arguments-ref .emphasize {
   font-style: italic;
 }
 
 
 /* token-stream-ref */
 
-token-stream-ref a[href]:hover {
+.token-stream-ref a[href]:hover {
   text-decoration: underline;
 }
-token-stream-ref a[href] {
+.token-stream-ref a[href] {
   color: #0489c3;
   text-decoration: none;
 }
-token-stream-ref .emphasize {
+.token-stream-ref .emphasize {
   font-style: italic;
 }
 
 
 /* unknown-ref */
 
-unknown-ref > a[href]:hover {
+.unknown-ref > a[href]:hover {
   text-decoration: underline;
 }
-unknown-ref > a[href] {
+.unknown-ref > a[href] {
   color: #0489c3;
   text-decoration: none;
 }
-unknown-ref > a[href] * {
+.unknown-ref > a[href] * {
   color: inherit;
 }
-unknown-ref .emphasize {
+.unknown-ref .emphasize {
   font-style: italic;
 }
 
 
 /* view-footer */
 
-view-footer {
+.view-footer {
   padding: 1em;
   padding-top: 10.3em;
   float: right;
   align-content: right;
 }
 
-view-footer > a {
+.view-footer > a {
   margin-bottom: 0.17em;
   font-size: 90%;
   float: right;
@@ -2661,7 +2661,7 @@
 
 /* virtual-collection */
 
-virtual-collection {
+.virtual-collection {
   position: relative;
   display: block;
   overflow-x: hidden;
@@ -2669,7 +2669,7 @@
   height: 100%;
 }
 
-virtual-collection .viewport {
+.virtual-collection .viewport {
   position: absolute;
   display: block;
   overflow-y: auto;
@@ -2680,14 +2680,14 @@
   left: 0;
 }
 
-virtual-collection .header {
+.virtual-collection .header {
   background: white;
   position: relative;
   display: block;
   z-index: +1;
 }
 
-virtual-collection search-bar {
+.virtual-collection .search-bar {
   position: relative;
   display: block;
   z-index: +1;
@@ -2699,45 +2699,45 @@
   box-shadow: 0px 1px 2px #AAAAAA;
 }
 
-virtual-collection .spacer {
+.virtual-collection .spacer {
   overflow: hidden;
   background: transparent;
   display: inline-block;
   min-width: 100%;
 }
 
-virtual-collection .buffer {
+.virtual-collection .buffer {
   background: transparent;
   position: relative;
   display: inline-block;
   min-width: 100%;
 }
 
-virtual-collection .header > div,
-virtual-collection .buffer > div {
+.virtual-collection .header > div,
+.virtual-collection .buffer > div {
   white-space: nowrap;
 }
 
-virtual-collection .header.attached > div,
-virtual-collection .buffer > div {
+.virtual-collection .header.attached > div,
+.virtual-collection .buffer > div {
   display: inline-block;
 }
 
-virtual-collection .buffer > div {
+.virtual-collection .buffer > div {
   min-width: 100%;
   white-space: nowrap;
 }
 
-virtual-collection .marked,
-virtual-collection .marked * {
+.virtual-collection .marked,
+.virtual-collection .marked * {
   background: yellow !important;
 }
 
 /* virtual-tree */
 
-virtual-tree .expander,
-virtual-tree .expander:hover,
-virtual-tree .expander:active {
+.virtual-tree .expander,
+.virtual-tree .expander:hover,
+.virtual-tree .expander:active {
   display: inline-block;
   text-align: center;
   font-weight: bold;
@@ -2748,74 +2748,74 @@
   padding: 0;
 }
 
-virtual-tree .expander:focus {
+.virtual-tree .expander:focus {
   outline: none;
 }
 
-virtual-tree .lines,
-virtual-tree .lines > span {
+.virtual-tree .lines,
+.virtual-tree .lines > span {
   display: inline-block;
   vertical-align: top;
   height: 100%;
   line-height: 100%;
 }
 
-virtual-tree .lines:before,
-virtual-tree .lines > span:before {
+.virtual-tree .lines:before,
+.virtual-tree .lines > span:before {
   display: inline-block;
   content: '';
 }
 
-virtual-tree .lines > span {
+.virtual-tree .lines > span {
   width: 3px;
   margin-left: 8px;
   margin-right: 8px;
 }
 
-virtual-tree .lines > span:nth-child(5n) {
+.virtual-tree .lines > span:nth-child(5n) {
   background-color: #673AB7;
 }
 
-virtual-tree .lines > span:nth-child(5n+1) {
+.virtual-tree .lines > span:nth-child(5n+1) {
   background-color: #F44336;
 }
 
-virtual-tree .lines > span:nth-child(5n+2) {
+.virtual-tree .lines > span:nth-child(5n+2) {
   background-color: #4CAF50;
 }
 
-virtual-tree .lines > span:nth-child(5n+3) {
+.virtual-tree .lines > span:nth-child(5n+3) {
   background-color: #3F51B5;
 }
 
-virtual-tree .lines > span:nth-child(5n+4) {
+.virtual-tree .lines > span:nth-child(5n+4) {
   background-color: #FF9800;
 }
 
 /* vm-connect-target */
 
-vm-connect-target > a {
+.vm-connect-target > a {
   color: #0489c3;
   text-decoration: none;
 }
 
-vm-connect-target > a:hover {
+.vm-connect-target > a:hover {
   text-decoration: underline;
 }
 
-vm-connect-target > button.delete-button {
+.vm-connect-target > button.delete-button {
   margin-left: 0.28em;
   padding: 4px;
   background: transparent;
   border: none !important;
 }
 
-vm-connect-target > button.delete-button:hover {
+.vm-connect-target > button.delete-button:hover {
   background: #ff0000;
 }
 
 /* vm-connect */
 
-vm-connect ul {
+.vm-connect ul {
   list-style-type: none;
 }
diff --git a/runtime/observatory/lib/src/elements/curly_block.dart b/runtime/observatory/lib/src/elements/curly_block.dart
index 3d88727..7bb7084 100644
--- a/runtime/observatory/lib/src/elements/curly_block.dart
+++ b/runtime/observatory/lib/src/elements/curly_block.dart
@@ -15,7 +15,7 @@
   CurlyBlockToggleEvent(this.control);
 }
 
-class CurlyBlockElement extends HtmlElement implements Renderable {
+class CurlyBlockElement extends CustomElement implements Renderable {
   static const tag = const Tag<CurlyBlockElement>('curly-block');
 
   RenderingScheduler<CurlyBlockElement> _r;
@@ -48,14 +48,14 @@
       {bool expanded: false, bool disabled: false, RenderingQueue queue}) {
     assert(expanded != null);
     assert(disabled != null);
-    CurlyBlockElement e = document.createElement(tag.name);
+    CurlyBlockElement e = new CurlyBlockElement.created();
     e._r = new RenderingScheduler<CurlyBlockElement>(e, queue: queue);
     e._expanded = expanded;
     e._disabled = disabled;
     return e;
   }
 
-  CurlyBlockElement.created() : super.created();
+  CurlyBlockElement.created() : super.created(tag);
 
   @override
   void attached() {
diff --git a/runtime/observatory/lib/src/elements/debugger.dart b/runtime/observatory/lib/src/elements/debugger.dart
index 053bab8..6355605 100644
--- a/runtime/observatory/lib/src/elements/debugger.dart
+++ b/runtime/observatory/lib/src/elements/debugger.dart
@@ -36,7 +36,8 @@
 abstract class DebuggerCommand extends Command {
   ObservatoryDebugger debugger;
 
-  DebuggerCommand(this.debugger, name, List<Command> children) : super(name, children);
+  DebuggerCommand(this.debugger, name, List<Command> children)
+      : super(name, children);
 
   String get helpShort;
   String get helpLong;
@@ -129,7 +130,8 @@
 }
 
 class HelpHotkeysCommand extends DebuggerCommand {
-  HelpHotkeysCommand(Debugger debugger) : super(debugger, 'hotkeys', <Command>[]);
+  HelpHotkeysCommand(Debugger debugger)
+      : super(debugger, 'hotkeys', <Command>[]);
 
   Future run(List<String> args) {
     var con = debugger.console;
@@ -213,7 +215,8 @@
       debugger.downFrame(count);
       debugger.console.print('frame = ${debugger.currentFrame}');
     } catch (e) {
-      debugger.console.print('frame must be in range [${e.start}..${e.end-1}]');
+      debugger.console
+          .print('frame must be in range [${e.start}..${e.end - 1}]');
     }
     return new Future.value(null);
   }
@@ -247,7 +250,8 @@
       debugger.upFrame(count);
       debugger.console.print('frame = ${debugger.currentFrame}');
     } on RangeError catch (e) {
-      debugger.console.print('frame must be in range [${e.start}..${e.end-1}]');
+      debugger.console
+          .print('frame must be in range [${e.start}..${e.end - 1}]');
     }
     return new Future.value(null);
   }
@@ -283,7 +287,8 @@
       debugger.currentFrame = frame;
       debugger.console.print('frame = ${debugger.currentFrame}');
     } on RangeError catch (e) {
-      debugger.console.print('frame must be in range [${e.start}..${e.end-1}]');
+      debugger.console
+          .print('frame must be in range [${e.start}..${e.end - 1}]');
     }
     return new Future.value(null);
   }
@@ -313,7 +318,8 @@
 }
 
 class ContinueCommand extends DebuggerCommand {
-  ContinueCommand(Debugger debugger) : super(debugger, 'continue', <Command>[]) {
+  ContinueCommand(Debugger debugger)
+      : super(debugger, 'continue', <Command>[]) {
     alias = 'c';
   }
 
@@ -354,7 +360,8 @@
 }
 
 class SyncNextCommand extends DebuggerCommand {
-  SyncNextCommand(Debugger debugger) : super(debugger, 'next-sync', <Command>[]);
+  SyncNextCommand(Debugger debugger)
+      : super(debugger, 'next-sync', <Command>[]);
 
   Future run(List<String> args) {
     return debugger.syncNext();
@@ -370,7 +377,8 @@
 }
 
 class AsyncNextCommand extends DebuggerCommand {
-  AsyncNextCommand(Debugger debugger) : super(debugger, 'next-async', <Command>[]);
+  AsyncNextCommand(Debugger debugger)
+      : super(debugger, 'next-async', <Command>[]);
 
   Future run(List<String> args) {
     return debugger.asyncNext();
@@ -1162,7 +1170,8 @@
 }
 
 class RefreshStackCommand extends DebuggerCommand {
-  RefreshStackCommand(Debugger debugger) : super(debugger, 'stack', <Command>[]);
+  RefreshStackCommand(Debugger debugger)
+      : super(debugger, 'stack', <Command>[]);
 
   Future run(List<String> args) {
     return debugger.refreshStack();
@@ -2001,7 +2010,7 @@
   }
 }
 
-class DebuggerPageElement extends HtmlElement implements Renderable {
+class DebuggerPageElement extends CustomElement implements Renderable {
   static const tag =
       const Tag<DebuggerPageElement>('debugger-page', dependencies: const [
     NavTopMenuElement.tag,
@@ -2022,7 +2031,7 @@
     assert(objects != null);
     assert(scripts != null);
     assert(events != null);
-    final DebuggerPageElement e = document.createElement(tag.name);
+    final DebuggerPageElement e = new DebuggerPageElement.created();
     final debugger = new ObservatoryDebugger(isolate);
     debugger.page = e;
     debugger.objects = objects;
@@ -2034,7 +2043,7 @@
     return e;
   }
 
-  DebuggerPageElement.created() : super.created();
+  DebuggerPageElement.created() : super.created(tag);
 
   Future<StreamSubscription> _vmSubscriptionFuture;
   Future<StreamSubscription> _isolateSubscriptionFuture;
@@ -2056,23 +2065,25 @@
     final stackDiv = new DivElement()..classes = ['stack'];
     final stackElement = new DebuggerStackElement(
         _isolate, _debugger, stackDiv, _objects, _scripts, _events);
-    stackDiv.children = <Element>[stackElement];
+    stackDiv.children = <Element>[stackElement.element];
     final consoleDiv = new DivElement()
       ..classes = ['console']
-      ..children = <Element>[consoleElement];
+      ..children = <Element>[consoleElement.element];
     final commandElement = new DebuggerInputElement(_isolate, _debugger);
     final commandDiv = new DivElement()
       ..classes = ['commandline']
-      ..children = <Element>[commandElement];
+      ..children = <Element>[commandElement.element];
 
     children = <Element>[
       navBar(<Element>[
-        new NavTopMenuElement(queue: app.queue),
-        new NavVMMenuElement(app.vm, app.events, queue: app.queue),
-        new NavIsolateMenuElement(_isolate, app.events, queue: app.queue),
+        new NavTopMenuElement(queue: app.queue).element,
+        new NavVMMenuElement(app.vm, app.events, queue: app.queue).element,
+        new NavIsolateMenuElement(_isolate, app.events, queue: app.queue)
+            .element,
         navMenu('debugger'),
         new NavNotifyElement(app.notifications,
-            notifyOnPause: false, queue: app.queue)
+                notifyOnPause: false, queue: app.queue)
+            .element
       ]),
       new DivElement()
         ..classes = ['variable']
@@ -2163,7 +2174,7 @@
   }
 }
 
-class DebuggerStackElement extends HtmlElement implements Renderable {
+class DebuggerStackElement extends CustomElement implements Renderable {
   static const tag = const Tag<DebuggerStackElement>('debugger-stack');
 
   S.Isolate _isolate;
@@ -2213,7 +2224,7 @@
     assert(objects != null);
     assert(scripts != null);
     assert(events != null);
-    final DebuggerStackElement e = document.createElement(tag.name);
+    final DebuggerStackElement e = new DebuggerStackElement.created();
     e._isolate = isolate;
     e._debugger = debugger;
     e._scroller = scroller;
@@ -2286,7 +2297,7 @@
 
     var li = new LIElement();
     li.classes.add('list-group-item');
-    li.children.insert(0, frameElement);
+    li.children.insert(0, frameElement.element);
 
     frameList.insert(0, li);
   }
@@ -2298,7 +2309,7 @@
 
     var li = new LIElement();
     li.classes.add('list-group-item');
-    li.children.insert(0, messageElement);
+    li.children.insert(0, messageElement.element);
 
     messageList.add(li);
   }
@@ -2323,7 +2334,9 @@
     int oldPos = frameElements.length - 1;
     int newPos = newFrames.length - 1;
     while (oldPos >= 0 && newPos >= 0) {
-      if (!frameElements[oldPos].children[0].matchFrame(newFrames[newPos])) {
+      DebuggerFrameElement dbgFrameElement =
+          CustomElement.reverse(frameElements[oldPos].children[0]);
+      if (!dbgFrameElement.matchFrame(newFrames[newPos])) {
         // The rest of the frame elements no longer match.  Remove them.
         for (int i = 0; i <= oldPos; i++) {
           // NOTE(turnidge): removeRange is missing, sadly.
@@ -2357,7 +2370,9 @@
 
     if (frameElements.isNotEmpty) {
       for (int i = newCount; i < frameElements.length; i++) {
-        frameElements[i].children[0].updateFrame(newFrames[i]);
+        DebuggerFrameElement dbgFrameElement =
+            CustomElement.reverse(frameElements[i].children[0]);
+        dbgFrameElement.updateFrame(newFrames[i]);
       }
     }
 
@@ -2389,7 +2404,8 @@
     if (messageElements.isNotEmpty) {
       // Update old messages.
       for (int i = 0; i < newStartingIndex; i++) {
-        DebuggerMessageElement e = messageElements[i].children[0];
+        DebuggerMessageElement e =
+            CustomElement.reverse(messageElements[i].children[0]);
         e.updateMessage(newMessages[i]);
       }
     }
@@ -2407,7 +2423,8 @@
     currentFrame = value;
     List frameElements = _frameList.children;
     for (var frameElement in frameElements) {
-      DebuggerFrameElement dbgFrameElement = frameElement.children[0];
+      DebuggerFrameElement dbgFrameElement =
+          CustomElement.reverse(frameElement.children[0]);
       if (dbgFrameElement.frame.index == currentFrame) {
         dbgFrameElement.setCurrent(true);
       } else {
@@ -2416,10 +2433,10 @@
     }
   }
 
-  DebuggerStackElement.created() : super.created();
+  DebuggerStackElement.created() : super.created(tag);
 }
 
-class DebuggerFrameElement extends HtmlElement implements Renderable {
+class DebuggerFrameElement extends CustomElement implements Renderable {
   static const tag = const Tag<DebuggerFrameElement>('debugger-frame');
 
   RenderingScheduler<DebuggerFrameElement> _r;
@@ -2476,7 +2493,7 @@
     assert(objects != null);
     assert(scripts != null);
     assert(events != null);
-    final DebuggerFrameElement e = document.createElement(tag.name);
+    final DebuggerFrameElement e = new DebuggerFrameElement.created();
     e._r = new RenderingScheduler<DebuggerFrameElement>(e, queue: queue);
     e._isolate = isolate;
     e._frame = frame;
@@ -2487,7 +2504,7 @@
     return e;
   }
 
-  DebuggerFrameElement.created() : super.created();
+  DebuggerFrameElement.created() : super.created(tag);
 
   void render() {
     if (_pinned) {
@@ -2545,16 +2562,17 @@
                   ..children = _frame.function?.location == null
                       ? const []
                       : [
-                          new SourceInsetElement(
-                              _isolate,
-                              _frame.function.location,
-                              _scripts,
-                              _objects,
-                              _events,
-                              currentPos: _frame.location.tokenPos,
-                              variables: _frame.variables,
-                              inDebuggerContext: true,
-                              queue: _r.queue)
+                          (new SourceInsetElement(
+                                  _isolate,
+                                  _frame.function.location,
+                                  _scripts,
+                                  _objects,
+                                  _events,
+                                  currentPos: _frame.location.tokenPos,
+                                  variables: _frame.variables,
+                                  inDebuggerContext: true,
+                                  queue: _r.queue))
+                              .element
                         ],
                 new DivElement()
                   ..classes = ['flex-item-vars']
@@ -2643,7 +2661,8 @@
                 ? const []
                 : [
                     new FunctionRefElement(_isolate, _frame.function,
-                        queue: _r.queue)
+                            queue: _r.queue)
+                        .element
                   ],
           new SpanElement()..text = ' ( ',
           new SpanElement()
@@ -2651,8 +2670,9 @@
                 ? const []
                 : [
                     new SourceLinkElement(
-                        _isolate, _frame.function.location, _scripts,
-                        queue: _r.queue)
+                            _isolate, _frame.function.location, _scripts,
+                            queue: _r.queue)
+                        .element
                   ],
           new SpanElement()..text = ' )'
         ]
@@ -2778,7 +2798,7 @@
   }
 }
 
-class DebuggerMessageElement extends HtmlElement implements Renderable {
+class DebuggerMessageElement extends CustomElement implements Renderable {
   static const tag = const Tag<DebuggerMessageElement>('debugger-message');
 
   RenderingScheduler<DebuggerMessageElement> _r;
@@ -2811,7 +2831,7 @@
     assert(message != null);
     assert(objects != null);
     assert(events != null);
-    final DebuggerMessageElement e = document.createElement(tag.name);
+    final DebuggerMessageElement e = new DebuggerMessageElement.created();
     e._r = new RenderingScheduler<DebuggerMessageElement>(e, queue: queue);
     e._isolate = isolate;
     e._message = message;
@@ -2821,7 +2841,7 @@
     return e;
   }
 
-  DebuggerMessageElement.created() : super.created();
+  DebuggerMessageElement.created() : super.created(tag);
 
   void render() {
     if (_pinned) {
@@ -2863,13 +2883,14 @@
                       ? const []
                       : [
                           new SourceInsetElement(
-                              _isolate,
-                              _message.handler.location,
-                              _scripts,
-                              _objects,
-                              _events,
-                              inDebuggerContext: true,
-                              queue: _r.queue)
+                                  _isolate,
+                                  _message.handler.location,
+                                  _scripts,
+                                  _objects,
+                                  _events,
+                                  inDebuggerContext: true,
+                                  queue: _r.queue)
+                              .element
                         ],
                 new DivElement()
                   ..classes = ['flex-item-vars']
@@ -2931,7 +2952,8 @@
                 ? const []
                 : [
                     new FunctionRefElement(_isolate, _message.handler,
-                        queue: _r.queue)
+                            queue: _r.queue)
+                        .element
                   ],
           new SpanElement()..text = ' ( ',
           new SpanElement()
@@ -2939,7 +2961,8 @@
                 ? const []
                 : [
                     new SourceLinkElement(_isolate, _message.location, _scripts,
-                        queue: _r.queue)
+                            queue: _r.queue)
+                        .element
                   ],
           new SpanElement()..text = ' )'
         ]
@@ -2998,16 +3021,16 @@
   }
 }
 
-class DebuggerConsoleElement extends HtmlElement implements Renderable {
+class DebuggerConsoleElement extends CustomElement implements Renderable {
   static const tag = const Tag<DebuggerConsoleElement>('debugger-console');
 
   factory DebuggerConsoleElement() {
-    final DebuggerConsoleElement e = document.createElement(tag.name);
+    final DebuggerConsoleElement e = new DebuggerConsoleElement.created();
     e.children = <Element>[new BRElement()];
     return e;
   }
 
-  DebuggerConsoleElement.created() : super.created();
+  DebuggerConsoleElement.created() : super.created(tag);
 
   /// Is [container] scrolled to the within [threshold] pixels of the bottom?
   static bool _isScrolledToBottom(DivElement container, [int threshold = 2]) {
@@ -3086,7 +3109,8 @@
 
   void printRef(S.Isolate isolate, S.Instance ref, M.ObjectRepository objects,
       {bool newline: true}) {
-    _append(new InstanceRefElement(isolate, ref, objects, queue: app.queue));
+    _append(new InstanceRefElement(isolate, ref, objects, queue: app.queue)
+        .element);
     if (newline) {
       this.newline();
     }
@@ -3107,7 +3131,7 @@
   ObservatoryApplication get app => ObservatoryApplication.app;
 }
 
-class DebuggerInputElement extends HtmlElement implements Renderable {
+class DebuggerInputElement extends CustomElement implements Renderable {
   static const tag = const Tag<DebuggerInputElement>('debugger-input');
 
   S.Isolate _isolate;
@@ -3134,14 +3158,14 @@
 
   factory DebuggerInputElement(
       S.Isolate isolate, ObservatoryDebugger debugger) {
-    final DebuggerInputElement e = document.createElement(tag.name);
+    final DebuggerInputElement e = new DebuggerInputElement.created();
     e.children = <Element>[e._modalPromptDiv, e._textBox];
     e._textBox.select();
     e._textBox.onKeyDown.listen(e._onKeyDown);
     return e;
   }
 
-  DebuggerInputElement.created() : super.created();
+  DebuggerInputElement.created() : super.created(tag);
 
   void _onKeyDown(KeyboardEvent e) {
     if (_busy) {
@@ -3321,9 +3345,9 @@
       ..setAttribute(
           'd',
           'M6 10c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 '
-          '2-2-.9-2-2-2zm12 0c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 '
-          '2-2-.9-2-2-2zm-6 0c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 '
-          '2-2-.9-2-2-2z')
+              '2-2-.9-2-2-2zm12 0c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 '
+              '2-2-.9-2-2-2zm-6 0c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 '
+              '2-2-.9-2-2-2z')
   ];
 
 final SvgSvgElement iconVerticalThreeDot = new SvgSvgElement()
@@ -3334,9 +3358,9 @@
       ..setAttribute(
           'd',
           'M12 8c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 '
-          '2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 '
-          '2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 '
-          '2-.9 2-2-.9-2-2-2z')
+              '2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 '
+              '2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 '
+              '2-.9 2-2-.9-2-2-2z')
   ];
 
 final SvgSvgElement iconInfo = new SvgSvgElement()
@@ -3347,7 +3371,7 @@
       ..setAttribute(
           'd',
           'M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 '
-          '10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z')
+              '10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z')
   ];
 
 final SvgSvgElement iconInfoOutline = new SvgSvgElement()
@@ -3358,7 +3382,7 @@
       ..setAttribute(
           'd',
           'M11 17h2v-6h-2v6zm1-15C6.48 2 2 6.48 2 12s4.48 10 '
-          '10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 '
-          '0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zM11 '
-          '9h2V7h-2v2z')
+              '10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 '
+              '0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zM11 '
+              '9h2V7h-2v2z')
   ];
diff --git a/runtime/observatory/lib/src/elements/error_ref.dart b/runtime/observatory/lib/src/elements/error_ref.dart
index ef7f04a..2e25096 100644
--- a/runtime/observatory/lib/src/elements/error_ref.dart
+++ b/runtime/observatory/lib/src/elements/error_ref.dart
@@ -10,7 +10,7 @@
 import 'package:observatory/src/elements/helpers/tag.dart';
 import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
 
-class ErrorRefElement extends HtmlElement implements Renderable {
+class ErrorRefElement extends CustomElement implements Renderable {
   static const tag = const Tag<ErrorRefElement>('error-ref');
 
   RenderingScheduler<ErrorRefElement> _r;
@@ -23,13 +23,13 @@
 
   factory ErrorRefElement(ErrorRef error, {RenderingQueue queue}) {
     assert(error != null);
-    ErrorRefElement e = document.createElement(tag.name);
+    ErrorRefElement e = new ErrorRefElement.created();
     e._r = new RenderingScheduler<ErrorRefElement>(e, queue: queue);
     e._error = error;
     return e;
   }
 
-  ErrorRefElement.created() : super.created();
+  ErrorRefElement.created() : super.created(tag);
 
   @override
   void attached() {
diff --git a/runtime/observatory/lib/src/elements/error_view.dart b/runtime/observatory/lib/src/elements/error_view.dart
index 0d1d9b8..010f4cc 100644
--- a/runtime/observatory/lib/src/elements/error_view.dart
+++ b/runtime/observatory/lib/src/elements/error_view.dart
@@ -14,7 +14,7 @@
 import 'package:observatory/src/elements/nav/top_menu.dart';
 import 'package:observatory/src/elements/view_footer.dart';
 
-class ErrorViewElement extends HtmlElement implements Renderable {
+class ErrorViewElement extends CustomElement implements Renderable {
   static const tag = const Tag<ErrorViewElement>('error-view',
       dependencies: const [
         NavTopMenuElement.tag,
@@ -36,14 +36,14 @@
       {RenderingQueue queue}) {
     assert(error != null);
     assert(notifications != null);
-    ErrorViewElement e = document.createElement(tag.name);
+    ErrorViewElement e = new ErrorViewElement.created();
     e._r = new RenderingScheduler<ErrorViewElement>(e, queue: queue);
     e._error = error;
     e._notifications = notifications;
     return e;
   }
 
-  ErrorViewElement.created() : super.created();
+  ErrorViewElement.created() : super.created(tag);
 
   @override
   void attached() {
@@ -61,8 +61,8 @@
   void render() {
     children = <Element>[
       navBar(<Element>[
-        new NavTopMenuElement(queue: _r.queue),
-        new NavNotifyElement(_notifications, queue: _r.queue)
+        new NavTopMenuElement(queue: _r.queue).element,
+        new NavNotifyElement(_notifications, queue: _r.queue).element
       ]),
       new DivElement()
         ..classes = ['content-centered']
@@ -74,7 +74,7 @@
             ..classes = ['well']
             ..children = <Element>[new PreElement()..text = error.message]
         ],
-      new ViewFooterElement(queue: _r.queue)
+      new ViewFooterElement(queue: _r.queue).element
     ];
   }
 
diff --git a/runtime/observatory/lib/src/elements/eval_box.dart b/runtime/observatory/lib/src/elements/eval_box.dart
index 0bf7b0c..db8ce82 100644
--- a/runtime/observatory/lib/src/elements/eval_box.dart
+++ b/runtime/observatory/lib/src/elements/eval_box.dart
@@ -12,7 +12,7 @@
 import 'package:observatory/src/elements/helpers/tag.dart';
 import 'package:observatory/src/elements/instance_ref.dart';
 
-class EvalBoxElement extends HtmlElement implements Renderable {
+class EvalBoxElement extends CustomElement implements Renderable {
   static const tag = const Tag<EvalBoxElement>('eval-box',
       dependencies: const [InstanceRefElement.tag]);
 
@@ -43,7 +43,7 @@
     assert(eval != null);
     assert(multiline != null);
     assert(quickExpressions != null);
-    EvalBoxElement e = document.createElement(tag.name);
+    EvalBoxElement e = new EvalBoxElement.created();
     e._r = new RenderingScheduler<EvalBoxElement>(e, queue: queue);
     e._isolate = isolate;
     e._context = context;
@@ -54,7 +54,7 @@
     return e;
   }
 
-  EvalBoxElement.created() : super.created();
+  EvalBoxElement.created() : super.created(tag);
 
   @override
   void attached() {
diff --git a/runtime/observatory/lib/src/elements/field_ref.dart b/runtime/observatory/lib/src/elements/field_ref.dart
index ab4f170..8074d44 100644
--- a/runtime/observatory/lib/src/elements/field_ref.dart
+++ b/runtime/observatory/lib/src/elements/field_ref.dart
@@ -10,7 +10,7 @@
 import 'package:observatory/src/elements/helpers/uris.dart';
 import 'package:observatory/src/elements/instance_ref.dart';
 
-class FieldRefElement extends HtmlElement implements Renderable {
+class FieldRefElement extends CustomElement implements Renderable {
   static const tag = const Tag<FieldRefElement>('field-ref',
       dependencies: const [InstanceRefElement.tag]);
 
@@ -32,7 +32,7 @@
     assert(isolate != null);
     assert(field != null);
     assert(objects != null);
-    FieldRefElement e = document.createElement(tag.name);
+    FieldRefElement e = new FieldRefElement.created();
     e._r = new RenderingScheduler<FieldRefElement>(e, queue: queue);
     e._isolate = isolate;
     e._field = field;
@@ -41,7 +41,7 @@
     return e;
   }
 
-  FieldRefElement.created() : super.created();
+  FieldRefElement.created() : super.created(tag);
 
   @override
   void attached() {
@@ -82,7 +82,8 @@
       children = <Element>[
         new SpanElement()..text = header,
         new InstanceRefElement(_isolate, _field.declaredType, _objects,
-            queue: _r.queue, expandable: _expandable),
+                queue: _r.queue, expandable: _expandable)
+            .element,
         new SpanElement()..text = ' ',
         new AnchorElement(href: Uris.inspect(_isolate, object: _field))
           ..text = _field.name
diff --git a/runtime/observatory/lib/src/elements/field_view.dart b/runtime/observatory/lib/src/elements/field_view.dart
index 27422a4..30b5c7c 100644
--- a/runtime/observatory/lib/src/elements/field_view.dart
+++ b/runtime/observatory/lib/src/elements/field_view.dart
@@ -26,7 +26,7 @@
 import 'package:observatory/src/elements/source_link.dart';
 import 'package:observatory/src/elements/view_footer.dart';
 
-class FieldViewElement extends HtmlElement implements Renderable {
+class FieldViewElement extends CustomElement implements Renderable {
   static const tag =
       const Tag<FieldViewElement>('field-view', dependencies: const [
     ClassRefElement.tag,
@@ -96,7 +96,7 @@
     assert(retainingPaths != null);
     assert(scripts != null);
     assert(objects != null);
-    FieldViewElement e = document.createElement(tag.name);
+    FieldViewElement e = new FieldViewElement.created();
     e._r = new RenderingScheduler<FieldViewElement>(e, queue: queue);
     e._vm = vm;
     e._isolate = isolate;
@@ -117,7 +117,7 @@
     return e;
   }
 
-  FieldViewElement.created() : super.created();
+  FieldViewElement.created() : super.created(tag);
 
   @override
   attached() {
@@ -160,8 +160,9 @@
           new HeadingElement.h2()..text = '$header ${field.name}',
           new HRElement(),
           new ObjectCommonElement(_isolate, _field, _retainedSizes,
-              _reachableSizes, _references, _retainingPaths, _objects,
-              queue: _r.queue),
+                  _reachableSizes, _references, _retainingPaths, _objects,
+                  queue: _r.queue)
+              .element,
           new BRElement(),
           new DivElement()
             ..classes = ['memberList']
@@ -172,36 +173,40 @@
                 ? const []
                 : [
                     new ScriptInsetElement(_isolate, _field.location.script,
-                        _scripts, _objects, _events,
-                        startPos: field.location.tokenPos,
-                        endPos: field.location.tokenPos,
-                        queue: _r.queue)
+                            _scripts, _objects, _events,
+                            startPos: field.location.tokenPos,
+                            endPos: field.location.tokenPos,
+                            queue: _r.queue)
+                        .element
                   ],
-          new ViewFooterElement(queue: _r.queue)
+          new ViewFooterElement(queue: _r.queue).element
         ]
     ];
   }
 
   List<Element> _createMenu() {
     final menu = <Element>[
-      new NavTopMenuElement(queue: _r.queue),
-      new NavVMMenuElement(_vm, _events, queue: _r.queue),
-      new NavIsolateMenuElement(_isolate, _events, queue: _r.queue)
+      new NavTopMenuElement(queue: _r.queue).element,
+      new NavVMMenuElement(_vm, _events, queue: _r.queue).element,
+      new NavIsolateMenuElement(_isolate, _events, queue: _r.queue).element
     ];
     if (_library != null) {
-      menu.add(new NavLibraryMenuElement(_isolate, _library, queue: _r.queue));
+      menu.add(new NavLibraryMenuElement(_isolate, _library, queue: _r.queue)
+          .element);
     } else if (_field.dartOwner is M.ClassRef) {
       menu.add(
-          new NavClassMenuElement(_isolate, _field.dartOwner, queue: _r.queue));
+          new NavClassMenuElement(_isolate, _field.dartOwner, queue: _r.queue)
+              .element);
     }
     menu.addAll(<Element>[
       navMenu(_field.name),
-      new NavRefreshElement(queue: _r.queue)
-        ..onRefresh.listen((e) {
-          e.element.disabled = true;
-          _refresh();
-        }),
-      new NavNotifyElement(_notifications, queue: _r.queue)
+      (new NavRefreshElement(queue: _r.queue)
+            ..onRefresh.listen((e) {
+              e.element.disabled = true;
+              _refresh();
+            }))
+          .element,
+      new NavNotifyElement(_notifications, queue: _r.queue).element
     ]);
     return menu;
   }
@@ -233,7 +238,8 @@
             ..classes = ['memberName']
             ..children = <Element>[
               new SourceLinkElement(_isolate, field.location, _scripts,
-                  queue: _r.queue)
+                      queue: _r.queue)
+                  .element
             ]
         ]
     ];
@@ -280,7 +286,8 @@
         break;
       case M.GuardClassKind.single:
         guard.add(
-            new ClassRefElement(_isolate, _field.guardClass, queue: _r.queue));
+            new ClassRefElement(_isolate, _field.guardClass, queue: _r.queue)
+                .element);
         break;
     }
     guard.add(new SpanElement()
diff --git a/runtime/observatory/lib/src/elements/flag_list.dart b/runtime/observatory/lib/src/elements/flag_list.dart
index b0ca6e1..7aa02fd 100644
--- a/runtime/observatory/lib/src/elements/flag_list.dart
+++ b/runtime/observatory/lib/src/elements/flag_list.dart
@@ -18,7 +18,7 @@
 import 'package:observatory/src/elements/nav/vm_menu.dart';
 import 'package:observatory/src/elements/view_footer.dart';
 
-class FlagListElement extends HtmlElement implements Renderable {
+class FlagListElement extends CustomElement implements Renderable {
   static const tag =
       const Tag<FlagListElement>('flag-list', dependencies: const [
     NavNotifyElement.tag,
@@ -47,7 +47,7 @@
     assert(events != null);
     assert(repository != null);
     assert(notifications != null);
-    FlagListElement e = document.createElement(tag.name);
+    FlagListElement e = new FlagListElement.created();
     e._r = new RenderingScheduler<FlagListElement>(e, queue: queue);
     e._vm = vm;
     e._events = events;
@@ -56,7 +56,7 @@
     return e;
   }
 
-  FlagListElement.created() : super.created();
+  FlagListElement.created() : super.created(tag);
 
   @override
   void attached() {
@@ -99,24 +99,25 @@
 
     children = <Element>[
       navBar(<Element>[
-        new NavTopMenuElement(queue: _r.queue),
-        new NavVMMenuElement(_vm, _events, queue: _r.queue),
+        new NavTopMenuElement(queue: _r.queue).element,
+        new NavVMMenuElement(_vm, _events, queue: _r.queue).element,
         navMenu('flags', link: Uris.flags()),
-        new NavRefreshElement(queue: _r.queue)
-          ..onRefresh.listen((e) async {
-            e.element.disabled = true;
-            try {
-              await _refresh();
-            } finally {
-              e.element.disabled = false;
-            }
-          }),
-        new NavNotifyElement(_notifications, queue: _r.queue)
+        (new NavRefreshElement(queue: _r.queue)
+              ..onRefresh.listen((e) async {
+                e.element.disabled = true;
+                try {
+                  await _refresh();
+                } finally {
+                  e.element.disabled = false;
+                }
+              }))
+            .element,
+        new NavNotifyElement(_notifications, queue: _r.queue).element
       ]),
       new DivElement()
         ..classes = ['content-centered']
         ..children = content,
-      new ViewFooterElement(queue: _r.queue)
+      new ViewFooterElement(queue: _r.queue).element
     ];
   }
 
diff --git a/runtime/observatory/lib/src/elements/function_ref.dart b/runtime/observatory/lib/src/elements/function_ref.dart
index 54ace9e..702eb39 100644
--- a/runtime/observatory/lib/src/elements/function_ref.dart
+++ b/runtime/observatory/lib/src/elements/function_ref.dart
@@ -19,7 +19,7 @@
 import 'package:observatory/src/elements/helpers/tag.dart';
 import 'package:observatory/src/elements/helpers/uris.dart';
 
-class FunctionRefElement extends HtmlElement implements Renderable {
+class FunctionRefElement extends CustomElement implements Renderable {
   static const tag = const Tag<FunctionRefElement>('function-ref');
 
   RenderingScheduler<FunctionRefElement> _r;
@@ -38,7 +38,7 @@
       {bool qualified: true, RenderingQueue queue}) {
     assert(function != null);
     assert(qualified != null);
-    FunctionRefElement e = document.createElement(tag.name);
+    FunctionRefElement e = new FunctionRefElement.created();
     e._r = new RenderingScheduler<FunctionRefElement>(e, queue: queue);
     e._isolate = isolate;
     e._function = function;
@@ -46,7 +46,7 @@
     return e;
   }
 
-  FunctionRefElement.created() : super.created();
+  FunctionRefElement.created() : super.created(tag);
 
   @override
   void attached() {
@@ -87,7 +87,7 @@
       if (owner is M.ClassRef) {
         content.addAll([
           new SpanElement()..text = '.',
-          new ClassRefElement(_isolate, owner, queue: _r.queue)
+          new ClassRefElement(_isolate, owner, queue: _r.queue).element
         ]);
       }
     }
diff --git a/runtime/observatory/lib/src/elements/function_view.dart b/runtime/observatory/lib/src/elements/function_view.dart
index 301d230..2215806 100644
--- a/runtime/observatory/lib/src/elements/function_view.dart
+++ b/runtime/observatory/lib/src/elements/function_view.dart
@@ -29,7 +29,7 @@
 import 'package:observatory/src/elements/source_link.dart';
 import 'package:observatory/src/elements/view_footer.dart';
 
-class FunctionViewElement extends HtmlElement implements Renderable {
+class FunctionViewElement extends CustomElement implements Renderable {
   static const tag =
       const Tag<FunctionViewElement>('function-view', dependencies: const [
     ClassRefElement.tag,
@@ -102,7 +102,7 @@
     assert(retainingPaths != null);
     assert(scripts != null);
     assert(objects != null);
-    FunctionViewElement e = document.createElement(tag.name);
+    FunctionViewElement e = new FunctionViewElement.created();
     e._r = new RenderingScheduler<FunctionViewElement>(e, queue: queue);
     e._vm = vm;
     e._isolate = isolate;
@@ -123,7 +123,7 @@
     return e;
   }
 
-  FunctionViewElement.created() : super.created();
+  FunctionViewElement.created() : super.created(tag);
 
   @override
   attached() {
@@ -148,8 +148,9 @@
           new HeadingElement.h2()..text = 'Function ${_function.name}',
           new HRElement(),
           new ObjectCommonElement(_isolate, _function, _retainedSizes,
-              _reachableSizes, _references, _retainingPaths, _objects,
-              queue: _r.queue),
+                  _reachableSizes, _references, _retainingPaths, _objects,
+                  queue: _r.queue)
+              .element,
           new BRElement(),
           new DivElement()
             ..classes = ['memberList']
@@ -160,35 +161,38 @@
                 ? const []
                 : [
                     new SourceInsetElement(_isolate, _function.location,
-                        _scripts, _objects, _events,
-                        queue: _r.queue)
+                            _scripts, _objects, _events,
+                            queue: _r.queue)
+                        .element
                   ],
-          new ViewFooterElement(queue: _r.queue)
+          new ViewFooterElement(queue: _r.queue).element
         ]
     ];
   }
 
   List<Element> _createMenu() {
     final menu = <Element>[
-      new NavTopMenuElement(queue: _r.queue),
-      new NavVMMenuElement(_vm, _events, queue: _r.queue),
-      new NavIsolateMenuElement(_isolate, _events, queue: _r.queue)
+      new NavTopMenuElement(queue: _r.queue).element,
+      new NavVMMenuElement(_vm, _events, queue: _r.queue).element,
+      new NavIsolateMenuElement(_isolate, _events, queue: _r.queue).element
     ];
     if (_library != null) {
-      menu.add(new NavLibraryMenuElement(_isolate, _library,
-          queue: _r.queue));
+      menu.add(new NavLibraryMenuElement(_isolate, _library, queue: _r.queue)
+          .element);
     } else if (_function.dartOwner is M.ClassRef) {
       menu.add(new NavClassMenuElement(_isolate, _function.dartOwner,
-          queue: _r.queue));
+              queue: _r.queue)
+          .element);
     }
     menu.addAll(<Element>[
       navMenu(_function.name),
-      new NavRefreshElement(queue: _r.queue)
-        ..onRefresh.listen((e) {
-          e.element.disabled = true;
-          _refresh();
-        }),
-      new NavNotifyElement(_notifications, queue: _r.queue)
+      (new NavRefreshElement(queue: _r.queue)
+            ..onRefresh.listen((e) {
+              e.element.disabled = true;
+              _refresh();
+            }))
+          .element,
+      new NavNotifyElement(_notifications, queue: _r.queue).element
     ]);
     return menu;
   }
@@ -205,8 +209,8 @@
             ..classes = ['memberName']
             ..children = <Element>[
               new SpanElement()
-                ..text = '${_function.isStatic ? "static ": ""}'
-                    '${_function.isConst ? "const ": ""}'
+                ..text = '${_function.isStatic ? "static " : ""}'
+                    '${_function.isConst ? "const " : ""}'
                     '${_functionKindToString(_function.kind)}'
             ]
         ],
@@ -237,7 +241,8 @@
             ..classes = ['memberName']
             ..children = <Element>[
               new FieldRefElement(_isolate, _function.field, _objects,
-                  queue: _r.queue)
+                      queue: _r.queue)
+                  .element
             ]
         ]);
     }
@@ -251,7 +256,8 @@
           ..classes = ['memberName']
           ..children = <Element>[
             new SourceLinkElement(_isolate, _function.location, _scripts,
-                queue: _r.queue)
+                    queue: _r.queue)
+                .element
           ]
       ]);
     if (_function.code != null) {
@@ -265,6 +271,7 @@
             ..classes = ['memberName']
             ..children = <Element>[
               new CodeRefElement(_isolate, _function.code, queue: _r.queue)
+                  .element
             ]
         ]);
     }
@@ -279,12 +286,13 @@
             ..classes = ['memberName']
             ..children = <Element>[
               new CodeRefElement(_isolate, _function.unoptimizedCode,
-                  queue: _r.queue),
+                      queue: _r.queue)
+                  .element,
               new SpanElement()
                 ..title = 'This count is used to determine when a function '
                     'will be optimized.  It is a combination of call '
                     'counts and other factors.'
-                ..text = ' (usage count: ${function.usageCounter })'
+                ..text = ' (usage count: ${function.usageCounter})'
             ]
         ]);
     }
@@ -298,8 +306,8 @@
           new DivElement()
             ..classes = ['memberName']
             ..children = <Element>[
-              new CodeRefElement(_isolate, _function.bytecode,
-                  queue: _r.queue),
+              new CodeRefElement(_isolate, _function.bytecode, queue: _r.queue)
+                  .element,
             ]
         ]);
     }
@@ -318,7 +326,8 @@
             ..classes = ['memberName']
             ..children = <Element>[
               new InstanceRefElement(_isolate, _function.icDataArray, _objects,
-                  queue: _r.queue)
+                      queue: _r.queue)
+                  .element
             ]
         ]);
     }
diff --git a/runtime/observatory/lib/src/elements/general_error.dart b/runtime/observatory/lib/src/elements/general_error.dart
index 152df99..f94872b 100644
--- a/runtime/observatory/lib/src/elements/general_error.dart
+++ b/runtime/observatory/lib/src/elements/general_error.dart
@@ -13,7 +13,7 @@
 import 'package:observatory/src/elements/nav/notify.dart';
 import 'package:observatory/src/elements/nav/top_menu.dart';
 
-class GeneralErrorElement extends HtmlElement implements Renderable {
+class GeneralErrorElement extends CustomElement implements Renderable {
   static const tag = const Tag<GeneralErrorElement>('general-error',
       dependencies: const [NavTopMenuElement.tag, NavNotifyElement.tag]);
 
@@ -32,14 +32,14 @@
       {String message: '', RenderingQueue queue}) {
     assert(notifications != null);
     assert(message != null);
-    GeneralErrorElement e = document.createElement(tag.name);
+    GeneralErrorElement e = new GeneralErrorElement.created();
     e._r = new RenderingScheduler<GeneralErrorElement>(e, queue: queue);
     e._message = message;
     e._notifications = notifications;
     return e;
   }
 
-  GeneralErrorElement.created() : super.created();
+  GeneralErrorElement.created() : super.created(tag);
 
   @override
   void attached() {
@@ -57,8 +57,8 @@
   void render() {
     children = <Element>[
       navBar(<Element>[
-        new NavTopMenuElement(queue: _r.queue),
-        new NavNotifyElement(_notifications, queue: _r.queue)
+        new NavTopMenuElement(queue: _r.queue).element,
+        new NavNotifyElement(_notifications, queue: _r.queue).element
       ]),
       new DivElement()
         ..classes = ['content-centered']
diff --git a/runtime/observatory/lib/src/elements/heap_map.dart b/runtime/observatory/lib/src/elements/heap_map.dart
index 6db1ce8..51373bfc 100644
--- a/runtime/observatory/lib/src/elements/heap_map.dart
+++ b/runtime/observatory/lib/src/elements/heap_map.dart
@@ -20,7 +20,7 @@
 import 'package:observatory/src/elements/nav/top_menu.dart';
 import 'package:observatory/src/elements/nav/vm_menu.dart';
 
-class HeapMapElement extends HtmlElement implements Renderable {
+class HeapMapElement extends CustomElement implements Renderable {
   static const tag = const Tag<HeapMapElement>('heap-map', dependencies: const [
     NavTopMenuElement.tag,
     NavVMMenuElement.tag,
@@ -48,7 +48,7 @@
     assert(isolate != null);
     assert(events != null);
     assert(notifications != null);
-    HeapMapElement e = document.createElement(tag.name);
+    HeapMapElement e = new HeapMapElement.created();
     e._r = new RenderingScheduler<HeapMapElement>(e, queue: queue);
     e._vm = vm;
     e._isolate = isolate;
@@ -57,7 +57,7 @@
     return e;
   }
 
-  HeapMapElement.created() : super.created();
+  HeapMapElement.created() : super.created(tag);
 
   @override
   attached() {
@@ -104,19 +104,23 @@
 
     children = <Element>[
       navBar(<Element>[
-        new NavTopMenuElement(queue: _r.queue),
-        new NavVMMenuElement(_vm, _events, queue: _r.queue),
-        new NavIsolateMenuElement(_isolate, _events, queue: _r.queue),
+        new NavTopMenuElement(queue: _r.queue).element,
+        new NavVMMenuElement(_vm, _events, queue: _r.queue).element,
+        new NavIsolateMenuElement(_isolate, _events, queue: _r.queue).element,
         navMenu('heap map'),
-        new NavRefreshElement(label: 'Mark-Compact', queue: _r.queue)
-          ..onRefresh.listen((_) => _refresh(gc: "mark-compact")),
-        new NavRefreshElement(label: 'Mark-Sweep', queue: _r.queue)
-          ..onRefresh.listen((_) => _refresh(gc: "mark-sweep")),
-        new NavRefreshElement(label: 'Scavenge', queue: _r.queue)
-          ..onRefresh.listen((_) => _refresh(gc: "scavenge")),
-        new NavRefreshElement(queue: _r.queue)
-          ..onRefresh.listen((_) => _refresh()),
-        new NavNotifyElement(_notifications, queue: _r.queue)
+        (new NavRefreshElement(label: 'Mark-Compact', queue: _r.queue)
+              ..onRefresh.listen((_) => _refresh(gc: "mark-compact")))
+            .element,
+        (new NavRefreshElement(label: 'Mark-Sweep', queue: _r.queue)
+              ..onRefresh.listen((_) => _refresh(gc: "mark-sweep")))
+            .element,
+        (new NavRefreshElement(label: 'Scavenge', queue: _r.queue)
+              ..onRefresh.listen((_) => _refresh(gc: "scavenge")))
+            .element,
+        (new NavRefreshElement(queue: _r.queue)
+              ..onRefresh.listen((_) => _refresh()))
+            .element,
+        (new NavNotifyElement(_notifications, queue: _r.queue)).element
       ]),
       new DivElement()
         ..classes = ['content-centered-big']
diff --git a/runtime/observatory/lib/src/elements/heap_snapshot.dart b/runtime/observatory/lib/src/elements/heap_snapshot.dart
index 3e6e455..2b32375 100644
--- a/runtime/observatory/lib/src/elements/heap_snapshot.dart
+++ b/runtime/observatory/lib/src/elements/heap_snapshot.dart
@@ -32,7 +32,7 @@
   groupByClass
 }
 
-class HeapSnapshotElement extends HtmlElement implements Renderable {
+class HeapSnapshotElement extends CustomElement implements Renderable {
   static const tag =
       const Tag<HeapSnapshotElement>('heap-snapshot', dependencies: const [
     ClassRefElement.tag,
@@ -79,7 +79,7 @@
     assert(notifications != null);
     assert(snapshots != null);
     assert(objects != null);
-    HeapSnapshotElement e = document.createElement(tag.name);
+    HeapSnapshotElement e = new HeapSnapshotElement.created();
     e._r = new RenderingScheduler<HeapSnapshotElement>(e, queue: queue);
     e._vm = vm;
     e._isolate = isolate;
@@ -90,7 +90,7 @@
     return e;
   }
 
-  HeapSnapshotElement.created() : super.created();
+  HeapSnapshotElement.created() : super.created(tag);
 
   @override
   attached() {
@@ -109,16 +109,17 @@
   void render() {
     final content = <Element>[
       navBar(<Element>[
-        new NavTopMenuElement(queue: _r.queue),
-        new NavVMMenuElement(_vm, _events, queue: _r.queue),
-        new NavIsolateMenuElement(_isolate, _events, queue: _r.queue),
+        new NavTopMenuElement(queue: _r.queue).element,
+        new NavVMMenuElement(_vm, _events, queue: _r.queue).element,
+        new NavIsolateMenuElement(_isolate, _events, queue: _r.queue).element,
         navMenu('heap snapshot'),
-        new NavRefreshElement(queue: _r.queue)
-          ..disabled = M.isHeapSnapshotProgressRunning(_progress?.status)
-          ..onRefresh.listen((e) {
-            _refresh();
-          }),
-        new NavNotifyElement(_notifications, queue: _r.queue)
+        (new NavRefreshElement(queue: _r.queue)
+              ..disabled = M.isHeapSnapshotProgressRunning(_progress?.status)
+              ..onRefresh.listen((e) {
+                _refresh();
+              }))
+            .element,
+        new NavNotifyElement(_notifications, queue: _r.queue).element
       ]),
     ];
     if (_progress == null) {
@@ -275,7 +276,7 @@
           new DivElement()
             ..classes = ['content-centered-big', 'explanation']
             ..text = text,
-          _tree
+          _tree.element
         ]);
         break;
       case HeapSnapshotTreeMode.mergedDominatorTree:
@@ -290,7 +291,7 @@
           new DivElement()
             ..classes = ['content-centered-big', 'explanation']
             ..text = text,
-          _tree
+          _tree.element
         ]);
         break;
       case HeapSnapshotTreeMode.ownershipTable:
@@ -308,7 +309,7 @@
           new DivElement()
             ..classes = ['content-centered-big', 'explanation']
             ..text = text,
-          _tree
+          _tree.element
         ]);
         break;
       case HeapSnapshotTreeMode.groupByClass:
@@ -318,7 +319,7 @@
             _createGroup, _updateGroup, _getChildrenGroup,
             items: items, queue: _r.queue);
         _tree.expand(_snapshot.dominatorTree);
-        report.add(_tree);
+        report.add(_tree.element);
         break;
       default:
         break;
@@ -504,8 +505,9 @@
       element.children[2].text = _tree.isExpanded(item) ? 'â–¼' : 'â–º';
       element.children[3].text = '${item.instances} instances of ';
       element.children[4] =
-          new ClassRefElement(_isolate, item.clazz, queue: _r.queue)
-            ..classes = ['name'];
+          (new ClassRefElement(_isolate, item.clazz, queue: _r.queue)
+                ..classes = ['name'])
+              .element;
     } else if (item is Iterable) {
       element.children[0].text = '';
       if (item.isNotEmpty) {
@@ -536,12 +538,12 @@
         element.children[3].text =
             '${item.count} references from instances of ';
         element.children[4].children = <Element>[
-          new ClassRefElement(_isolate, item.source, queue: _r.queue)
+          new ClassRefElement(_isolate, item.source, queue: _r.queue).element
         ];
       } else if (item is M.HeapSnapshotClassOutbound) {
         element.children[3]..text = '${item.count} references to instances of ';
         element.children[4].children = <Element>[
-          new ClassRefElement(_isolate, item.target, queue: _r.queue)
+          new ClassRefElement(_isolate, item.target, queue: _r.queue).element
         ];
       }
     }
@@ -556,8 +558,9 @@
       ..classes = ['name']
       ..children = <Element>[
         new SpanElement()..text = ' instances of ',
-        new ClassRefElement(_isolate, item.clazz, queue: _r.queue)
-          ..classes = ['name']
+        (new ClassRefElement(_isolate, item.clazz, queue: _r.queue)
+              ..classes = ['name'])
+            .element
       ];
   }
 
diff --git a/runtime/observatory/lib/src/elements/helpers/any_ref.dart b/runtime/observatory/lib/src/elements/helpers/any_ref.dart
index 693fe7e..e69b983 100644
--- a/runtime/observatory/lib/src/elements/helpers/any_ref.dart
+++ b/runtime/observatory/lib/src/elements/helpers/any_ref.dart
@@ -39,52 +39,57 @@
     }
   } else if (ref is M.ObjectRef) {
     if (ref is M.ClassRef) {
-      return new ClassRefElement(isolate, ref, queue: queue);
+      return new ClassRefElement(isolate, ref, queue: queue).element;
     } else if (ref is M.CodeRef) {
-      return new CodeRefElement(isolate, ref, queue: queue);
+      return new CodeRefElement(isolate, ref, queue: queue).element;
     } else if (ref is M.ContextRef) {
       return new ContextRefElement(isolate, ref, objects,
-          queue: queue, expandable: expandable);
+              queue: queue, expandable: expandable)
+          .element;
     } else if (ref is M.Error) {
-      return new ErrorRefElement(ref, queue: queue);
+      return new ErrorRefElement(ref, queue: queue).element;
     } else if (ref is M.FieldRef) {
       return new FieldRefElement(isolate, ref, objects,
-          queue: queue, expandable: expandable);
+              queue: queue, expandable: expandable)
+          .element;
     } else if (ref is M.FunctionRef) {
-      return new FunctionRefElement(isolate, ref, queue: queue);
+      return new FunctionRefElement(isolate, ref, queue: queue).element;
     } else if (ref is M.ICDataRef) {
-      return new ICDataRefElement(isolate, ref, queue: queue);
+      return new ICDataRefElement(isolate, ref, queue: queue).element;
     } else if (ref is M.InstanceRef) {
       return new InstanceRefElement(isolate, ref, objects,
-          queue: queue, expandable: expandable);
+              queue: queue, expandable: expandable)
+          .element;
     } else if (ref is M.LibraryRef) {
-      return new LibraryRefElement(isolate, ref, queue: queue);
+      return new LibraryRefElement(isolate, ref, queue: queue).element;
     } else if (ref is M.LocalVarDescriptorsRef) {
-      return new LocalVarDescriptorsRefElement(isolate, ref, queue: queue);
+      return new LocalVarDescriptorsRefElement(isolate, ref, queue: queue)
+          .element;
     } else if (ref is M.MegamorphicCacheRef) {
-      return new MegamorphicCacheRefElement(isolate, ref, queue: queue);
+      return new MegamorphicCacheRefElement(isolate, ref, queue: queue).element;
     } else if (ref is M.ObjectPoolRef) {
-      return new ObjectPoolRefElement(isolate, ref, queue: queue);
+      return new ObjectPoolRefElement(isolate, ref, queue: queue).element;
     } else if (ref is M.PcDescriptorsRef) {
-      return new PcDescriptorsRefElement(isolate, ref, queue: queue);
+      return new PcDescriptorsRefElement(isolate, ref, queue: queue).element;
     } else if (ref is M.ScriptRef) {
-      return new ScriptRefElement(isolate, ref, queue: queue);
+      return new ScriptRefElement(isolate, ref, queue: queue).element;
     } else if (ref is M.SingleTargetCacheRef) {
-      return new SingleTargetCacheRefElement(isolate, ref, queue: queue);
+      return new SingleTargetCacheRefElement(isolate, ref, queue: queue)
+          .element;
     } else if (ref is M.SubtypeTestCacheRef) {
-      return new SubtypeTestCacheRefElement(isolate, ref, queue: queue);
+      return new SubtypeTestCacheRefElement(isolate, ref, queue: queue).element;
     } else if (ref is M.TypeArgumentsRef) {
-      return new TypeArgumentsRefElement(isolate, ref, queue: queue);
+      return new TypeArgumentsRefElement(isolate, ref, queue: queue).element;
     } else if (ref is M.UnknownObjectRef) {
-      return new UnknownObjectRefElement(isolate, ref, queue: queue);
+      return new UnknownObjectRefElement(isolate, ref, queue: queue).element;
     } else if (ref is M.UnlinkedCallRef) {
-      return new UnlinkedCallRefElement(isolate, ref, queue: queue);
+      return new UnlinkedCallRefElement(isolate, ref, queue: queue).element;
     } else {
       return new AnchorElement(href: Uris.inspect(isolate, object: ref))
         ..text = 'object';
     }
   } else if (ref is M.Sentinel) {
-    return new SentinelValueElement(ref, queue: queue);
+    return new SentinelValueElement(ref, queue: queue).element;
   }
   throw new Exception('Unknown ref type (${ref.runtimeType})');
 }
diff --git a/runtime/observatory/lib/src/elements/helpers/tag.dart b/runtime/observatory/lib/src/elements/helpers/tag.dart
index 0d488c1..1ad74c7 100644
--- a/runtime/observatory/lib/src/elements/helpers/tag.dart
+++ b/runtime/observatory/lib/src/elements/helpers/tag.dart
@@ -2,10 +2,91 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'dart:async';
 import 'dart:html';
 
+HtmlElement element(CustomElement e) => e.element;
+
+class CustomElement {
+  static Expando reverseElements = new Expando();
+  static CustomElement reverse(HtmlElement element) => reverseElements[element];
+
+  static List<CustomElement> toBeAttached = new List<CustomElement>();
+  static void drainAttached() {
+    // Send 'attached' to elements that have been attached to the document.
+    bool fired = false;
+    var connectedElements = toBeAttached
+        .where((CustomElement element) => element.element.isConnected)
+        .toList();
+    for (CustomElement element in connectedElements) {
+      toBeAttached.remove(element);
+      element.attached();
+      fired = true;
+    }
+
+    if (toBeAttached.isEmpty) {
+      return; // Done.
+    }
+
+    if (fired) {
+      // The 'attached' events above may have scheduled microtasks that will
+      // will add more CustomElements to be document, e.g. 'render'.
+      scheduleMicrotask(() => drainAttached());
+    }
+
+    while (!toBeAttached.isEmpty) {
+      // Either this element will never be attached or it will be attached
+      // after a turn of the outer event loop. Fire 'attached' in case it is
+      // the latter, since firing it out of order is preferrable to not firing
+      // it at all.
+      CustomElement element = toBeAttached.removeLast();
+      print("Warning: created but not in document: $element");
+      element.attached();
+    }
+  }
+
+  final HtmlElement element;
+  CustomElement.created(Tag tag) : element = document.createElement("shadow") {
+    reverseElements[element] = this;
+    element.classes = [tag.name];
+
+    if (toBeAttached.isEmpty) {
+      scheduleMicrotask(() => drainAttached());
+    }
+    toBeAttached.add(this);
+  }
+
+  void attached() {}
+  void detached() {}
+
+  Element get parent => element.parent;
+
+  List<Element> get children => element.children;
+  set children(List<Element> c) => element.children = c;
+
+  CssClassSet get classes => element.classes;
+  set classes(dynamic c) => element.classes = c;
+
+  String get title => element.title;
+  set title(String t) => element.title = t;
+
+  String get text => element.text;
+  set text(String t) => element.text = t;
+
+  CssStyleDeclaration get style => element.style;
+
+  ElementStream<MouseEvent> get onClick => element.onClick;
+
+  Rectangle getBoundingClientRect() => element.getBoundingClientRect();
+
+  List<Node> getElementsByClassName(String c) =>
+      element.getElementsByClassName(c);
+
+  void scrollIntoView() => element.scrollIntoView();
+}
+
 /// Utility class for Custom Tags registration.
-class Tag<T extends HtmlElement> {
+class Tag<T extends CustomElement> {
   /// Tag name.
   final String name;
 
@@ -13,25 +94,4 @@
   final Iterable<Tag> dependencies;
 
   const Tag(this.name, {this.dependencies: const []});
-
-  static final Map<Type, String> _tagByClass = <Type, String>{};
-  static final Map<String, Type> _classByTag = <String, Type>{};
-
-  /// Ensures that the Tag and all the dependencies are registered.
-  void ensureRegistration() {
-    if (!_tagByClass.containsKey(T) && !_classByTag.containsKey(name)) {
-      document.registerElement(name, T);
-      _tagByClass[T] = name;
-      _classByTag[name] = T;
-      dependencies.forEach((tag) => tag.ensureRegistration());
-    }
-    var tag = _tagByClass[T];
-    if (tag != name) {
-      throw new ArgumentError('Class $T is already registered to tag ${tag}');
-    }
-    var c = _classByTag[name];
-    if (c != T) {
-      throw new ArgumentError('Tag $name is already registered by class ${c}');
-    }
-  }
 }
diff --git a/runtime/observatory/lib/src/elements/icdata_ref.dart b/runtime/observatory/lib/src/elements/icdata_ref.dart
index 5a4f4d7..bcf1c04 100644
--- a/runtime/observatory/lib/src/elements/icdata_ref.dart
+++ b/runtime/observatory/lib/src/elements/icdata_ref.dart
@@ -9,7 +9,7 @@
 import 'package:observatory/src/elements/helpers/tag.dart';
 import 'package:observatory/src/elements/helpers/uris.dart';
 
-class ICDataRefElement extends HtmlElement implements Renderable {
+class ICDataRefElement extends CustomElement implements Renderable {
   static const tag = const Tag<ICDataRefElement>('icdata-ref');
 
   RenderingScheduler<ICDataRefElement> _r;
@@ -26,14 +26,14 @@
       {RenderingQueue queue}) {
     assert(isolate != null);
     assert(icdata != null);
-    ICDataRefElement e = document.createElement(tag.name);
+    ICDataRefElement e = new ICDataRefElement.created();
     e._r = new RenderingScheduler<ICDataRefElement>(e, queue: queue);
     e._isolate = isolate;
     e._icdata = icdata;
     return e;
   }
 
-  ICDataRefElement.created() : super.created();
+  ICDataRefElement.created() : super.created(tag);
 
   @override
   void attached() {
diff --git a/runtime/observatory/lib/src/elements/icdata_view.dart b/runtime/observatory/lib/src/elements/icdata_view.dart
index 3729a73..f089e5b 100644
--- a/runtime/observatory/lib/src/elements/icdata_view.dart
+++ b/runtime/observatory/lib/src/elements/icdata_view.dart
@@ -19,7 +19,7 @@
 import 'package:observatory/src/elements/object_common.dart';
 import 'package:observatory/src/elements/view_footer.dart';
 
-class ICDataViewElement extends HtmlElement implements Renderable {
+class ICDataViewElement extends CustomElement implements Renderable {
   static const tag =
       const Tag<ICDataViewElement>('icdata-view', dependencies: const [
     CurlyBlockElement.tag,
@@ -77,7 +77,7 @@
     assert(references != null);
     assert(retainingPaths != null);
     assert(objects != null);
-    ICDataViewElement e = document.createElement(tag.name);
+    ICDataViewElement e = new ICDataViewElement.created();
     e._r = new RenderingScheduler<ICDataViewElement>(e, queue: queue);
     e._vm = vm;
     e._isolate = isolate;
@@ -93,7 +93,7 @@
     return e;
   }
 
-  ICDataViewElement.created() : super.created();
+  ICDataViewElement.created() : super.created(tag);
 
   @override
   attached() {
@@ -111,17 +111,18 @@
   void render() {
     children = <Element>[
       navBar(<Element>[
-        new NavTopMenuElement(queue: _r.queue),
-        new NavVMMenuElement(_vm, _events, queue: _r.queue),
-        new NavIsolateMenuElement(_isolate, _events, queue: _r.queue),
+        new NavTopMenuElement(queue: _r.queue).element,
+        new NavVMMenuElement(_vm, _events, queue: _r.queue).element,
+        new NavIsolateMenuElement(_isolate, _events, queue: _r.queue).element,
         navMenu('icdata'),
-        new NavRefreshElement(queue: _r.queue)
-          ..onRefresh.listen((e) async {
-            e.element.disabled = true;
-            _icdata = await _icdatas.get(_isolate, _icdata.id);
-            _r.dirty();
-          }),
-        new NavNotifyElement(_notifications, queue: _r.queue)
+        (new NavRefreshElement(queue: _r.queue)
+              ..onRefresh.listen((e) async {
+                e.element.disabled = true;
+                _icdata = await _icdatas.get(_isolate, _icdata.id);
+                _r.dirty();
+              }))
+            .element,
+        new NavNotifyElement(_notifications, queue: _r.queue).element
       ]),
       new DivElement()
         ..classes = ['content-centered-big']
@@ -129,8 +130,9 @@
           new HeadingElement.h2()..text = 'ICData',
           new HRElement(),
           new ObjectCommonElement(_isolate, _icdata, _retainedSizes,
-              _reachableSizes, _references, _retainingPaths, _objects,
-              queue: _r.queue),
+                  _reachableSizes, _references, _retainingPaths, _objects,
+                  queue: _r.queue)
+              .element,
           new DivElement()
             ..classes = ['memberList']
             ..children = <Element>[
@@ -192,7 +194,7 @@
                 ]
             ],
           new HRElement(),
-          new ViewFooterElement(queue: _r.queue)
+          new ViewFooterElement(queue: _r.queue).element
         ]
     ];
   }
diff --git a/runtime/observatory/lib/src/elements/inbound_references.dart b/runtime/observatory/lib/src/elements/inbound_references.dart
index bfd9d29..a1e24f6 100644
--- a/runtime/observatory/lib/src/elements/inbound_references.dart
+++ b/runtime/observatory/lib/src/elements/inbound_references.dart
@@ -11,7 +11,7 @@
 import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
 import 'package:observatory/src/elements/helpers/tag.dart';
 
-class InboundReferencesElement extends HtmlElement implements Renderable {
+class InboundReferencesElement extends CustomElement implements Renderable {
   static const tag = const Tag<InboundReferencesElement>('inbound-references',
       dependencies: const [CurlyBlockElement.tag, InstanceRefElement.tag]);
 
@@ -37,7 +37,7 @@
     assert(object != null);
     assert(references != null);
     assert(objects != null);
-    InboundReferencesElement e = document.createElement(tag.name);
+    InboundReferencesElement e = new InboundReferencesElement.created();
     e._r = new RenderingScheduler<InboundReferencesElement>(e, queue: queue);
     e._isolate = isolate;
     e._object = object;
@@ -46,7 +46,7 @@
     return e;
   }
 
-  InboundReferencesElement.created() : super.created();
+  InboundReferencesElement.created() : super.created(tag);
 
   @override
   void attached() {
@@ -73,7 +73,7 @@
               e.control.disabled = false;
             }
           });
-    children = <Element>[curlyBlock];
+    children = <Element>[curlyBlock.element];
     _r.waitFor([curlyBlock.onRendered.first]);
   }
 
@@ -109,8 +109,9 @@
     content.addAll([
       anyRef(_isolate, reference.source, _objects, queue: _r.queue),
       new InboundReferencesElement(
-          _isolate, reference.source, _references, _objects,
-          queue: _r.queue)
+              _isolate, reference.source, _references, _objects,
+              queue: _r.queue)
+          .element
     ]);
 
     return new DivElement()
diff --git a/runtime/observatory/lib/src/elements/instance_ref.dart b/runtime/observatory/lib/src/elements/instance_ref.dart
index 6ee4dfd..96db281 100644
--- a/runtime/observatory/lib/src/elements/instance_ref.dart
+++ b/runtime/observatory/lib/src/elements/instance_ref.dart
@@ -13,7 +13,7 @@
 import 'package:observatory/src/elements/helpers/uris.dart';
 import 'package:observatory/utils.dart';
 
-class InstanceRefElement extends HtmlElement implements Renderable {
+class InstanceRefElement extends CustomElement implements Renderable {
   static const tag = const Tag<InstanceRefElement>('instance-ref',
       dependencies: const [CurlyBlockElement.tag]);
 
@@ -37,7 +37,7 @@
     assert(isolate != null);
     assert(instance != null);
     assert(objects != null);
-    InstanceRefElement e = document.createElement(tag.name);
+    InstanceRefElement e = new InstanceRefElement.created();
     e._r = new RenderingScheduler<InstanceRefElement>(e, queue: queue);
     e._isolate = isolate;
     e._instance = instance;
@@ -46,7 +46,7 @@
     return e;
   }
 
-  InstanceRefElement.created() : super.created();
+  InstanceRefElement.created() : super.created(tag);
 
   @override
   void attached() {
@@ -67,20 +67,21 @@
     if (_expandable && _hasValue()) {
       content.addAll([
         new SpanElement()..text = ' ',
-        new CurlyBlockElement(expanded: _expanded, queue: _r.queue)
-          ..content = <Element>[
-            new DivElement()
-              ..classes = ['indent']
-              ..children = _createValue()
-          ]
-          ..onToggle.listen((e) async {
-            _expanded = e.control.expanded;
-            if (_expanded) {
-              e.control.disabled = true;
-              await _refresh();
-              e.control.disabled = false;
-            }
-          })
+        (new CurlyBlockElement(expanded: _expanded, queue: _r.queue)
+              ..content = <Element>[
+                new DivElement()
+                  ..classes = ['indent']
+                  ..children = _createValue()
+              ]
+              ..onToggle.listen((e) async {
+                _expanded = e.control.expanded;
+                if (_expanded) {
+                  e.control.disabled = true;
+                  await _refresh();
+                  e.control.disabled = false;
+                }
+              }))
+            .element
       ]);
     }
 
@@ -268,8 +269,8 @@
         return _loadedInstance.fields
             .map<Element>((f) => new DivElement()
               ..children = <Element>[
-                new FieldRefElement(_isolate, f.decl, _objects,
-                    queue: _r.queue),
+                new FieldRefElement(_isolate, f.decl, _objects, queue: _r.queue)
+                    .element,
                 new SpanElement()..text = ' = ',
                 anyRef(_isolate, f.value, _objects, queue: _r.queue)
               ])
@@ -329,11 +330,13 @@
         return [
           new SpanElement()..text = '<key> : ',
           new InstanceRefElement(_isolate, _loadedInstance.key, _objects,
-              queue: _r.queue),
+                  queue: _r.queue)
+              .element,
           new BRElement(),
           new SpanElement()..text = '<value> : ',
           new InstanceRefElement(_isolate, _loadedInstance.value, _objects,
-              queue: _r.queue),
+                  queue: _r.queue)
+              .element,
         ];
       default:
         return [];
diff --git a/runtime/observatory/lib/src/elements/instance_view.dart b/runtime/observatory/lib/src/elements/instance_view.dart
index 174af31..6540562 100644
--- a/runtime/observatory/lib/src/elements/instance_view.dart
+++ b/runtime/observatory/lib/src/elements/instance_view.dart
@@ -32,7 +32,7 @@
 import 'package:observatory/src/elements/view_footer.dart';
 import 'package:observatory/utils.dart';
 
-class InstanceViewElement extends HtmlElement implements Renderable {
+class InstanceViewElement extends CustomElement implements Renderable {
   static const tag =
       const Tag<InstanceViewElement>('instance-view', dependencies: const [
     ClassRefElement.tag,
@@ -117,7 +117,7 @@
     assert(arguments != null);
     assert(breakpoints != null);
     assert(functions != null);
-    InstanceViewElement e = document.createElement(tag.name);
+    InstanceViewElement e = new InstanceViewElement.created();
     e._r = new RenderingScheduler<InstanceViewElement>(e, queue: queue);
     e._vm = vm;
     e._isolate = isolate;
@@ -138,7 +138,7 @@
     return e;
   }
 
-  InstanceViewElement.created() : super.created();
+  InstanceViewElement.created() : super.created(tag);
 
   @override
   attached() {
@@ -162,25 +162,29 @@
             : 'instance of ${_instance.clazz.name}',
       new HRElement(),
       new ObjectCommonElement(_isolate, _instance, _retainedSizes,
-          _reachableSizes, _references, _retainingPaths, _objects,
-          queue: _r.queue),
+              _reachableSizes, _references, _retainingPaths, _objects,
+              queue: _r.queue)
+          .element,
       new BRElement(),
       new DivElement()
         ..classes = ['memberList']
         ..children = _createMembers(),
       new HRElement(),
       new EvalBoxElement(_isolate, _instance, _objects, _eval,
-          quickExpressions: const ['toString()', 'runtimeType'],
-          queue: _r.queue)
+              quickExpressions: const ['toString()', 'runtimeType'],
+              queue: _r.queue)
+          .element
     ];
     if (_location != null) {
       content.addAll([
         new HRElement(),
         new SourceInsetElement(_isolate, _location, _scripts, _objects, _events,
-            queue: _r.queue)
+                queue: _r.queue)
+            .element
       ]);
     }
-    content.addAll([new HRElement(), new ViewFooterElement(queue: _r.queue)]);
+    content.addAll(
+        [new HRElement(), new ViewFooterElement(queue: _r.queue).element]);
     children = <Element>[
       navBar(_createMenu()),
       new DivElement()
@@ -191,22 +195,25 @@
 
   List<Element> _createMenu() {
     final menu = <Element>[
-      new NavTopMenuElement(queue: _r.queue),
-      new NavVMMenuElement(_vm, _events, queue: _r.queue),
-      new NavIsolateMenuElement(_isolate, _events, queue: _r.queue)
+      new NavTopMenuElement(queue: _r.queue).element,
+      new NavVMMenuElement(_vm, _events, queue: _r.queue).element,
+      new NavIsolateMenuElement(_isolate, _events, queue: _r.queue).element
     ];
     if (_library != null) {
-      menu.add(new NavLibraryMenuElement(_isolate, _library, queue: _r.queue));
+      menu.add(new NavLibraryMenuElement(_isolate, _library, queue: _r.queue)
+          .element);
     }
     menu.addAll(<Element>[
-      new NavClassMenuElement(_isolate, _instance.clazz, queue: _r.queue),
+      new NavClassMenuElement(_isolate, _instance.clazz, queue: _r.queue)
+          .element,
       navMenu('instance'),
-      new NavRefreshElement(queue: _r.queue)
-        ..onRefresh.listen((e) {
-          e.element.disabled = true;
-          _refresh();
-        }),
-      new NavNotifyElement(_notifications, queue: _r.queue)
+      (new NavRefreshElement(queue: _r.queue)
+            ..onRefresh.listen((e) {
+              e.element.disabled = true;
+              _refresh();
+            }))
+          .element,
+      new NavNotifyElement(_notifications, queue: _r.queue).element
     ]);
     return menu;
   }
@@ -241,7 +248,8 @@
             ..classes = ['memberValue']
             ..children = <Element>[
               new ClassRefElement(_isolate, _instance.typeClass,
-                  queue: _r.queue)
+                      queue: _r.queue)
+                  .element
             ]
         ]);
     }
@@ -257,7 +265,8 @@
             ..children = ([new SpanElement()..text = '< ']
               ..addAll(_typeArguments.types.expand((type) => [
                     new InstanceRefElement(_isolate, type, _objects,
-                        queue: _r.queue),
+                            queue: _r.queue)
+                        .element,
                     new SpanElement()..text = ', '
                   ]))
               ..removeLast()
@@ -275,7 +284,8 @@
             ..classes = ['memberValue']
             ..children = <Element>[
               new ClassRefElement(_isolate, _instance.parameterizedClass,
-                  queue: _r.queue)
+                      queue: _r.queue)
+                  .element
             ]
         ]);
     }
@@ -302,7 +312,8 @@
             ..classes = ['memberValue']
             ..children = <Element>[
               new InstanceRefElement(_isolate, _instance.targetType, _objects,
-                  queue: _r.queue)
+                      queue: _r.queue)
+                  .element
             ]
         ]);
     }
@@ -317,7 +328,8 @@
             ..classes = ['memberValue']
             ..children = <Element>[
               new InstanceRefElement(_isolate, _instance.bound, _objects,
-                  queue: _r.queue)
+                      queue: _r.queue)
+                  .element
             ]
         ]);
     }
@@ -332,7 +344,8 @@
             ..classes = ['memberValue']
             ..children = <Element>[
               new FunctionRefElement(_isolate, _instance.closureFunction,
-                  queue: _r.queue)
+                      queue: _r.queue)
+                  .element
             ]
         ]);
     }
@@ -347,8 +360,9 @@
             ..classes = ['memberValue']
             ..children = <Element>[
               new ContextRefElement(
-                  _isolate, _instance.closureContext, _objects,
-                  queue: _r.queue)
+                      _isolate, _instance.closureContext, _objects,
+                      queue: _r.queue)
+                  .element
             ]
         ]);
     }
@@ -386,25 +400,26 @@
           new DivElement()
             ..classes = ['memberName']
             ..children = <Element>[
-              new CurlyBlockElement(
-                  expanded: _instance.nativeFields.length <= 100,
-                  queue: _r.queue)
-                ..content = <Element>[
-                  new DivElement()
-                    ..classes = ['memberList']
-                    ..children = _instance.nativeFields
-                        .map<Element>((f) => new DivElement()
-                          ..classes = ['memberItem']
-                          ..children = <Element>[
-                            new DivElement()
-                              ..classes = ['memberName']
-                              ..text = '[ ${i++} ]',
-                            new DivElement()
-                              ..classes = ['memberValue']
-                              ..text = '[ ${f.value} ]'
-                          ])
-                        .toList()
-                ]
+              (new CurlyBlockElement(
+                      expanded: _instance.nativeFields.length <= 100,
+                      queue: _r.queue)
+                    ..content = <Element>[
+                      new DivElement()
+                        ..classes = ['memberList']
+                        ..children = _instance.nativeFields
+                            .map<Element>((f) => new DivElement()
+                              ..classes = ['memberItem']
+                              ..children = <Element>[
+                                new DivElement()
+                                  ..classes = ['memberName']
+                                  ..text = '[ ${i++} ]',
+                                new DivElement()
+                                  ..classes = ['memberValue']
+                                  ..text = '[ ${f.value} ]'
+                              ])
+                            .toList()
+                    ])
+                  .element
             ]
         ]);
     }
@@ -420,31 +435,34 @@
           new DivElement()
             ..classes = ['memberName']
             ..children = <Element>[
-              new CurlyBlockElement(
-                  expanded: fields.length <= 100, queue: _r.queue)
-                ..content = <Element>[
-                  new DivElement()
-                    ..classes = ['memberList']
-                    ..children = fields
-                        .map<Element>((f) => new DivElement()
-                          ..classes = ['memberItem']
-                          ..children = <Element>[
-                            new DivElement()
-                              ..classes = ['memberName']
+              (new CurlyBlockElement(
+                      expanded: fields.length <= 100, queue: _r.queue)
+                    ..content = <Element>[
+                      new DivElement()
+                        ..classes = ['memberList']
+                        ..children = fields
+                            .map<Element>((f) => new DivElement()
+                              ..classes = ['memberItem']
                               ..children = <Element>[
-                                new FieldRefElement(_isolate, f.decl, _objects,
-                                    queue: _r.queue)
-                              ],
-                            new DivElement()
-                              ..classes = ['memberValue']
-                              ..children = <Element>[
-                                new SpanElement()..text = ' = ',
-                                anyRef(_isolate, f.value, _objects,
-                                    queue: _r.queue)
-                              ]
-                          ])
-                        .toList()
-                ]
+                                new DivElement()
+                                  ..classes = ['memberName']
+                                  ..children = <Element>[
+                                    new FieldRefElement(
+                                            _isolate, f.decl, _objects,
+                                            queue: _r.queue)
+                                        .element
+                                  ],
+                                new DivElement()
+                                  ..classes = ['memberValue']
+                                  ..children = <Element>[
+                                    new SpanElement()..text = ' = ',
+                                    anyRef(_isolate, f.value, _objects,
+                                        queue: _r.queue)
+                                  ]
+                              ])
+                            .toList()
+                    ])
+                  .element
             ]
         ]);
     }
@@ -461,27 +479,28 @@
           new DivElement()
             ..classes = ['memberValue']
             ..children = <Element>[
-              new CurlyBlockElement(
-                  expanded: elements.length <= 100, queue: _r.queue)
-                ..content = <Element>[
-                  new DivElement()
-                    ..classes = ['memberList']
-                    ..children = elements
-                        .map<Element>((element) => new DivElement()
-                          ..classes = ['memberItem']
-                          ..children = <Element>[
-                            new DivElement()
-                              ..classes = ['memberName']
-                              ..text = '[ ${i++} ]',
-                            new DivElement()
-                              ..classes = ['memberValue']
+              (new CurlyBlockElement(
+                      expanded: elements.length <= 100, queue: _r.queue)
+                    ..content = <Element>[
+                      new DivElement()
+                        ..classes = ['memberList']
+                        ..children = elements
+                            .map<Element>((element) => new DivElement()
+                              ..classes = ['memberItem']
                               ..children = <Element>[
-                                anyRef(_isolate, element, _objects,
-                                    queue: _r.queue)
-                              ]
-                          ])
-                        .toList()
-                ]
+                                new DivElement()
+                                  ..classes = ['memberName']
+                                  ..text = '[ ${i++} ]',
+                                new DivElement()
+                                  ..classes = ['memberValue']
+                                  ..children = <Element>[
+                                    anyRef(_isolate, element, _objects,
+                                        queue: _r.queue)
+                                  ]
+                              ])
+                            .toList()
+                    ])
+                  .element
             ]
         ]);
       if (_instance.length != elements.length) {
@@ -509,32 +528,33 @@
           new DivElement()
             ..classes = ['memberName']
             ..children = <Element>[
-              new CurlyBlockElement(
-                  expanded: associations.length <= 100, queue: _r.queue)
-                ..content = <Element>[
-                  new DivElement()
-                    ..classes = ['memberList']
-                    ..children = associations
-                        .map<Element>((a) => new DivElement()
-                          ..classes = ['memberItem']
-                          ..children = <Element>[
-                            new DivElement()
-                              ..classes = ['memberName']
+              (new CurlyBlockElement(
+                      expanded: associations.length <= 100, queue: _r.queue)
+                    ..content = <Element>[
+                      new DivElement()
+                        ..classes = ['memberList']
+                        ..children = associations
+                            .map<Element>((a) => new DivElement()
+                              ..classes = ['memberItem']
                               ..children = <Element>[
-                                new SpanElement()..text = '[ ',
-                                anyRef(_isolate, a.key, _objects,
-                                    queue: _r.queue),
-                                new SpanElement()..text = ' ]',
-                              ],
-                            new DivElement()
-                              ..classes = ['memberValue']
-                              ..children = <Element>[
-                                anyRef(_isolate, a.value, _objects,
-                                    queue: _r.queue)
-                              ]
-                          ])
-                        .toList()
-                ]
+                                new DivElement()
+                                  ..classes = ['memberName']
+                                  ..children = <Element>[
+                                    new SpanElement()..text = '[ ',
+                                    anyRef(_isolate, a.key, _objects,
+                                        queue: _r.queue),
+                                    new SpanElement()..text = ' ]',
+                                  ],
+                                new DivElement()
+                                  ..classes = ['memberValue']
+                                  ..children = <Element>[
+                                    anyRef(_isolate, a.value, _objects,
+                                        queue: _r.queue)
+                                  ]
+                              ])
+                            .toList()
+                    ])
+                  .element
             ]
         ]);
       if (_instance.length != associations.length) {
@@ -564,24 +584,25 @@
           new DivElement()
             ..classes = ['memberValue']
             ..children = <Element>[
-              new CurlyBlockElement(
-                  expanded: typedElements.length <= 100, queue: _r.queue)
-                ..content = <Element>[
-                  new DivElement()
-                    ..classes = ['memberList']
-                    ..children = typedElements
-                        .map<Element>((e) => new DivElement()
-                          ..classes = ['memberItem']
-                          ..children = <Element>[
-                            new DivElement()
-                              ..classes = ['memberName']
-                              ..text = '[ ${i++} ]',
-                            new DivElement()
-                              ..classes = ['memberValue']
-                              ..text = '$e'
-                          ])
-                        .toList()
-                ]
+              (new CurlyBlockElement(
+                      expanded: typedElements.length <= 100, queue: _r.queue)
+                    ..content = <Element>[
+                      new DivElement()
+                        ..classes = ['memberList']
+                        ..children = typedElements
+                            .map<Element>((e) => new DivElement()
+                              ..classes = ['memberItem']
+                              ..children = <Element>[
+                                new DivElement()
+                                  ..classes = ['memberName']
+                                  ..text = '[ ${i++} ]',
+                                new DivElement()
+                                  ..classes = ['memberValue']
+                                  ..text = '$e'
+                              ])
+                            .toList()
+                    ])
+                  .element
             ]
         ]);
       if (_instance.length != typedElements.length) {
@@ -643,7 +664,8 @@
               ..classes = ['memberValue']
               ..children = <Element>[
                 new FunctionRefElement(_isolate, _instance.oneByteFunction,
-                    queue: _r.queue)
+                        queue: _r.queue)
+                    .element
               ]
           ],
         new DivElement()
@@ -656,7 +678,8 @@
               ..classes = ['memberValue']
               ..children = <Element>[
                 new FunctionRefElement(_isolate, _instance.twoByteFunction,
-                    queue: _r.queue)
+                        queue: _r.queue)
+                    .element
               ]
           ],
         new DivElement()
@@ -669,8 +692,9 @@
               ..classes = ['memberValue']
               ..children = <Element>[
                 new FunctionRefElement(
-                    _isolate, _instance.externalOneByteFunction,
-                    queue: _r.queue)
+                        _isolate, _instance.externalOneByteFunction,
+                        queue: _r.queue)
+                    .element
               ]
           ],
         new DivElement()
@@ -683,8 +707,9 @@
               ..classes = ['memberValue']
               ..children = <Element>[
                 new FunctionRefElement(
-                    _isolate, _instance.externalTwoByteFunction,
-                    queue: _r.queue)
+                        _isolate, _instance.externalTwoByteFunction,
+                        queue: _r.queue)
+                    .element
               ]
           ],
         new DivElement()
@@ -697,8 +722,9 @@
               ..classes = ['memberValue']
               ..children = <Element>[
                 new InstanceRefElement(
-                    _isolate, _instance.oneByteBytecode, _objects,
-                    queue: _r.queue)
+                        _isolate, _instance.oneByteBytecode, _objects,
+                        queue: _r.queue)
+                    .element
               ]
           ],
         new DivElement()
@@ -711,8 +737,9 @@
               ..classes = ['memberValue']
               ..children = <Element>[
                 new InstanceRefElement(
-                    _isolate, _instance.twoByteBytecode, _objects,
-                    queue: _r.queue)
+                        _isolate, _instance.twoByteBytecode, _objects,
+                        queue: _r.queue)
+                    .element
               ]
           ]
       ]);
@@ -744,7 +771,8 @@
               ..classes = ['memberValue']
               ..children = <Element>[
                 new InstanceRefElement(_isolate, _instance.key, _objects,
-                    queue: _r.queue),
+                        queue: _r.queue)
+                    .element,
               ]
           ],
         new DivElement()
@@ -757,7 +785,8 @@
               ..classes = ['memberValue']
               ..children = <Element>[
                 new InstanceRefElement(_isolate, _instance.value, _objects,
-                    queue: _r.queue),
+                        queue: _r.queue)
+                    .element,
               ]
           ]
       ]);
diff --git a/runtime/observatory/lib/src/elements/isolate/counter_chart.dart b/runtime/observatory/lib/src/elements/isolate/counter_chart.dart
index 37f8098..8cdd325 100644
--- a/runtime/observatory/lib/src/elements/isolate/counter_chart.dart
+++ b/runtime/observatory/lib/src/elements/isolate/counter_chart.dart
@@ -9,7 +9,7 @@
 import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
 import 'package:observatory/src/elements/helpers/tag.dart';
 
-class IsolateCounterChartElement extends HtmlElement implements Renderable {
+class IsolateCounterChartElement extends CustomElement implements Renderable {
   static const tag =
       const Tag<IsolateCounterChartElement>('isolate-counter-chart');
 
@@ -23,13 +23,13 @@
 
   factory IsolateCounterChartElement(Map counters, {RenderingQueue queue}) {
     assert(counters != null);
-    IsolateCounterChartElement e = document.createElement(tag.name);
+    IsolateCounterChartElement e = new IsolateCounterChartElement.created();
     e._r = new RenderingScheduler<IsolateCounterChartElement>(e, queue: queue);
     e._counters = counters;
     return e;
   }
 
-  IsolateCounterChartElement.created() : super.created();
+  IsolateCounterChartElement.created() : super.created(tag);
 
   @override
   void attached() {
diff --git a/runtime/observatory/lib/src/elements/isolate/location.dart b/runtime/observatory/lib/src/elements/isolate/location.dart
index 161917e..e10e3d2 100644
--- a/runtime/observatory/lib/src/elements/isolate/location.dart
+++ b/runtime/observatory/lib/src/elements/isolate/location.dart
@@ -10,7 +10,7 @@
 import 'package:observatory/src/elements/helpers/tag.dart';
 import 'package:observatory/src/elements/source_link.dart';
 
-class IsolateLocationElement extends HtmlElement implements Renderable {
+class IsolateLocationElement extends CustomElement implements Renderable {
   static const tag = const Tag<IsolateLocationElement>('isolate-location',
       dependencies: const [FunctionRefElement.tag, SourceLinkElement.tag]);
 
@@ -30,7 +30,7 @@
     assert(isolate != null);
     assert(events != null);
     assert(scripts != null);
-    IsolateLocationElement e = document.createElement(tag.name);
+    IsolateLocationElement e = new IsolateLocationElement.created();
     e._r = new RenderingScheduler<IsolateLocationElement>(e, queue: queue);
     e._isolate = isolate;
     e._events = events;
@@ -38,7 +38,7 @@
     return e;
   }
 
-  IsolateLocationElement.created() : super.created();
+  IsolateLocationElement.created() : super.created(tag);
 
   @override
   void attached() {
@@ -66,12 +66,14 @@
         children = <Element>[
           new SpanElement()..text = 'at ',
           new FunctionRefElement(
-              _isolate, M.topFrame(_isolate.pauseEvent).function,
-              queue: _r.queue),
+                  _isolate, M.topFrame(_isolate.pauseEvent).function,
+                  queue: _r.queue)
+              .element,
           new SpanElement()..text = ' (',
           new SourceLinkElement(
-              _isolate, M.topFrame(_isolate.pauseEvent).location, _scripts,
-              queue: _r.queue),
+                  _isolate, M.topFrame(_isolate.pauseEvent).location, _scripts,
+                  queue: _r.queue)
+              .element,
           new SpanElement()..text = ') '
         ];
         break;
@@ -93,12 +95,14 @@
             content.addAll([
               new SpanElement()..text = ' at ',
               new FunctionRefElement(
-                  _isolate, M.topFrame(_isolate.pauseEvent).function,
-                  queue: _r.queue),
+                      _isolate, M.topFrame(_isolate.pauseEvent).function,
+                      queue: _r.queue)
+                  .element,
               new SpanElement()..text = ' (',
-              new SourceLinkElement(
-                  _isolate, M.topFrame(_isolate.pauseEvent).location, _scripts,
-                  queue: _r.queue),
+              new SourceLinkElement(_isolate,
+                      M.topFrame(_isolate.pauseEvent).location, _scripts,
+                      queue: _r.queue)
+                  .element,
               new SpanElement()..text = ') '
             ]);
           }
diff --git a/runtime/observatory/lib/src/elements/isolate/run_state.dart b/runtime/observatory/lib/src/elements/isolate/run_state.dart
index 6dfc005..77ff052 100644
--- a/runtime/observatory/lib/src/elements/isolate/run_state.dart
+++ b/runtime/observatory/lib/src/elements/isolate/run_state.dart
@@ -8,7 +8,7 @@
 import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
 import 'package:observatory/src/elements/helpers/tag.dart';
 
-class IsolateRunStateElement extends HtmlElement implements Renderable {
+class IsolateRunStateElement extends CustomElement implements Renderable {
   static const tag = const Tag<IsolateRunStateElement>('isolate-run-state');
 
   RenderingScheduler<IsolateRunStateElement> _r;
@@ -24,14 +24,14 @@
       {RenderingQueue queue}) {
     assert(isolate != null);
     assert(events != null);
-    IsolateRunStateElement e = document.createElement(tag.name);
+    IsolateRunStateElement e = new IsolateRunStateElement.created();
     e._r = new RenderingScheduler<IsolateRunStateElement>(e, queue: queue);
     e._isolate = isolate;
     e._events = events;
     return e;
   }
 
-  IsolateRunStateElement.created() : super.created();
+  IsolateRunStateElement.created() : super.created(tag);
 
   @override
   void attached() {
diff --git a/runtime/observatory/lib/src/elements/isolate/shared_summary.dart b/runtime/observatory/lib/src/elements/isolate/shared_summary.dart
index be163f2..652c96c 100644
--- a/runtime/observatory/lib/src/elements/isolate/shared_summary.dart
+++ b/runtime/observatory/lib/src/elements/isolate/shared_summary.dart
@@ -11,7 +11,7 @@
 import 'package:observatory/src/elements/helpers/uris.dart';
 import 'package:observatory/src/elements/isolate/counter_chart.dart';
 
-class IsolateSharedSummaryElement extends HtmlElement implements Renderable {
+class IsolateSharedSummaryElement extends CustomElement implements Renderable {
   static const tag = const Tag<IsolateSharedSummaryElement>(
       'isolate-shared-summary',
       dependencies: const [IsolateCounterChartElement.tag]);
@@ -30,14 +30,14 @@
       {RenderingQueue queue}) {
     assert(isolate != null);
     assert(events != null);
-    IsolateSharedSummaryElement e = document.createElement(tag.name);
+    IsolateSharedSummaryElement e = new IsolateSharedSummaryElement.created();
     e._r = new RenderingScheduler<IsolateSharedSummaryElement>(e, queue: queue);
     e._isolate = isolate;
     e._events = events;
     return e;
   }
 
-  IsolateSharedSummaryElement.created() : super.created();
+  IsolateSharedSummaryElement.created() : super.created(tag);
 
   @override
   void attached() {
@@ -150,7 +150,7 @@
               new AnchorElement(href: Uris.logging(_isolate))..text = 'logging'
             ]
         ],
-      new IsolateCounterChartElement(_isolate.counters, queue: _r.queue)
+      new IsolateCounterChartElement(_isolate.counters, queue: _r.queue).element
     ];
     if (_isolate.error != null) {
       children = <Element>[
diff --git a/runtime/observatory/lib/src/elements/isolate/summary.dart b/runtime/observatory/lib/src/elements/isolate/summary.dart
index 434e1fa..88c91a0 100644
--- a/runtime/observatory/lib/src/elements/isolate/summary.dart
+++ b/runtime/observatory/lib/src/elements/isolate/summary.dart
@@ -13,7 +13,7 @@
 import 'package:observatory/src/elements/isolate/run_state.dart';
 import 'package:observatory/src/elements/isolate/shared_summary.dart';
 
-class IsolateSummaryElement extends HtmlElement implements Renderable {
+class IsolateSummaryElement extends CustomElement implements Renderable {
   static const tag =
       const Tag<IsolateSummaryElement>('isolate-summary', dependencies: const [
     IsolateRefElement.tag,
@@ -42,7 +42,7 @@
     assert(isolates != null);
     assert(events != null);
     assert(scripts != null);
-    IsolateSummaryElement e = document.createElement(tag.name);
+    IsolateSummaryElement e = new IsolateSummaryElement.created();
     e._r = new RenderingScheduler<IsolateSummaryElement>(e, queue: queue);
     e._isolate = isolate;
     e._isolates = isolates;
@@ -51,7 +51,7 @@
     return e;
   }
 
-  IsolateSummaryElement.created() : super.created();
+  IsolateSummaryElement.created() : super.created(tag);
 
   @override
   void attached() {
@@ -71,7 +71,7 @@
     if (_loadedIsolate == null) {
       children = <Element>[
         new SpanElement()..text = 'loading ',
-        new IsolateRefElement(_isolate, _events, queue: _r.queue)
+        new IsolateRefElement(_isolate, _events, queue: _r.queue).element
       ];
     } else {
       children = <Element>[
@@ -82,14 +82,17 @@
               ..classes = ['isolate-ref-container']
               ..children = <Element>[
                 new IsolateRefElement(_isolate, _events, queue: _r.queue)
+                    .element
               ],
             new DivElement()..style.flex = '1',
             new DivElement()
               ..classes = ['flex-row', 'isolate-state-container']
               ..children = <Element>[
-                new IsolateRunStateElement(_isolate, _events, queue: _r.queue),
+                new IsolateRunStateElement(_isolate, _events, queue: _r.queue)
+                    .element,
                 new IsolateLocationElement(_isolate, _events, _scripts,
-                    queue: _r.queue),
+                        queue: _r.queue)
+                    .element,
                 new SpanElement()..text = ' [',
                 new AnchorElement(href: Uris.debugger(_isolate))
                   ..text = 'debug',
@@ -98,6 +101,7 @@
           ],
         new BRElement(),
         new IsolateSharedSummaryElement(_isolate, _events, queue: _r.queue)
+            .element
       ];
     }
   }
diff --git a/runtime/observatory/lib/src/elements/isolate_reconnect.dart b/runtime/observatory/lib/src/elements/isolate_reconnect.dart
index 0820d41..bf72f2f 100644
--- a/runtime/observatory/lib/src/elements/isolate_reconnect.dart
+++ b/runtime/observatory/lib/src/elements/isolate_reconnect.dart
@@ -15,7 +15,7 @@
 import 'package:observatory/src/elements/nav/top_menu.dart';
 import 'package:observatory/src/elements/view_footer.dart';
 
-class IsolateReconnectElement extends HtmlElement implements Renderable {
+class IsolateReconnectElement extends CustomElement implements Renderable {
   static const tag = const Tag<IsolateReconnectElement>('isolate-reconnect',
       dependencies: const [
         NavTopMenuElement.tag,
@@ -47,7 +47,7 @@
     assert(missing != null);
     assert(uri != null);
     assert(notifications != null);
-    IsolateReconnectElement e = document.createElement(tag.name);
+    IsolateReconnectElement e = new IsolateReconnectElement.created();
     e._r = new RenderingScheduler<IsolateReconnectElement>(e, queue: queue);
     e._vm = vm;
     e._events = events;
@@ -57,7 +57,7 @@
     return e;
   }
 
-  IsolateReconnectElement.created() : super.created();
+  IsolateReconnectElement.created() : super.created(tag);
 
   @override
   void attached() {
@@ -80,8 +80,8 @@
   void render() {
     children = <Element>[
       navBar(<Element>[
-        new NavTopMenuElement(queue: _r.queue),
-        new NavNotifyElement(_notifications, queue: _r.queue)
+        new NavTopMenuElement(queue: _r.queue).element,
+        new NavNotifyElement(_notifications, queue: _r.queue).element
       ]),
       new DivElement()
         ..classes = ['content-centered']
@@ -111,7 +111,7 @@
                   new AnchorElement(href: Uris.vm())..text = 'isolates summary',
                 ]))
         ],
-      new ViewFooterElement(queue: _r.queue)
+      new ViewFooterElement(queue: _r.queue).element
     ];
   }
 }
diff --git a/runtime/observatory/lib/src/elements/isolate_ref.dart b/runtime/observatory/lib/src/elements/isolate_ref.dart
index 49a2182..32e32a4 100644
--- a/runtime/observatory/lib/src/elements/isolate_ref.dart
+++ b/runtime/observatory/lib/src/elements/isolate_ref.dart
@@ -11,7 +11,7 @@
 import 'package:observatory/src/elements/helpers/tag.dart';
 import 'package:observatory/src/elements/helpers/uris.dart';
 
-class IsolateRefElement extends HtmlElement implements Renderable {
+class IsolateRefElement extends CustomElement implements Renderable {
   static const tag = const Tag<IsolateRefElement>('isolate-ref');
 
   RenderingScheduler<IsolateRefElement> _r;
@@ -28,14 +28,14 @@
       {RenderingQueue queue}) {
     assert(isolate != null);
     assert(events != null);
-    IsolateRefElement e = document.createElement(tag.name);
+    IsolateRefElement e = new IsolateRefElement.created();
     e._r = new RenderingScheduler<IsolateRefElement>(e, queue: queue);
     e._isolate = isolate;
     e._events = events;
     return e;
   }
 
-  IsolateRefElement.created() : super.created();
+  IsolateRefElement.created() : super.created(tag);
 
   @override
   void attached() {
diff --git a/runtime/observatory/lib/src/elements/isolate_view.dart b/runtime/observatory/lib/src/elements/isolate_view.dart
index 01f5b60..9db502b 100644
--- a/runtime/observatory/lib/src/elements/isolate_view.dart
+++ b/runtime/observatory/lib/src/elements/isolate_view.dart
@@ -30,7 +30,7 @@
 import 'package:observatory/src/elements/view_footer.dart';
 import 'package:observatory/utils.dart';
 
-class IsolateViewElement extends HtmlElement implements Renderable {
+class IsolateViewElement extends CustomElement implements Renderable {
   static const tag =
       const Tag<IsolateViewElement>('isolate-view', dependencies: const [
     CurlyBlockElement.tag,
@@ -95,7 +95,7 @@
     assert(objects != null);
     assert(eval != null);
     assert(libraries != null);
-    IsolateViewElement e = document.createElement(tag.name);
+    IsolateViewElement e = new IsolateViewElement.created();
     e._r = new RenderingScheduler<IsolateViewElement>(e, queue: queue);
     e._vm = vm;
     e._isolate = isolate;
@@ -110,7 +110,7 @@
     return e;
   }
 
-  IsolateViewElement.created() : super.created();
+  IsolateViewElement.created() : super.created(tag);
 
   @override
   attached() {
@@ -139,23 +139,25 @@
     final List<M.Thread> threads = _isolate.threads;
     children = <Element>[
       navBar(<Element>[
-        new NavTopMenuElement(queue: _r.queue),
-        new NavVMMenuElement(_vm, _events, queue: _r.queue),
-        new NavIsolateMenuElement(_isolate, _events, queue: _r.queue),
-        new NavReloadElement(_isolate, _isolates, _events, queue: _r.queue)
-          ..onReload.listen((_) async {
-            _isolate = await _isolates.get(_isolate);
-            await _loadExtraData();
-            _r.dirty();
-          }),
-        new NavRefreshElement(queue: _r.queue)
-          ..onRefresh.listen((e) async {
-            e.element.disabled = true;
-            _isolate = await _isolates.get(_isolate);
-            await _loadExtraData();
-            _r.dirty();
-          }),
-        new NavNotifyElement(_notifications, queue: _r.queue)
+        new NavTopMenuElement(queue: _r.queue).element,
+        new NavVMMenuElement(_vm, _events, queue: _r.queue).element,
+        new NavIsolateMenuElement(_isolate, _events, queue: _r.queue).element,
+        (new NavReloadElement(_isolate, _isolates, _events, queue: _r.queue)
+              ..onReload.listen((_) async {
+                _isolate = await _isolates.get(_isolate);
+                await _loadExtraData();
+                _r.dirty();
+              }))
+            .element,
+        (new NavRefreshElement(queue: _r.queue)
+              ..onRefresh.listen((e) async {
+                e.element.disabled = true;
+                _isolate = await _isolates.get(_isolate);
+                await _loadExtraData();
+                _r.dirty();
+              }))
+            .element,
+        new NavNotifyElement(_notifications, queue: _r.queue).element
       ]),
       new DivElement()
         ..classes = ['content-centered-big']
@@ -168,10 +170,11 @@
               new DivElement()..style.flex = '1',
               new DivElement()
                 ..children = <Element>[
-                  new IsolateRunStateElement(_isolate, _events,
-                      queue: _r.queue),
+                  new IsolateRunStateElement(_isolate, _events, queue: _r.queue)
+                      .element,
                   new IsolateLocationElement(_isolate, _events, _scripts,
-                      queue: _r.queue),
+                          queue: _r.queue)
+                      .element,
                   new SpanElement()..text = ' [',
                   new AnchorElement(href: Uris.debugger(_isolate))
                     ..text = 'debug',
@@ -182,16 +185,20 @@
             ..children = _function != null
                 ? [
                     new BRElement(),
-                    new SourceInsetElement(_isolate, _function.location,
-                        _scripts, _objects, _events,
-                        currentPos:
-                            M.topFrame(isolate.pauseEvent).location.tokenPos,
-                        queue: _r.queue)
-                      ..classes = ['header_inset']
+                    (new SourceInsetElement(_isolate, _function.location,
+                            _scripts, _objects, _events,
+                            currentPos: M
+                                .topFrame(isolate.pauseEvent)
+                                .location
+                                .tokenPos,
+                            queue: _r.queue)
+                          ..classes = ['header_inset'])
+                        .element
                   ]
                 : const [],
           new HRElement(),
-          new IsolateSharedSummaryElement(_isolate, _events, queue: _r.queue),
+          new IsolateSharedSummaryElement(_isolate, _events, queue: _r.queue)
+              .element,
           new HRElement(),
           new DivElement()
             ..classes = ['memberList']
@@ -228,8 +235,9 @@
                       _isolate.rootLibrary == null
                           ? (new SpanElement()..text = 'loading...')
                           : new LibraryRefElement(
-                              _isolate, _isolate.rootLibrary,
-                              queue: _r.queue)
+                                  _isolate, _isolate.rootLibrary,
+                                  queue: _r.queue)
+                              .element
                     ]
                 ],
               new DivElement()
@@ -243,7 +251,8 @@
                           ..classes = ['memberValue']
                           ..children = <Element>[
                             new FunctionRefElement(_isolate, _isolate.entry,
-                                queue: _r.queue)
+                                    queue: _r.queue)
+                                .element
                           ]
                       ]
                     : const [],
@@ -323,14 +332,16 @@
                   new DivElement()
                     ..classes = ['memberValue']
                     ..children = <Element>[
-                      new CurlyBlockElement(queue: _r.queue)
-                        ..content = libraries
-                            .map<Element>((l) => new DivElement()
-                              ..children = <Element>[
-                                new LibraryRefElement(_isolate, l,
-                                    queue: _r.queue)
-                              ])
-                            .toList()
+                      (new CurlyBlockElement(queue: _r.queue)
+                            ..content = libraries
+                                .map<Element>((l) => new DivElement()
+                                  ..children = <Element>[
+                                    new LibraryRefElement(_isolate, l,
+                                            queue: _r.queue)
+                                        .element
+                                  ])
+                                .toList())
+                          .element
                     ]
                 ],
               new DivElement()
@@ -342,25 +353,29 @@
                   new DivElement()
                     ..classes = ['memberValue']
                     ..children = <Element>[
-                      new CurlyBlockElement(queue: _r.queue)
-                        ..content = threads.map<Element>(_populateThreadInfo)
+                      (new CurlyBlockElement(queue: _r.queue)
+                            ..content =
+                                threads.map<Element>(_populateThreadInfo))
+                          .element
                     ]
                 ]
             ],
           new HRElement(),
           new EvalBoxElement(_isolate, _isolate.rootLibrary, _objects, _eval,
-              queue: _r.queue),
+                  queue: _r.queue)
+              .element,
           new DivElement()
             ..children = _rootScript != null
                 ? [
                     new HRElement(),
                     new ScriptInsetElement(
-                        _isolate, _rootScript, _scripts, _objects, _events,
-                        queue: _r.queue)
+                            _isolate, _rootScript, _scripts, _objects, _events,
+                            queue: _r.queue)
+                        .element
                   ]
                 : const [],
           new HRElement(),
-          new ViewFooterElement(queue: _r.queue)
+          new ViewFooterElement(queue: _r.queue).element
         ]
     ];
   }
@@ -370,22 +385,23 @@
       ..classes = ['indent']
       ..children = <Element>[
         new SpanElement()..text = '${t.id} ',
-        new CurlyBlockElement(queue: _r.queue)
-          ..content = <Element>[
-            new DivElement()
-              ..classes = ['indent']
-              ..text = 'kind ${t.kindString}',
-            new DivElement()
-              ..classes = ['indent']
-              ..title = '${t.zoneHighWatermark}B'
-              ..text = 'zone capacity high watermark '
-                  '${Utils.formatSize(t.zoneHighWatermark)}',
-            new DivElement()
-              ..classes = ['indent']
-              ..title = '${t.zoneCapacity}B'
-              ..text = 'current zone capacity ' +
-                  '${Utils.formatSize(t.zoneCapacity)}',
-          ]
+        (new CurlyBlockElement(queue: _r.queue)
+              ..content = <Element>[
+                new DivElement()
+                  ..classes = ['indent']
+                  ..text = 'kind ${t.kindString}',
+                new DivElement()
+                  ..classes = ['indent']
+                  ..title = '${t.zoneHighWatermark}B'
+                  ..text = 'zone capacity high watermark '
+                      '${Utils.formatSize(t.zoneHighWatermark)}',
+                new DivElement()
+                  ..classes = ['indent']
+                  ..title = '${t.zoneCapacity}B'
+                  ..text = 'current zone capacity ' +
+                      '${Utils.formatSize(t.zoneCapacity)}',
+              ])
+            .element
       ];
   }
 
diff --git a/runtime/observatory/lib/src/elements/json_view.dart b/runtime/observatory/lib/src/elements/json_view.dart
index 6b452ef..7f1474b 100644
--- a/runtime/observatory/lib/src/elements/json_view.dart
+++ b/runtime/observatory/lib/src/elements/json_view.dart
@@ -14,7 +14,7 @@
 import 'package:observatory/src/elements/nav/top_menu.dart';
 import 'package:observatory/src/elements/view_footer.dart';
 
-class JSONViewElement extends HtmlElement implements Renderable {
+class JSONViewElement extends CustomElement implements Renderable {
   static const tag = const Tag<JSONViewElement>('json-view',
       dependencies: const [
         NavTopMenuElement.tag,
@@ -36,14 +36,14 @@
       {RenderingQueue queue}) {
     assert(notifications != null);
     assert(map != null);
-    JSONViewElement e = document.createElement(tag.name);
+    JSONViewElement e = new JSONViewElement.created();
     e._r = new RenderingScheduler<JSONViewElement>(e, queue: queue);
     e._notifications = notifications;
     e._map = map;
     return e;
   }
 
-  JSONViewElement.created() : super.created();
+  JSONViewElement.created() : super.created(tag);
 
   @override
   attached() {
@@ -61,8 +61,8 @@
   void render() {
     children = <Element>[
       navBar(<Element>[
-        new NavTopMenuElement(queue: _r.queue),
-        new NavNotifyElement(_notifications, queue: _r.queue)
+        new NavTopMenuElement(queue: _r.queue).element,
+        new NavNotifyElement(_notifications, queue: _r.queue).element
       ]),
       new DivElement()
         ..classes = ['content-centered-big']
@@ -71,7 +71,7 @@
           new HRElement(),
           new PreElement()..text = JSONPretty.stringify(_map),
           new HRElement(),
-          new ViewFooterElement(queue: _r.queue)
+          new ViewFooterElement(queue: _r.queue).element
         ]
     ];
   }
diff --git a/runtime/observatory/lib/src/elements/library_ref.dart b/runtime/observatory/lib/src/elements/library_ref.dart
index dcfe17a..a6d3ba8 100644
--- a/runtime/observatory/lib/src/elements/library_ref.dart
+++ b/runtime/observatory/lib/src/elements/library_ref.dart
@@ -11,7 +11,7 @@
 import 'package:observatory/src/elements/helpers/tag.dart';
 import 'package:observatory/src/elements/helpers/uris.dart';
 
-class LibraryRefElement extends HtmlElement implements Renderable {
+class LibraryRefElement extends CustomElement implements Renderable {
   static const tag = const Tag<LibraryRefElement>('library-ref');
 
   RenderingScheduler<LibraryRefElement> _r;
@@ -28,14 +28,14 @@
       {RenderingQueue queue}) {
     assert(isolate != null);
     assert(library != null);
-    LibraryRefElement e = document.createElement(tag.name);
+    LibraryRefElement e = new LibraryRefElement.created();
     e._r = new RenderingScheduler<LibraryRefElement>(e, queue: queue);
     e._isolate = isolate;
     e._library = library;
     return e;
   }
 
-  LibraryRefElement.created() : super.created();
+  LibraryRefElement.created() : super.created(tag);
 
   @override
   void attached() {
diff --git a/runtime/observatory/lib/src/elements/library_view.dart b/runtime/observatory/lib/src/elements/library_view.dart
index 2f9f2d4..c452e4d 100644
--- a/runtime/observatory/lib/src/elements/library_view.dart
+++ b/runtime/observatory/lib/src/elements/library_view.dart
@@ -28,7 +28,7 @@
 import 'package:observatory/src/elements/script_inset.dart';
 import 'package:observatory/src/elements/view_footer.dart';
 
-class LibraryViewElement extends HtmlElement implements Renderable {
+class LibraryViewElement extends CustomElement implements Renderable {
   static const tag =
       const Tag<LibraryViewElement>('library-view', dependencies: const [
     ClassRefElement.tag,
@@ -104,7 +104,7 @@
     assert(scripts != null);
     assert(objects != null);
     assert(eval != null);
-    LibraryViewElement e = document.createElement(tag.name);
+    LibraryViewElement e = new LibraryViewElement.created();
     e._r = new RenderingScheduler<LibraryViewElement>(e, queue: queue);
     e._vm = vm;
     e._isolate = isolate;
@@ -123,7 +123,7 @@
     return e;
   }
 
-  LibraryViewElement.created() : super.created();
+  LibraryViewElement.created() : super.created(tag);
 
   @override
   attached() {
@@ -142,16 +142,17 @@
   void render() {
     children = <Element>[
       navBar(<Element>[
-        new NavTopMenuElement(queue: _r.queue),
-        new NavVMMenuElement(_vm, _events, queue: _r.queue),
-        new NavIsolateMenuElement(_isolate, _events, queue: _r.queue),
-        new NavLibraryMenuElement(_isolate, _library, queue: _r.queue),
-        new NavRefreshElement(queue: _r.queue)
-          ..onRefresh.listen((e) async {
-            e.element.disabled = true;
-            _refresh();
-          }),
-        new NavNotifyElement(_notifications, queue: _r.queue)
+        new NavTopMenuElement(queue: _r.queue).element,
+        new NavVMMenuElement(_vm, _events, queue: _r.queue).element,
+        new NavIsolateMenuElement(_isolate, _events, queue: _r.queue).element,
+        new NavLibraryMenuElement(_isolate, _library, queue: _r.queue).element,
+        (new NavRefreshElement(queue: _r.queue)
+              ..onRefresh.listen((e) async {
+                e.element.disabled = true;
+                _refresh();
+              }))
+            .element,
+        new NavNotifyElement(_notifications, queue: _r.queue).element
       ]),
       new DivElement()
         ..classes = ['content-centered-big']
@@ -159,8 +160,9 @@
           new HeadingElement.h2()..text = 'Library',
           new HRElement(),
           new ObjectCommonElement(_isolate, _library, _retainedSizes,
-              _reachableSizes, _references, _retainingPaths, _objects,
-              queue: _r.queue),
+                  _reachableSizes, _references, _retainingPaths, _objects,
+                  queue: _r.queue)
+              .element,
           new DivElement()
             ..classes = ['memberList']
             ..children = <Element>[
@@ -187,7 +189,8 @@
             ],
           new HRElement(),
           new EvalBoxElement(_isolate, _library, _objects, _eval,
-              queue: _r.queue),
+                  queue: _r.queue)
+              .element,
           new HRElement(),
           _createDependencies(),
           new BRElement(),
@@ -200,10 +203,11 @@
           _createFunctions(),
           new HRElement(),
           new ScriptInsetElement(
-              _isolate, _library.rootScript, _scripts, _objects, _events,
-              queue: _r.queue),
+                  _isolate, _library.rootScript, _scripts, _objects, _events,
+                  queue: _r.queue)
+              .element,
           new HRElement(),
-          new ViewFooterElement(queue: _r.queue)
+          new ViewFooterElement(queue: _r.queue).element
         ]
     ];
   }
@@ -225,18 +229,21 @@
     return new DivElement()
       ..children = <Element>[
         new SpanElement()..text = 'dependencies (${dependencies.length}) ',
-        new CurlyBlockElement(queue: _r.queue)
-          ..content = dependencies
-              .map<Element>((d) => new DivElement()
-                ..classes = ['indent']
-                ..children = <Element>[
-                  new SpanElement()..text = d.isImport ? 'import ' : 'export ',
-                  new LibraryRefElement(_isolate, d.target, queue: _r.queue),
-                  new SpanElement()
-                    ..text = d.prefix == null ? '' : ' as ${d.prefix}',
-                  new SpanElement()..text = d.isDeferred ? ' deferred' : '',
-                ])
-              .toList()
+        (new CurlyBlockElement(queue: _r.queue)
+              ..content = dependencies
+                  .map<Element>((d) => new DivElement()
+                    ..classes = ['indent']
+                    ..children = <Element>[
+                      new SpanElement()
+                        ..text = d.isImport ? 'import ' : 'export ',
+                      new LibraryRefElement(_isolate, d.target, queue: _r.queue)
+                          .element,
+                      new SpanElement()
+                        ..text = d.prefix == null ? '' : ' as ${d.prefix}',
+                      new SpanElement()..text = d.isDeferred ? ' deferred' : '',
+                    ])
+                  .toList())
+            .element
       ];
   }
 
@@ -248,14 +255,15 @@
     return new DivElement()
       ..children = <Element>[
         new SpanElement()..text = 'scripts (${scripts.length}) ',
-        new CurlyBlockElement(queue: _r.queue)
-          ..content = scripts
-              .map<Element>((s) => new DivElement()
-                ..classes = ['indent']
-                ..children = <Element>[
-                  new ScriptRefElement(_isolate, s, queue: _r.queue)
-                ])
-              .toList()
+        (new CurlyBlockElement(queue: _r.queue)
+              ..content = scripts
+                  .map<Element>((s) => new DivElement()
+                    ..classes = ['indent']
+                    ..children = <Element>[
+                      new ScriptRefElement(_isolate, s, queue: _r.queue).element
+                    ])
+                  .toList())
+            .element
       ];
   }
 
@@ -267,14 +275,15 @@
     return new DivElement()
       ..children = <Element>[
         new SpanElement()..text = 'classes (${classes.length}) ',
-        new CurlyBlockElement(queue: _r.queue)
-          ..content = classes
-              .map<Element>((c) => new DivElement()
-                ..classes = ['indent']
-                ..children = <Element>[
-                  new ClassRefElement(_isolate, c, queue: _r.queue)
-                ])
-              .toList()
+        (new CurlyBlockElement(queue: _r.queue)
+              ..content = classes
+                  .map<Element>((c) => new DivElement()
+                    ..classes = ['indent']
+                    ..children = <Element>[
+                      new ClassRefElement(_isolate, c, queue: _r.queue).element
+                    ])
+                  .toList())
+            .element
       ];
   }
 
@@ -286,32 +295,34 @@
     return new DivElement()
       ..children = <Element>[
         new SpanElement()..text = 'variables (${variables.length}) ',
-        new CurlyBlockElement(queue: _r.queue)
-          ..content = <Element>[
-            _variables == null
-                ? (new SpanElement()..text = 'loading...')
-                : (new DivElement()
-                  ..classes = ['indent', 'memberList']
-                  ..children = _variables
-                      .map<Element>((f) => new DivElement()
-                        ..classes = ['memberItem']
-                        ..children = <Element>[
-                          new DivElement()
-                            ..classes = ['memberName']
+        (new CurlyBlockElement(queue: _r.queue)
+              ..content = <Element>[
+                _variables == null
+                    ? (new SpanElement()..text = 'loading...')
+                    : (new DivElement()
+                      ..classes = ['indent', 'memberList']
+                      ..children = _variables
+                          .map<Element>((f) => new DivElement()
+                            ..classes = ['memberItem']
                             ..children = <Element>[
-                              new FieldRefElement(_isolate, f, _objects,
-                                  queue: _r.queue)
-                            ],
-                          new DivElement()
-                            ..classes = ['memberValue']
-                            ..children = <Element>[
-                              new SpanElement()..text = ' = ',
-                              anyRef(_isolate, f.staticValue, _objects,
-                                  queue: _r.queue)
-                            ]
-                        ])
-                      .toList())
-          ]
+                              new DivElement()
+                                ..classes = ['memberName']
+                                ..children = <Element>[
+                                  new FieldRefElement(_isolate, f, _objects,
+                                          queue: _r.queue)
+                                      .element
+                                ],
+                              new DivElement()
+                                ..classes = ['memberValue']
+                                ..children = <Element>[
+                                  new SpanElement()..text = ' = ',
+                                  anyRef(_isolate, f.staticValue, _objects,
+                                      queue: _r.queue)
+                                ]
+                            ])
+                          .toList())
+              ])
+            .element
       ];
   }
 
@@ -323,14 +334,16 @@
     return new DivElement()
       ..children = <Element>[
         new SpanElement()..text = 'functions (${functions.length}) ',
-        new CurlyBlockElement(queue: _r.queue)
-          ..content = functions
-              .map<Element>((f) => new DivElement()
-                ..classes = ['indent']
-                ..children = <Element>[
-                  new FunctionRefElement(_isolate, f, queue: _r.queue)
-                ])
-              .toList()
+        (new CurlyBlockElement(queue: _r.queue)
+              ..content = functions
+                  .map<Element>((f) => new DivElement()
+                    ..classes = ['indent']
+                    ..children = <Element>[
+                      new FunctionRefElement(_isolate, f, queue: _r.queue)
+                          .element
+                    ])
+                  .toList())
+            .element
       ];
   }
 }
diff --git a/runtime/observatory/lib/src/elements/local_var_descriptors_ref.dart b/runtime/observatory/lib/src/elements/local_var_descriptors_ref.dart
index 578a148..e5afd63 100644
--- a/runtime/observatory/lib/src/elements/local_var_descriptors_ref.dart
+++ b/runtime/observatory/lib/src/elements/local_var_descriptors_ref.dart
@@ -10,7 +10,8 @@
 import 'package:observatory/src/elements/helpers/tag.dart';
 import 'package:observatory/src/elements/helpers/uris.dart';
 
-class LocalVarDescriptorsRefElement extends HtmlElement implements Renderable {
+class LocalVarDescriptorsRefElement extends CustomElement
+    implements Renderable {
   static const tag = const Tag<LocalVarDescriptorsRefElement>('var-ref');
 
   RenderingScheduler<LocalVarDescriptorsRefElement> _r;
@@ -29,7 +30,8 @@
       {RenderingQueue queue}) {
     assert(isolate != null);
     assert(localVar != null);
-    LocalVarDescriptorsRefElement e = document.createElement(tag.name);
+    LocalVarDescriptorsRefElement e =
+        new LocalVarDescriptorsRefElement.created();
     e._r =
         new RenderingScheduler<LocalVarDescriptorsRefElement>(e, queue: queue);
     e._isolate = isolate;
@@ -37,7 +39,7 @@
     return e;
   }
 
-  LocalVarDescriptorsRefElement.created() : super.created();
+  LocalVarDescriptorsRefElement.created() : super.created(tag);
 
   @override
   void attached() {
diff --git a/runtime/observatory/lib/src/elements/logging.dart b/runtime/observatory/lib/src/elements/logging.dart
index 8e168fa..5237010 100644
--- a/runtime/observatory/lib/src/elements/logging.dart
+++ b/runtime/observatory/lib/src/elements/logging.dart
@@ -21,7 +21,7 @@
 import 'package:observatory/src/elements/nav/vm_menu.dart';
 import 'package:observatory/src/elements/view_footer.dart';
 
-class LoggingPageElement extends HtmlElement implements Renderable {
+class LoggingPageElement extends CustomElement implements Renderable {
   static const tag =
       const Tag<LoggingPageElement>('logging-page', dependencies: const [
     LoggingListElement.tag,
@@ -55,7 +55,7 @@
     assert(isolate != null);
     assert(events != null);
     assert(notifications != null);
-    LoggingPageElement e = document.createElement(tag.name);
+    LoggingPageElement e = new LoggingPageElement.created();
     e._r = new RenderingScheduler<LoggingPageElement>(e, queue: queue);
     e._vm = vm;
     e._isolate = isolate;
@@ -64,7 +64,7 @@
     return e;
   }
 
-  LoggingPageElement.created() : super.created();
+  LoggingPageElement.created() : super.created(tag);
 
   @override
   attached() {
@@ -86,17 +86,18 @@
     _logs.level = _level;
     children = <Element>[
       navBar(<Element>[
-        new NavTopMenuElement(queue: _r.queue),
-        new NavVMMenuElement(_vm, _events, queue: _r.queue),
-        new NavIsolateMenuElement(_isolate, _events, queue: _r.queue),
+        new NavTopMenuElement(queue: _r.queue).element,
+        new NavVMMenuElement(_vm, _events, queue: _r.queue).element,
+        new NavIsolateMenuElement(_isolate, _events, queue: _r.queue).element,
         navMenu('logging'),
-        new NavRefreshElement(label: 'clear', queue: _r.queue)
-          ..onRefresh.listen((e) async {
-            e.element.disabled = true;
-            _logs = null;
-            _r.dirty();
-          }),
-        new NavNotifyElement(_notifications, queue: _r.queue)
+        (new NavRefreshElement(label: 'clear', queue: _r.queue)
+              ..onRefresh.listen((e) async {
+                e.element.disabled = true;
+                _logs = null;
+                _r.dirty();
+              }))
+            .element,
+        new NavNotifyElement(_notifications, queue: _r.queue).element
       ]),
       new DivElement()
         ..classes = ['content-centered-big']
@@ -105,7 +106,7 @@
           new SpanElement()..text = 'Show messages with severity ',
           _createLevelSelector(),
           new HRElement(),
-          _logs
+          _logs.element
         ]
     ];
   }
diff --git a/runtime/observatory/lib/src/elements/logging_list.dart b/runtime/observatory/lib/src/elements/logging_list.dart
index ac9c728..4f935ee 100644
--- a/runtime/observatory/lib/src/elements/logging_list.dart
+++ b/runtime/observatory/lib/src/elements/logging_list.dart
@@ -10,7 +10,7 @@
 import 'package:observatory/src/elements/helpers/tag.dart';
 import 'package:observatory/utils.dart';
 
-class LoggingListElement extends HtmlElement implements Renderable {
+class LoggingListElement extends CustomElement implements Renderable {
   static const tag = const Tag<LoggingListElement>('logging-list');
 
   RenderingScheduler<LoggingListElement> _r;
@@ -32,14 +32,14 @@
       {RenderingQueue queue}) {
     assert(isolate != null);
     assert(events != null);
-    LoggingListElement e = document.createElement(tag.name);
+    LoggingListElement e = new LoggingListElement.created();
     e._r = new RenderingScheduler<LoggingListElement>(e, queue: queue);
     e._isolate = isolate;
     e._events = events;
     return e;
   }
 
-  LoggingListElement.created() : super.created();
+  LoggingListElement.created() : super.created(tag);
 
   @override
   attached() {
diff --git a/runtime/observatory/lib/src/elements/megamorphiccache_ref.dart b/runtime/observatory/lib/src/elements/megamorphiccache_ref.dart
index b7eb6c2..d93696e 100644
--- a/runtime/observatory/lib/src/elements/megamorphiccache_ref.dart
+++ b/runtime/observatory/lib/src/elements/megamorphiccache_ref.dart
@@ -10,7 +10,7 @@
 import 'package:observatory/src/elements/helpers/tag.dart';
 import 'package:observatory/src/elements/helpers/uris.dart';
 
-class MegamorphicCacheRefElement extends HtmlElement implements Renderable {
+class MegamorphicCacheRefElement extends CustomElement implements Renderable {
   static const tag =
       const Tag<MegamorphicCacheRefElement>('megamorphic-cache-ref');
 
@@ -30,14 +30,14 @@
       {RenderingQueue queue}) {
     assert(isolate != null);
     assert(cache != null);
-    MegamorphicCacheRefElement e = document.createElement(tag.name);
+    MegamorphicCacheRefElement e = new MegamorphicCacheRefElement.created();
     e._r = new RenderingScheduler<MegamorphicCacheRefElement>(e, queue: queue);
     e._isolate = isolate;
     e._cache = cache;
     return e;
   }
 
-  MegamorphicCacheRefElement.created() : super.created();
+  MegamorphicCacheRefElement.created() : super.created(tag);
 
   @override
   void attached() {
diff --git a/runtime/observatory/lib/src/elements/megamorphiccache_view.dart b/runtime/observatory/lib/src/elements/megamorphiccache_view.dart
index 5a35092..698ea59 100644
--- a/runtime/observatory/lib/src/elements/megamorphiccache_view.dart
+++ b/runtime/observatory/lib/src/elements/megamorphiccache_view.dart
@@ -22,7 +22,7 @@
 import 'package:observatory/src/elements/object_common.dart';
 import 'package:observatory/src/elements/view_footer.dart';
 
-class MegamorphicCacheViewElement extends HtmlElement implements Renderable {
+class MegamorphicCacheViewElement extends CustomElement implements Renderable {
   static const tag = const Tag<MegamorphicCacheViewElement>(
       'megamorphiccache-view',
       dependencies: const [
@@ -83,7 +83,7 @@
     assert(references != null);
     assert(retainingPaths != null);
     assert(objects != null);
-    MegamorphicCacheViewElement e = document.createElement(tag.name);
+    MegamorphicCacheViewElement e = new MegamorphicCacheViewElement.created();
     e._r = new RenderingScheduler<MegamorphicCacheViewElement>(e, queue: queue);
     e._vm = vm;
     e._isolate = isolate;
@@ -99,7 +99,7 @@
     return e;
   }
 
-  MegamorphicCacheViewElement.created() : super.created();
+  MegamorphicCacheViewElement.created() : super.created(tag);
 
   @override
   attached() {
@@ -117,17 +117,18 @@
   void render() {
     children = <Element>[
       navBar(<Element>[
-        new NavTopMenuElement(queue: _r.queue),
-        new NavVMMenuElement(_vm, _events, queue: _r.queue),
-        new NavIsolateMenuElement(_isolate, _events, queue: _r.queue),
+        new NavTopMenuElement(queue: _r.queue).element,
+        new NavVMMenuElement(_vm, _events, queue: _r.queue).element,
+        new NavIsolateMenuElement(_isolate, _events, queue: _r.queue).element,
         navMenu('megamorphic inline cache'),
-        new NavRefreshElement(queue: _r.queue)
-          ..onRefresh.listen((e) async {
-            e.element.disabled = true;
-            _cache = await _caches.get(_isolate, _cache.id);
-            _r.dirty();
-          }),
-        new NavNotifyElement(_notifications, queue: _r.queue)
+        (new NavRefreshElement(queue: _r.queue)
+              ..onRefresh.listen((e) async {
+                e.element.disabled = true;
+                _cache = await _caches.get(_isolate, _cache.id);
+                _r.dirty();
+              }))
+            .element,
+        new NavNotifyElement(_notifications, queue: _r.queue).element
       ]),
       new DivElement()
         ..classes = ['content-centered-big']
@@ -135,8 +136,9 @@
           new HeadingElement.h2()..text = 'Megamorphic Cache',
           new HRElement(),
           new ObjectCommonElement(_isolate, _cache, _retainedSizes,
-              _reachableSizes, _references, _retainingPaths, _objects,
-              queue: _r.queue),
+                  _reachableSizes, _references, _retainingPaths, _objects,
+                  queue: _r.queue)
+              .element,
           new BRElement(),
           new DivElement()
             ..classes = ['memberList']
@@ -189,7 +191,7 @@
                 ]
             ],
           new HRElement(),
-          new ViewFooterElement(queue: _r.queue)
+          new ViewFooterElement(queue: _r.queue).element
         ]
     ];
   }
diff --git a/runtime/observatory/lib/src/elements/memory/allocations.dart b/runtime/observatory/lib/src/elements/memory/allocations.dart
index 1d8c4ba..11ff282 100644
--- a/runtime/observatory/lib/src/elements/memory/allocations.dart
+++ b/runtime/observatory/lib/src/elements/memory/allocations.dart
@@ -30,7 +30,7 @@
 
 enum _SortingDirection { ascending, descending }
 
-class MemoryAllocationsElement extends HtmlElement implements Renderable {
+class MemoryAllocationsElement extends CustomElement implements Renderable {
   static const tag = const Tag<MemoryAllocationsElement>('memory-allocations',
       dependencies: const [ClassRefElement.tag, VirtualCollectionElement.tag]);
 
@@ -54,7 +54,7 @@
     assert(isolate != null);
     assert(editor != null);
     assert(repository != null);
-    MemoryAllocationsElement e = document.createElement(tag.name);
+    MemoryAllocationsElement e = new MemoryAllocationsElement.created();
     e._r = new RenderingScheduler<MemoryAllocationsElement>(e, queue: queue);
     e._isolate = isolate;
     e._editor = editor;
@@ -62,7 +62,7 @@
     return e;
   }
 
-  MemoryAllocationsElement.created() : super.created();
+  MemoryAllocationsElement.created() : super.created(tag);
 
   @override
   attached() {
@@ -92,18 +92,19 @@
     } else {
       children = <Element>[
         new VirtualCollectionElement(
-            _createCollectionLine, _updateCollectionLine,
-            createHeader: _createCollectionHeader,
-            search: _search,
-            items: _profile.members
-                .where((member) =>
-                    member.newSpace.accumulated.instances != 0 ||
-                    member.newSpace.current.instances != 0 ||
-                    member.oldSpace.accumulated.instances != 0 ||
-                    member.oldSpace.current.instances != 0)
-                .toList()
-                  ..sort(_createSorter()),
-            queue: _r.queue)
+                _createCollectionLine, _updateCollectionLine,
+                createHeader: _createCollectionHeader,
+                search: _search,
+                items: _profile.members
+                    .where((member) =>
+                        member.newSpace.accumulated.instances != 0 ||
+                        member.newSpace.current.instances != 0 ||
+                        member.oldSpace.accumulated.instances != 0 ||
+                        member.oldSpace.current.instances != 0)
+                    .toList()
+                      ..sort(_createSorter()),
+                queue: _r.queue)
+            .element
       ];
     }
   }
@@ -239,8 +240,9 @@
         ..classes = ['name'];
       return;
     }
-    e.children[4] = new ClassRefElement(_isolate, item.clazz, queue: _r.queue)
-      ..classes = ['name'];
+    e.children[4] = (new ClassRefElement(_isolate, item.clazz, queue: _r.queue)
+          ..classes = ['name'])
+        .element;
     Element.clickEvent.forTarget(e.children[4], useCapture: true).listen((e) {
       if (_editor.isAvailable) {
         e.preventDefault();
diff --git a/runtime/observatory/lib/src/elements/memory/dashboard.dart b/runtime/observatory/lib/src/elements/memory/dashboard.dart
index 802bed5..c0af46d 100644
--- a/runtime/observatory/lib/src/elements/memory/dashboard.dart
+++ b/runtime/observatory/lib/src/elements/memory/dashboard.dart
@@ -28,7 +28,7 @@
 import 'package:observatory/src/elements/memory/graph.dart';
 import 'package:observatory/src/elements/memory/profile.dart';
 
-class MemoryDashboardElement extends HtmlElement implements Renderable {
+class MemoryDashboardElement extends CustomElement implements Renderable {
   static const tag = const Tag<MemoryDashboardElement>('memory-dashboard',
       dependencies: const [
         NavNotifyElement.tag,
@@ -71,7 +71,7 @@
     assert(allocations != null);
     assert(events != null);
     assert(notifications != null);
-    MemoryDashboardElement e = document.createElement(tag.name);
+    MemoryDashboardElement e = new MemoryDashboardElement.created();
     e._r = new RenderingScheduler<MemoryDashboardElement>(e, queue: queue);
     e._vm = vm;
     e._vms = vms;
@@ -85,7 +85,7 @@
     return e;
   }
 
-  MemoryDashboardElement.created() : super.created();
+  MemoryDashboardElement.created() : super.created(tag);
 
   @override
   attached() {
@@ -111,13 +111,15 @@
             ..onIsolateSelected.listen(_onIsolateSelected);
     }
     children = <Element>[
-      navBar(<Element>[new NavNotifyElement(_notifications, queue: _r.queue)]),
+      navBar(<Element>[
+        new NavNotifyElement(_notifications, queue: _r.queue).element
+      ]),
       new DivElement()
         ..classes = ['content-centered-big']
         ..children = <Element>[
           new HeadingElement.h2()..text = 'Memory Dashboard',
           new HRElement(),
-          _graph,
+          _graph.element,
           new HRElement(),
         ],
     ];
@@ -129,7 +131,8 @@
         ]);
     } else {
       children.add(new MemoryProfileElement(
-          _isolate, _editor, _allocations, _snapshots, _objects));
+              _isolate, _editor, _allocations, _snapshots, _objects)
+          .element);
     }
   }
 
diff --git a/runtime/observatory/lib/src/elements/memory/graph.dart b/runtime/observatory/lib/src/elements/memory/graph.dart
index 30b18ac..5f0fd9d 100644
--- a/runtime/observatory/lib/src/elements/memory/graph.dart
+++ b/runtime/observatory/lib/src/elements/memory/graph.dart
@@ -29,7 +29,7 @@
   const IsolateSelectedEvent([this.isolate]);
 }
 
-class MemoryGraphElement extends HtmlElement implements Renderable {
+class MemoryGraphElement extends CustomElement implements Renderable {
   static const tag = const Tag<MemoryGraphElement>('memory-graph');
 
   RenderingScheduler<MemoryGraphElement> _r;
@@ -59,7 +59,7 @@
     assert(vms != null);
     assert(isolates != null);
     assert(events != null);
-    MemoryGraphElement e = document.createElement(tag.name);
+    MemoryGraphElement e = new MemoryGraphElement.created();
     e._r = new RenderingScheduler<MemoryGraphElement>(e, queue: queue);
     e._vm = vm;
     e._vms = vms;
@@ -68,7 +68,7 @@
     return e;
   }
 
-  MemoryGraphElement.created() : super.created() {
+  MemoryGraphElement.created() : super.created(tag) {
     final now = new DateTime.now();
     var sample = now.subtract(_window);
     while (sample.isBefore(now)) {
@@ -455,7 +455,7 @@
 
   StyleElement get style => new StyleElement()
     ..text = '''
-memory-graph svg .stacked-line-rdr-line:nth-child(2n+${_offset+1})
+memory-graph svg .stacked-line-rdr-line:nth-child(2n+${_offset + 1})
   path:nth-child(1) {
   filter: url(#stroke-grid);
 }''';
diff --git a/runtime/observatory/lib/src/elements/memory/profile.dart b/runtime/observatory/lib/src/elements/memory/profile.dart
index 2c72042..7d86456 100644
--- a/runtime/observatory/lib/src/elements/memory/profile.dart
+++ b/runtime/observatory/lib/src/elements/memory/profile.dart
@@ -23,7 +23,7 @@
 
 enum _Analysis { allocations, dominatorTree }
 
-class MemoryProfileElement extends HtmlElement implements Renderable {
+class MemoryProfileElement extends CustomElement implements Renderable {
   static const tag = const Tag<MemoryProfileElement>('memory-profile',
       dependencies: const [
         MemoryAllocationsElement.tag,
@@ -56,7 +56,7 @@
     assert(allocations != null);
     assert(snapshots != null);
     assert(objects != null);
-    MemoryProfileElement e = document.createElement(tag.name);
+    MemoryProfileElement e = new MemoryProfileElement.created();
     e._r = new RenderingScheduler<MemoryProfileElement>(e, queue: queue);
     e._isolate = isolate;
     e._editor = editor;
@@ -66,7 +66,7 @@
     return e;
   }
 
-  MemoryProfileElement.created() : super.created();
+  MemoryProfileElement.created() : super.created(tag);
 
   @override
   attached() {
@@ -88,13 +88,13 @@
       case _Analysis.allocations:
         final MemoryAllocationsElement allocations =
             new MemoryAllocationsElement(_isolate, _editor, _allocations);
-        current = allocations;
+        current = allocations.element;
         reload = ({bool gc: false}) => allocations.reload(gc: gc);
         break;
       case _Analysis.dominatorTree:
         final MemorySnapshotElement snapshot =
             new MemorySnapshotElement(_isolate, _editor, _snapshots, _objects);
-        current = snapshot;
+        current = snapshot.element;
         reload = ({bool gc: false}) => snapshot.reload(gc: gc);
         break;
     }
diff --git a/runtime/observatory/lib/src/elements/memory/snapshot.dart b/runtime/observatory/lib/src/elements/memory/snapshot.dart
index 816a772..b518e96 100644
--- a/runtime/observatory/lib/src/elements/memory/snapshot.dart
+++ b/runtime/observatory/lib/src/elements/memory/snapshot.dart
@@ -14,7 +14,7 @@
 import 'package:observatory/src/elements/helpers/uris.dart';
 import 'package:observatory/utils.dart';
 
-class MemorySnapshotElement extends HtmlElement implements Renderable {
+class MemorySnapshotElement extends CustomElement implements Renderable {
   static const tag =
       const Tag<MemorySnapshotElement>('memory-snapshot', dependencies: const [
     ClassRefElement.tag,
@@ -42,7 +42,7 @@
     assert(editor != null);
     assert(snapshots != null);
     assert(objects != null);
-    MemorySnapshotElement e = document.createElement(tag.name);
+    MemorySnapshotElement e = new MemorySnapshotElement.created();
     e._r = new RenderingScheduler<MemorySnapshotElement>(e, queue: queue);
     e._isolate = isolate;
     e._editor = editor;
@@ -51,7 +51,7 @@
     return e;
   }
 
-  MemorySnapshotElement.created() : super.created();
+  MemorySnapshotElement.created() : super.created(tag);
 
   @override
   attached() {
@@ -161,7 +161,7 @@
         ..classes = ['content-centered-big', 'explanation']
         ..text = text
         ..title = text,
-      _tree
+      _tree.element
     ];
   }
 
diff --git a/runtime/observatory/lib/src/elements/metric/details.dart b/runtime/observatory/lib/src/elements/metric/details.dart
index 458d12b..72d218e 100644
--- a/runtime/observatory/lib/src/elements/metric/details.dart
+++ b/runtime/observatory/lib/src/elements/metric/details.dart
@@ -8,7 +8,7 @@
 import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
 import 'package:observatory/src/elements/helpers/tag.dart';
 
-class MetricDetailsElement extends HtmlElement implements Renderable {
+class MetricDetailsElement extends CustomElement implements Renderable {
   static const tag = const Tag<MetricDetailsElement>('metric-details');
 
   RenderingScheduler<MetricDetailsElement> _r;
@@ -28,7 +28,7 @@
     assert(isolate != null);
     assert(metric != null);
     assert(metrics != null);
-    MetricDetailsElement e = document.createElement(tag.name);
+    MetricDetailsElement e = new MetricDetailsElement.created();
     e._r = new RenderingScheduler<MetricDetailsElement>(e, queue: queue);
     e._isolate = isolate;
     e._metric = metric;
@@ -36,7 +36,7 @@
     return e;
   }
 
-  MetricDetailsElement.created() : super.created();
+  MetricDetailsElement.created() : super.created(tag);
 
   @override
   void attached() {
diff --git a/runtime/observatory/lib/src/elements/metric/graph.dart b/runtime/observatory/lib/src/elements/metric/graph.dart
index 608a936..24406a2 100644
--- a/runtime/observatory/lib/src/elements/metric/graph.dart
+++ b/runtime/observatory/lib/src/elements/metric/graph.dart
@@ -9,7 +9,7 @@
 import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
 import 'package:observatory/src/elements/helpers/tag.dart';
 
-class MetricGraphElement extends HtmlElement implements Renderable {
+class MetricGraphElement extends CustomElement implements Renderable {
   static const tag = const Tag<MetricGraphElement>('metric-graph');
 
   RenderingScheduler<MetricGraphElement> _r;
@@ -30,7 +30,7 @@
     assert(isolate != null);
     assert(metric != null);
     assert(metrics != null);
-    MetricGraphElement e = document.createElement(tag.name);
+    MetricGraphElement e = new MetricGraphElement.created();
     e._r = new RenderingScheduler<MetricGraphElement>(e, queue: queue);
     e._isolate = isolate;
     e._metric = metric;
@@ -38,7 +38,7 @@
     return e;
   }
 
-  MetricGraphElement.created() : super.created();
+  MetricGraphElement.created() : super.created(tag);
 
   @override
   void attached() {
diff --git a/runtime/observatory/lib/src/elements/metrics.dart b/runtime/observatory/lib/src/elements/metrics.dart
index ce8b91a..50e2da0 100644
--- a/runtime/observatory/lib/src/elements/metrics.dart
+++ b/runtime/observatory/lib/src/elements/metrics.dart
@@ -19,7 +19,7 @@
 import 'package:observatory/src/elements/nav/top_menu.dart';
 import 'package:observatory/src/elements/nav/vm_menu.dart';
 
-class MetricsPageElement extends HtmlElement implements Renderable {
+class MetricsPageElement extends CustomElement implements Renderable {
   static const tag =
       const Tag<MetricsPageElement>('metrics-page', dependencies: const [
     MetricDetailsElement.tag,
@@ -58,7 +58,7 @@
     assert(isolate != null);
     assert(events != null);
     assert(notifications != null);
-    MetricsPageElement e = document.createElement(tag.name);
+    MetricsPageElement e = new MetricsPageElement.created();
     e._r = new RenderingScheduler<MetricsPageElement>(e, queue: queue);
     e._vm = vm;
     e._isolate = isolate;
@@ -68,7 +68,7 @@
     return e;
   }
 
-  MetricsPageElement.created() : super.created();
+  MetricsPageElement.created() : super.created(tag);
 
   @override
   attached() {
@@ -87,16 +87,17 @@
   void render() {
     children = <Element>[
       navBar(<Element>[
-        new NavTopMenuElement(queue: _r.queue),
-        new NavVMMenuElement(_vm, _events, queue: _r.queue),
-        new NavIsolateMenuElement(_isolate, _events, queue: _r.queue),
+        new NavTopMenuElement(queue: _r.queue).element,
+        new NavVMMenuElement(_vm, _events, queue: _r.queue).element,
+        new NavIsolateMenuElement(_isolate, _events, queue: _r.queue).element,
         navMenu('metrics'),
-        new NavRefreshElement(queue: _r.queue)
-          ..onRefresh.listen((e) {
-            e.element.disabled = true;
-            _refresh();
-          }),
-        new NavNotifyElement(_notifications, queue: _r.queue)
+        (new NavRefreshElement(queue: _r.queue)
+              ..onRefresh.listen((e) {
+                e.element.disabled = true;
+                _refresh();
+              }))
+            .element,
+        new NavNotifyElement(_notifications, queue: _r.queue).element
       ]),
       new DivElement()
         ..classes = ['content-centered-big']
@@ -125,7 +126,8 @@
                 ? const []
                 : [
                     new MetricDetailsElement(_isolate, _selected, _metrics,
-                        queue: _r.queue)
+                            queue: _r.queue)
+                        .element
                   ],
           new HRElement(),
           new DivElement()
@@ -134,7 +136,8 @@
                 ? const []
                 : [
                     new MetricGraphElement(_isolate, _selected, _metrics,
-                        queue: _r.queue)
+                            queue: _r.queue)
+                        .element
                   ]
         ],
     ];
diff --git a/runtime/observatory/lib/src/elements/native_memory_profiler.dart b/runtime/observatory/lib/src/elements/native_memory_profiler.dart
index b32f2d2..8936b31 100644
--- a/runtime/observatory/lib/src/elements/native_memory_profiler.dart
+++ b/runtime/observatory/lib/src/elements/native_memory_profiler.dart
@@ -20,7 +20,7 @@
 import 'package:observatory/src/elements/sample_buffer_control.dart';
 import 'package:observatory/src/elements/stack_trace_tree_config.dart';
 
-class NativeMemoryProfileElement extends HtmlElement implements Renderable {
+class NativeMemoryProfileElement extends CustomElement implements Renderable {
   static const tag = const Tag<NativeMemoryProfileElement>(
       'native-memory-profile',
       dependencies: const [
@@ -62,7 +62,7 @@
     assert(events != null);
     assert(notifications != null);
     assert(profiles != null);
-    NativeMemoryProfileElement e = document.createElement(tag.name);
+    NativeMemoryProfileElement e = new NativeMemoryProfileElement.created();
     e._r = new RenderingScheduler<NativeMemoryProfileElement>(e, queue: queue);
     e._vm = vm;
     e._events = events;
@@ -71,7 +71,7 @@
     return e;
   }
 
-  NativeMemoryProfileElement.created() : super.created();
+  NativeMemoryProfileElement.created() : super.created(tag);
 
   @override
   attached() {
@@ -90,51 +90,55 @@
   void render() {
     var content = <Element>[
       navBar(<Element>[
-        new NavTopMenuElement(queue: _r.queue),
-        new NavVMMenuElement(_vm, _events, queue: _r.queue),
+        new NavTopMenuElement(queue: _r.queue).element,
+        new NavVMMenuElement(_vm, _events, queue: _r.queue).element,
         navMenu('native memory profile', link: Uris.nativeMemory()),
-        new NavRefreshElement(queue: _r.queue)..onRefresh.listen(_refresh),
-        new NavNotifyElement(_notifications, queue: _r.queue)
+        (new NavRefreshElement(queue: _r.queue)..onRefresh.listen(_refresh))
+            .element,
+        new NavNotifyElement(_notifications, queue: _r.queue).element
       ]),
     ];
     if (_progress == null) {
       children = content;
       return;
     }
-    content.add(new SampleBufferControlElement(_vm, _progress, _progressStream,
-        selectedTag: _tag, queue: _r.queue)
-      ..onTagChange.listen((e) {
-        _tag = e.element.selectedTag;
-        _request(forceFetch: true);
-      }));
+    content.add((new SampleBufferControlElement(_vm, _progress, _progressStream,
+            selectedTag: _tag, queue: _r.queue)
+          ..onTagChange.listen((e) {
+            _tag = e.element.selectedTag;
+            _request(forceFetch: true);
+          }))
+        .element);
     if (_progress.status == M.SampleProfileLoadingStatus.loaded) {
       CpuProfileVirtualTreeElement tree;
       content.addAll([
         new BRElement(),
-        new StackTraceTreeConfigElement(
-            mode: _mode,
-            direction: _direction,
-            filter: _filter,
-            queue: _r.queue)
-          ..onModeChange.listen((e) {
-            _mode = tree.mode = e.element.mode;
-          })
-          ..onFilterChange.listen((e) {
-            _filter = e.element.filter.trim();
-            tree.filters = _filter.isNotEmpty
-                ? [
-                    (node) {
-                      return node.name.contains(_filter);
-                    }
-                  ]
-                : const [];
-          })
-          ..onDirectionChange.listen((e) {
-            _direction = tree.direction = e.element.direction;
-          }),
+        (new StackTraceTreeConfigElement(
+                mode: _mode,
+                direction: _direction,
+                filter: _filter,
+                queue: _r.queue)
+              ..onModeChange.listen((e) {
+                _mode = tree.mode = e.element.mode;
+              })
+              ..onFilterChange.listen((e) {
+                _filter = e.element.filter.trim();
+                tree.filters = _filter.isNotEmpty
+                    ? [
+                        (node) {
+                          return node.name.contains(_filter);
+                        }
+                      ]
+                    : const [];
+              })
+              ..onDirectionChange.listen((e) {
+                _direction = tree.direction = e.element.direction;
+              }))
+            .element,
         new BRElement(),
-        tree = new CpuProfileVirtualTreeElement(null, _progress.profile,
-            queue: _r.queue, type: M.SampleProfileType.memory)
+        (tree = new CpuProfileVirtualTreeElement(null, _progress.profile,
+                queue: _r.queue, type: M.SampleProfileType.memory))
+            .element,
       ]);
     }
     children = content;
diff --git a/runtime/observatory/lib/src/elements/nav/class_menu.dart b/runtime/observatory/lib/src/elements/nav/class_menu.dart
index 3844443..c388eb3 100644
--- a/runtime/observatory/lib/src/elements/nav/class_menu.dart
+++ b/runtime/observatory/lib/src/elements/nav/class_menu.dart
@@ -10,7 +10,7 @@
 import 'package:observatory/src/elements/helpers/tag.dart';
 import 'package:observatory/src/elements/helpers/uris.dart';
 
-class NavClassMenuElement extends HtmlElement implements Renderable {
+class NavClassMenuElement extends CustomElement implements Renderable {
   static const tag = const Tag<NavClassMenuElement>('nav-class-menu');
 
   RenderingScheduler _r;
@@ -34,14 +34,14 @@
       {RenderingQueue queue}) {
     assert(isolate != null);
     assert(cls != null);
-    NavClassMenuElement e = document.createElement(tag.name);
+    NavClassMenuElement e = new NavClassMenuElement.created();
     e._r = new RenderingScheduler<NavClassMenuElement>(e, queue: queue);
     e._isolate = isolate;
     e._cls = cls;
     return e;
   }
 
-  NavClassMenuElement.created() : super.created();
+  NavClassMenuElement.created() : super.created(tag);
 
   @override
   void attached() {
diff --git a/runtime/observatory/lib/src/elements/nav/isolate_menu.dart b/runtime/observatory/lib/src/elements/nav/isolate_menu.dart
index 5a1cfed..9b94daf 100644
--- a/runtime/observatory/lib/src/elements/nav/isolate_menu.dart
+++ b/runtime/observatory/lib/src/elements/nav/isolate_menu.dart
@@ -11,7 +11,7 @@
 import 'package:observatory/src/elements/helpers/uris.dart';
 import 'package:observatory/src/elements/nav/menu_item.dart';
 
-class NavIsolateMenuElement extends HtmlElement implements Renderable {
+class NavIsolateMenuElement extends CustomElement implements Renderable {
   static const tag = const Tag<NavIsolateMenuElement>('nav-isolate-menu',
       dependencies: const [NavMenuItemElement.tag]);
 
@@ -36,14 +36,14 @@
       {RenderingQueue queue}) {
     assert(isolate != null);
     assert(events != null);
-    NavIsolateMenuElement e = document.createElement(tag.name);
+    NavIsolateMenuElement e = new NavIsolateMenuElement.created();
     e._r = new RenderingScheduler<NavIsolateMenuElement>(e, queue: queue);
     e._isolate = isolate;
     e._events = events;
     return e;
   }
 
-  NavIsolateMenuElement.created() : super.created();
+  NavIsolateMenuElement.created() : super.created(tag);
 
   @override
   void attached() {
@@ -70,27 +70,38 @@
   void render() {
     final content = <Element>[
       new NavMenuItemElement('debugger',
-          queue: _r.queue, link: Uris.debugger(isolate)),
+              queue: _r.queue, link: Uris.debugger(isolate))
+          .element,
       new NavMenuItemElement('class hierarchy',
-          queue: _r.queue, link: Uris.classTree(isolate)),
+              queue: _r.queue, link: Uris.classTree(isolate))
+          .element,
       new NavMenuItemElement('cpu profile',
-          queue: _r.queue, link: Uris.cpuProfiler(isolate)),
+              queue: _r.queue, link: Uris.cpuProfiler(isolate))
+          .element,
       new NavMenuItemElement('cpu profile (table)',
-          queue: _r.queue, link: Uris.cpuProfilerTable(isolate)),
+              queue: _r.queue, link: Uris.cpuProfilerTable(isolate))
+          .element,
       new NavMenuItemElement('allocation profile',
-          queue: _r.queue, link: Uris.allocationProfiler(isolate)),
+              queue: _r.queue, link: Uris.allocationProfiler(isolate))
+          .element,
       new NavMenuItemElement('heap snapshot',
-          queue: _r.queue, link: Uris.heapSnapshot(isolate)),
+              queue: _r.queue, link: Uris.heapSnapshot(isolate))
+          .element,
       new NavMenuItemElement('heap map',
-          queue: _r.queue, link: Uris.heapMap(isolate)),
+              queue: _r.queue, link: Uris.heapMap(isolate))
+          .element,
       new NavMenuItemElement('metrics',
-          queue: _r.queue, link: Uris.metrics(isolate)),
+              queue: _r.queue, link: Uris.metrics(isolate))
+          .element,
       new NavMenuItemElement('persistent handles',
-          queue: _r.queue, link: Uris.persistentHandles(isolate)),
+              queue: _r.queue, link: Uris.persistentHandles(isolate))
+          .element,
       new NavMenuItemElement('ports',
-          queue: _r.queue, link: Uris.ports(isolate)),
+              queue: _r.queue, link: Uris.ports(isolate))
+          .element,
       new NavMenuItemElement('logging',
-          queue: _r.queue, link: Uris.logging(isolate)),
+              queue: _r.queue, link: Uris.logging(isolate))
+          .element,
     ]..addAll(_content);
     children = <Element>[
       navMenu(isolate.name, content: content, link: Uris.inspect(isolate))
diff --git a/runtime/observatory/lib/src/elements/nav/library_menu.dart b/runtime/observatory/lib/src/elements/nav/library_menu.dart
index 8750d5e..2ef6f15 100644
--- a/runtime/observatory/lib/src/elements/nav/library_menu.dart
+++ b/runtime/observatory/lib/src/elements/nav/library_menu.dart
@@ -10,7 +10,7 @@
 import 'package:observatory/src/elements/helpers/tag.dart';
 import 'package:observatory/src/elements/helpers/uris.dart';
 
-class NavLibraryMenuElement extends HtmlElement implements Renderable {
+class NavLibraryMenuElement extends CustomElement implements Renderable {
   static const tag = const Tag<NavLibraryMenuElement>('nav-library-menu');
 
   RenderingScheduler _r;
@@ -34,14 +34,14 @@
       {RenderingQueue queue}) {
     assert(isolate != null);
     assert(library != null);
-    NavLibraryMenuElement e = document.createElement(tag.name);
+    NavLibraryMenuElement e = new NavLibraryMenuElement.created();
     e._r = new RenderingScheduler<NavLibraryMenuElement>(e, queue: queue);
     e._isolate = isolate;
     e._library = library;
     return e;
   }
 
-  NavLibraryMenuElement.created() : super.created();
+  NavLibraryMenuElement.created() : super.created(tag);
 
   @override
   void attached() {
diff --git a/runtime/observatory/lib/src/elements/nav/menu_item.dart b/runtime/observatory/lib/src/elements/nav/menu_item.dart
index b196b4f..5df68a9 100644
--- a/runtime/observatory/lib/src/elements/nav/menu_item.dart
+++ b/runtime/observatory/lib/src/elements/nav/menu_item.dart
@@ -7,7 +7,7 @@
 import 'package:observatory/src/elements/helpers/tag.dart';
 import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
 
-class NavMenuItemElement extends HtmlElement implements Renderable {
+class NavMenuItemElement extends CustomElement implements Renderable {
   static const tag = const Tag<NavMenuItemElement>('nav-menu-item');
 
   RenderingScheduler _r;
@@ -32,14 +32,14 @@
   factory NavMenuItemElement(String label,
       {String link, RenderingQueue queue}) {
     assert(label != null);
-    NavMenuItemElement e = document.createElement(tag.name);
+    NavMenuItemElement e = new NavMenuItemElement.created();
     e._r = new RenderingScheduler<NavMenuItemElement>(e, queue: queue);
     e._label = label;
     e._link = link;
     return e;
   }
 
-  NavMenuItemElement.created() : super.created();
+  NavMenuItemElement.created() : super.created(tag);
 
   @override
   void attached() {
diff --git a/runtime/observatory/lib/src/elements/nav/notify.dart b/runtime/observatory/lib/src/elements/nav/notify.dart
index 6b22f32..a33d800 100644
--- a/runtime/observatory/lib/src/elements/nav/notify.dart
+++ b/runtime/observatory/lib/src/elements/nav/notify.dart
@@ -10,7 +10,7 @@
 import 'package:observatory/src/elements/nav/notify_event.dart';
 import 'package:observatory/src/elements/nav/notify_exception.dart';
 
-class NavNotifyElement extends HtmlElement implements Renderable {
+class NavNotifyElement extends CustomElement implements Renderable {
   static const tag = const Tag<NavNotifyElement>('nav-notify',
       dependencies: const [
         NavNotifyEventElement.tag,
@@ -35,14 +35,14 @@
       {bool notifyOnPause: true, RenderingQueue queue}) {
     assert(repository != null);
     assert(notifyOnPause != null);
-    NavNotifyElement e = document.createElement(tag.name);
+    NavNotifyElement e = new NavNotifyElement.created();
     e._r = new RenderingScheduler<NavNotifyElement>(e, queue: queue);
     e._repository = repository;
     e._notifyOnPause = notifyOnPause;
     return e;
   }
 
-  NavNotifyElement.created() : super.created();
+  NavNotifyElement.created() : super.created(tag);
 
   @override
   void attached() {
@@ -82,12 +82,14 @@
 
   Element _toElement(M.Notification notification) {
     if (notification is M.EventNotification) {
-      return new NavNotifyEventElement(notification.event, queue: _r.queue)
-        ..onDelete.listen((_) => _repository.delete(notification));
+      return (new NavNotifyEventElement(notification.event, queue: _r.queue)
+            ..onDelete.listen((_) => _repository.delete(notification)))
+          .element;
     } else if (notification is M.ExceptionNotification) {
-      return new NavNotifyExceptionElement(notification.exception,
-          stacktrace: notification.stacktrace, queue: _r.queue)
-        ..onDelete.listen((_) => _repository.delete(notification));
+      return (new NavNotifyExceptionElement(notification.exception,
+              stacktrace: notification.stacktrace, queue: _r.queue)
+            ..onDelete.listen((_) => _repository.delete(notification)))
+          .element;
     } else {
       assert(false);
       return new DivElement()..text = 'Invalid Notification Type';
diff --git a/runtime/observatory/lib/src/elements/nav/notify_event.dart b/runtime/observatory/lib/src/elements/nav/notify_event.dart
index a75e723..fc9defc 100644
--- a/runtime/observatory/lib/src/elements/nav/notify_event.dart
+++ b/runtime/observatory/lib/src/elements/nav/notify_event.dart
@@ -14,7 +14,7 @@
   EventDeleteEvent(this.event);
 }
 
-class NavNotifyEventElement extends HtmlElement implements Renderable {
+class NavNotifyEventElement extends CustomElement implements Renderable {
   static const tag = const Tag<NavNotifyEventElement>('nav-event');
 
   RenderingScheduler _r;
@@ -31,13 +31,13 @@
 
   factory NavNotifyEventElement(M.Event event, {RenderingQueue queue}) {
     assert(event != null);
-    NavNotifyEventElement e = document.createElement(tag.name);
+    NavNotifyEventElement e = new NavNotifyEventElement.created();
     e._r = new RenderingScheduler<NavNotifyEventElement>(e, queue: queue);
     e._event = event;
     return e;
   }
 
-  NavNotifyEventElement.created() : super.created();
+  NavNotifyEventElement.created() : super.created(tag);
 
   @override
   void attached() {
diff --git a/runtime/observatory/lib/src/elements/nav/notify_exception.dart b/runtime/observatory/lib/src/elements/nav/notify_exception.dart
index 3c84af7..9a746f0 100644
--- a/runtime/observatory/lib/src/elements/nav/notify_exception.dart
+++ b/runtime/observatory/lib/src/elements/nav/notify_exception.dart
@@ -16,7 +16,7 @@
   ExceptionDeleteEvent(this.exception, {this.stacktrace});
 }
 
-class NavNotifyExceptionElement extends HtmlElement implements Renderable {
+class NavNotifyExceptionElement extends CustomElement implements Renderable {
   static const tag = const Tag<NavNotifyExceptionElement>('nav-exception');
 
   RenderingScheduler _r;
@@ -37,14 +37,14 @@
   factory NavNotifyExceptionElement(dynamic exception,
       {StackTrace stacktrace: null, RenderingQueue queue}) {
     assert(exception != null);
-    NavNotifyExceptionElement e = document.createElement(tag.name);
+    NavNotifyExceptionElement e = new NavNotifyExceptionElement.created();
     e._r = new RenderingScheduler<NavNotifyExceptionElement>(e, queue: queue);
     e._exception = exception;
     e._stacktrace = stacktrace;
     return e;
   }
 
-  NavNotifyExceptionElement.created() : super.created();
+  NavNotifyExceptionElement.created() : super.created(tag);
 
   @override
   void attached() {
diff --git a/runtime/observatory/lib/src/elements/nav/refresh.dart b/runtime/observatory/lib/src/elements/nav/refresh.dart
index da859a5..1d918fb 100644
--- a/runtime/observatory/lib/src/elements/nav/refresh.dart
+++ b/runtime/observatory/lib/src/elements/nav/refresh.dart
@@ -12,7 +12,7 @@
   RefreshEvent(this.element);
 }
 
-class NavRefreshElement extends HtmlElement implements Renderable {
+class NavRefreshElement extends CustomElement implements Renderable {
   static const tag = const Tag<NavRefreshElement>('nav-refresh');
 
   RenderingScheduler _r;
@@ -36,14 +36,14 @@
       {String label: 'Refresh', bool disabled: false, RenderingQueue queue}) {
     assert(label != null);
     assert(disabled != null);
-    NavRefreshElement e = document.createElement(tag.name);
+    NavRefreshElement e = new NavRefreshElement.created();
     e._r = new RenderingScheduler<NavRefreshElement>(e, queue: queue);
     e._label = label;
     e._disabled = disabled;
     return e;
   }
 
-  NavRefreshElement.created() : super.created();
+  NavRefreshElement.created() : super.created(tag);
 
   @override
   void attached() {
diff --git a/runtime/observatory/lib/src/elements/nav/reload.dart b/runtime/observatory/lib/src/elements/nav/reload.dart
index 86c8225..64534d3 100644
--- a/runtime/observatory/lib/src/elements/nav/reload.dart
+++ b/runtime/observatory/lib/src/elements/nav/reload.dart
@@ -15,7 +15,7 @@
   ReloadEvent(this.element);
 }
 
-class NavReloadElement extends HtmlElement implements Renderable {
+class NavReloadElement extends CustomElement implements Renderable {
   static const tag = const Tag<NavReloadElement>('nav-reload');
 
   RenderingScheduler _r;
@@ -38,7 +38,7 @@
     assert(isolate == null);
     assert(isolates == null);
     assert(events == null);
-    NavReloadElement e = document.createElement(tag.name);
+    NavReloadElement e = new NavReloadElement.created();
     e._r = new RenderingScheduler<NavReloadElement>(e, queue: queue);
     e._isolate = isolate;
     e._isolates = isolates;
@@ -46,7 +46,7 @@
     return e;
   }
 
-  NavReloadElement.created() : super.created();
+  NavReloadElement.created() : super.created(tag);
 
   @override
   void attached() {
diff --git a/runtime/observatory/lib/src/elements/nav/top_menu.dart b/runtime/observatory/lib/src/elements/nav/top_menu.dart
index 285be91..eb8cf97 100644
--- a/runtime/observatory/lib/src/elements/nav/top_menu.dart
+++ b/runtime/observatory/lib/src/elements/nav/top_menu.dart
@@ -10,7 +10,7 @@
 import 'package:observatory/src/elements/helpers/uris.dart';
 import 'package:observatory/src/elements/nav/menu_item.dart';
 
-class NavTopMenuElement extends HtmlElement implements Renderable {
+class NavTopMenuElement extends CustomElement implements Renderable {
   static const tag = const Tag<NavTopMenuElement>('nav-top-menu',
       dependencies: const [NavMenuItemElement.tag]);
 
@@ -28,12 +28,12 @@
   }
 
   factory NavTopMenuElement({RenderingQueue queue}) {
-    NavTopMenuElement e = document.createElement(tag.name);
+    NavTopMenuElement e = new NavTopMenuElement.created();
     e._r = new RenderingScheduler<NavTopMenuElement>(e, queue: queue);
     return e;
   }
 
-  NavTopMenuElement.created() : super.created();
+  NavTopMenuElement.created() : super.created(tag);
 
   @override
   void attached() {
@@ -50,7 +50,7 @@
 
   void render() {
     final content = (<Element>[
-      new NavMenuItemElement('Connect to a VM', link: Uris.vmConnect()),
+      new NavMenuItemElement('Connect to a VM', link: Uris.vmConnect()).element,
     ]..addAll(_content));
     children = <Element>[
       navMenu('Observatory', link: Uris.vm(), content: content)
diff --git a/runtime/observatory/lib/src/elements/nav/vm_menu.dart b/runtime/observatory/lib/src/elements/nav/vm_menu.dart
index af1f8c4..38fbdf7 100644
--- a/runtime/observatory/lib/src/elements/nav/vm_menu.dart
+++ b/runtime/observatory/lib/src/elements/nav/vm_menu.dart
@@ -11,7 +11,7 @@
 import 'package:observatory/src/elements/helpers/uris.dart';
 import 'package:observatory/src/elements/nav/menu_item.dart';
 
-class NavVMMenuElement extends HtmlElement implements Renderable {
+class NavVMMenuElement extends CustomElement implements Renderable {
   static const tag = const Tag<NavVMMenuElement>('nav-vm-menu',
       dependencies: const [NavMenuItemElement.tag]);
 
@@ -36,14 +36,14 @@
       {RenderingQueue queue}) {
     assert(vm != null);
     assert(events != null);
-    NavVMMenuElement e = document.createElement(tag.name);
+    NavVMMenuElement e = new NavVMMenuElement.created();
     e._r = new RenderingScheduler<NavVMMenuElement>(e, queue: queue);
     e._vm = vm;
     e._events = events;
     return e;
   }
 
-  NavVMMenuElement.created() : super.created();
+  NavVMMenuElement.created() : super.created(tag);
 
   @override
   void attached() {
@@ -66,7 +66,8 @@
   void render() {
     final content = (_vm.isolates.map<Element>((isolate) {
       return new NavMenuItemElement(isolate.name,
-          queue: _r.queue, link: Uris.inspect(isolate));
+              queue: _r.queue, link: Uris.inspect(isolate))
+          .element;
     }).toList()
       ..addAll(_content));
     children = <Element>[
diff --git a/runtime/observatory/lib/src/elements/object_common.dart b/runtime/observatory/lib/src/elements/object_common.dart
index 4df6eba..c2fd2c3 100644
--- a/runtime/observatory/lib/src/elements/object_common.dart
+++ b/runtime/observatory/lib/src/elements/object_common.dart
@@ -13,7 +13,7 @@
 import 'package:observatory/src/elements/sentinel_value.dart';
 import 'package:observatory/utils.dart';
 
-class ObjectCommonElement extends HtmlElement implements Renderable {
+class ObjectCommonElement extends CustomElement implements Renderable {
   static const tag =
       const Tag<ObjectCommonElement>('object-common', dependencies: const [
     ClassRefElement.tag,
@@ -57,7 +57,7 @@
     assert(references != null);
     assert(retainingPaths != null);
     assert(objects != null);
-    ObjectCommonElement e = document.createElement(tag.name);
+    ObjectCommonElement e = new ObjectCommonElement.created();
     e._r = new RenderingScheduler<ObjectCommonElement>(e, queue: queue);
     e._isolate = isolate;
     e._object = object;
@@ -69,7 +69,7 @@
     return e;
   }
 
-  ObjectCommonElement.created() : super.created();
+  ObjectCommonElement.created() : super.created(tag);
 
   @override
   void attached() {
@@ -110,7 +110,8 @@
                   _object.clazz == null
                       ? (new SpanElement()..text = '...')
                       : new ClassRefElement(_isolate, _object.clazz,
-                          queue: _r.queue)
+                              queue: _r.queue)
+                          .element
                 ]
             ],
           new DivElement()
@@ -156,7 +157,7 @@
                 ..text = 'Retaining path ',
               new DivElement()
                 ..classes = ['memberValue']
-                ..children = <Element>[_path]
+                ..children = <Element>[_path.element]
             ],
           new DivElement()
             ..classes = ['memberItem']
@@ -167,7 +168,7 @@
                 ..text = 'Inbound references ',
               new DivElement()
                 ..classes = ['memberValue']
-                ..children = <Element>[_inbounds]
+                ..children = <Element>[_inbounds.element]
             ]
         ]
     ];
@@ -177,12 +178,13 @@
     final content = <Element>[];
     if (_reachableSize != null) {
       if (_reachableSize.isSentinel) {
-        content.add(new SentinelValueElement(_reachableSize.asSentinel,
-            queue: _r.queue));
+        content.add(
+            new SentinelValueElement(_reachableSize.asSentinel, queue: _r.queue)
+                .element);
       } else {
         content.add(new SpanElement()
-          ..text = Utils
-              .formatSize(int.parse(_reachableSize.asValue.valueAsString)));
+          ..text = Utils.formatSize(
+              int.parse(_reachableSize.asValue.valueAsString)));
       }
     } else {
       content.add(new SpanElement()..text = '...');
@@ -205,8 +207,9 @@
     final content = <Element>[];
     if (_retainedSize != null) {
       if (_retainedSize.isSentinel) {
-        content.add(new SentinelValueElement(_retainedSize.asSentinel,
-            queue: _r.queue));
+        content.add(
+            new SentinelValueElement(_retainedSize.asSentinel, queue: _r.queue)
+                .element);
       } else {
         content.add(new SpanElement()
           ..text =
diff --git a/runtime/observatory/lib/src/elements/object_view.dart b/runtime/observatory/lib/src/elements/object_view.dart
index d2a7237..2d7620f 100644
--- a/runtime/observatory/lib/src/elements/object_view.dart
+++ b/runtime/observatory/lib/src/elements/object_view.dart
@@ -19,7 +19,7 @@
 import 'package:observatory/src/elements/object_common.dart';
 import 'package:observatory/src/elements/view_footer.dart';
 
-class ObjectViewElement extends HtmlElement implements Renderable {
+class ObjectViewElement extends CustomElement implements Renderable {
   static const tag =
       const Tag<ObjectViewElement>('object-view', dependencies: const [
     ContextRefElement.tag,
@@ -75,7 +75,7 @@
     assert(reachableSizes != null);
     assert(references != null);
     assert(retainingPaths != null);
-    ObjectViewElement e = document.createElement(tag.name);
+    ObjectViewElement e = new ObjectViewElement.created();
     e._r = new RenderingScheduler<ObjectViewElement>(e, queue: queue);
     e._vm = vm;
     e._isolate = isolate;
@@ -90,7 +90,7 @@
     return e;
   }
 
-  ObjectViewElement.created() : super.created();
+  ObjectViewElement.created() : super.created(tag);
 
   @override
   attached() {
@@ -108,17 +108,18 @@
   void render() {
     children = <Element>[
       navBar(<Element>[
-        new NavTopMenuElement(queue: _r.queue),
-        new NavVMMenuElement(_vm, _events, queue: _r.queue),
-        new NavIsolateMenuElement(_isolate, _events, queue: _r.queue),
+        new NavTopMenuElement(queue: _r.queue).element,
+        new NavVMMenuElement(_vm, _events, queue: _r.queue).element,
+        new NavIsolateMenuElement(_isolate, _events, queue: _r.queue).element,
         navMenu('object'),
-        new NavRefreshElement(queue: _r.queue)
-          ..onRefresh.listen((e) async {
-            e.element.disabled = true;
-            _object = await _objects.get(_isolate, _object.id);
-            _r.dirty();
-          }),
-        new NavNotifyElement(_notifications, queue: _r.queue)
+        (new NavRefreshElement(queue: _r.queue)
+              ..onRefresh.listen((e) async {
+                e.element.disabled = true;
+                _object = await _objects.get(_isolate, _object.id);
+                _r.dirty();
+              }))
+            .element,
+        new NavNotifyElement(_notifications, queue: _r.queue).element
       ]),
       new DivElement()
         ..classes = ['content-centered-big']
@@ -126,10 +127,11 @@
           new HeadingElement.h2()..text = 'Object',
           new HRElement(),
           new ObjectCommonElement(_isolate, _object, _retainedSizes,
-              _reachableSizes, _references, _retainingPaths, _objects,
-              queue: _r.queue),
+                  _reachableSizes, _references, _retainingPaths, _objects,
+                  queue: _r.queue)
+              .element,
           new HRElement(),
-          new ViewFooterElement(queue: _r.queue)
+          new ViewFooterElement(queue: _r.queue).element
         ]
     ];
   }
diff --git a/runtime/observatory/lib/src/elements/objectpool_ref.dart b/runtime/observatory/lib/src/elements/objectpool_ref.dart
index 9c77445..cd9902a 100644
--- a/runtime/observatory/lib/src/elements/objectpool_ref.dart
+++ b/runtime/observatory/lib/src/elements/objectpool_ref.dart
@@ -9,7 +9,7 @@
 import 'package:observatory/src/elements/helpers/tag.dart';
 import 'package:observatory/src/elements/helpers/uris.dart';
 
-class ObjectPoolRefElement extends HtmlElement implements Renderable {
+class ObjectPoolRefElement extends CustomElement implements Renderable {
   static const tag = const Tag<ObjectPoolRefElement>('object-pool-ref');
 
   RenderingScheduler<ObjectPoolRefElement> _r;
@@ -26,14 +26,14 @@
       {RenderingQueue queue}) {
     assert(isolate != null);
     assert(pool != null);
-    ObjectPoolRefElement e = document.createElement(tag.name);
+    ObjectPoolRefElement e = new ObjectPoolRefElement.created();
     e._r = new RenderingScheduler<ObjectPoolRefElement>(e, queue: queue);
     e._isolate = isolate;
     e._pool = pool;
     return e;
   }
 
-  ObjectPoolRefElement.created() : super.created();
+  ObjectPoolRefElement.created() : super.created(tag);
 
   @override
   void attached() {
diff --git a/runtime/observatory/lib/src/elements/objectpool_view.dart b/runtime/observatory/lib/src/elements/objectpool_view.dart
index 71ce7a0..0d4c232 100644
--- a/runtime/observatory/lib/src/elements/objectpool_view.dart
+++ b/runtime/observatory/lib/src/elements/objectpool_view.dart
@@ -22,7 +22,7 @@
 import 'package:observatory/src/elements/object_common.dart';
 import 'package:observatory/src/elements/view_footer.dart';
 
-class ObjectPoolViewElement extends HtmlElement implements Renderable {
+class ObjectPoolViewElement extends CustomElement implements Renderable {
   static const tag =
       const Tag<ObjectPoolViewElement>('object-pool-view', dependencies: const [
     ContextRefElement.tag,
@@ -81,7 +81,7 @@
     assert(references != null);
     assert(retainingPaths != null);
     assert(objects != null);
-    ObjectPoolViewElement e = document.createElement(tag.name);
+    ObjectPoolViewElement e = new ObjectPoolViewElement.created();
     e._r = new RenderingScheduler<ObjectPoolViewElement>(e, queue: queue);
     e._vm = vm;
     e._isolate = isolate;
@@ -97,7 +97,7 @@
     return e;
   }
 
-  ObjectPoolViewElement.created() : super.created();
+  ObjectPoolViewElement.created() : super.created(tag);
 
   @override
   attached() {
@@ -115,17 +115,18 @@
   void render() {
     children = <Element>[
       navBar(<Element>[
-        new NavTopMenuElement(queue: _r.queue),
-        new NavVMMenuElement(_vm, _events, queue: _r.queue),
-        new NavIsolateMenuElement(_isolate, _events, queue: _r.queue),
+        new NavTopMenuElement(queue: _r.queue).element,
+        new NavVMMenuElement(_vm, _events, queue: _r.queue).element,
+        new NavIsolateMenuElement(_isolate, _events, queue: _r.queue).element,
         navMenu('instance'),
-        new NavRefreshElement(queue: _r.queue)
-          ..onRefresh.listen((e) async {
-            e.element.disabled = true;
-            _pool = await _pools.get(_isolate, _pool.id);
-            _r.dirty();
-          }),
-        new NavNotifyElement(_notifications, queue: _r.queue)
+        (new NavRefreshElement(queue: _r.queue)
+              ..onRefresh.listen((e) async {
+                e.element.disabled = true;
+                _pool = await _pools.get(_isolate, _pool.id);
+                _r.dirty();
+              }))
+            .element,
+        new NavNotifyElement(_notifications, queue: _r.queue).element
       ]),
       new DivElement()
         ..classes = ['content-centered-big']
@@ -133,8 +134,9 @@
           new HeadingElement.h2()..text = 'ObjectPool',
           new HRElement(),
           new ObjectCommonElement(_isolate, _pool, _retainedSizes,
-              _reachableSizes, _references, _retainingPaths, _objects,
-              queue: _r.queue),
+                  _reachableSizes, _references, _retainingPaths, _objects,
+                  queue: _r.queue)
+              .element,
           new HRElement(),
           new HeadingElement.h3()..text = 'entries (${_pool.entries.length})',
           new DivElement()
@@ -152,7 +154,7 @@
                   ])
                 .toList(),
           new HRElement(),
-          new ViewFooterElement(queue: _r.queue)
+          new ViewFooterElement(queue: _r.queue).element
         ]
     ];
   }
diff --git a/runtime/observatory/lib/src/elements/objectstore_view.dart b/runtime/observatory/lib/src/elements/objectstore_view.dart
index a7b31c9..66b50dc 100644
--- a/runtime/observatory/lib/src/elements/objectstore_view.dart
+++ b/runtime/observatory/lib/src/elements/objectstore_view.dart
@@ -19,7 +19,7 @@
 import 'package:observatory/src/elements/nav/vm_menu.dart';
 import 'package:observatory/src/elements/view_footer.dart';
 
-class ObjectStoreViewElement extends HtmlElement implements Renderable {
+class ObjectStoreViewElement extends CustomElement implements Renderable {
   static const tag = const Tag<ObjectStoreViewElement>('objectstore-view',
       dependencies: const [
         InstanceRefElement.tag,
@@ -61,7 +61,7 @@
     assert(notifications != null);
     assert(stores != null);
     assert(objects != null);
-    ObjectStoreViewElement e = document.createElement(tag.name);
+    ObjectStoreViewElement e = new ObjectStoreViewElement.created();
     e._r = new RenderingScheduler<ObjectStoreViewElement>(e, queue: queue);
     e._vm = vm;
     e._isolate = isolate;
@@ -72,7 +72,7 @@
     return e;
   }
 
-  ObjectStoreViewElement.created() : super.created();
+  ObjectStoreViewElement.created() : super.created(tag);
 
   @override
   attached() {
@@ -92,12 +92,13 @@
     final fields = _store?.fields?.toList(growable: false);
     children = <Element>[
       navBar(<Element>[
-        new NavTopMenuElement(queue: _r.queue),
-        new NavVMMenuElement(_vm, _events, queue: _r.queue),
-        new NavIsolateMenuElement(_isolate, _events, queue: _r.queue),
-        new NavRefreshElement(disabled: _store == null, queue: _r.queue)
-          ..onRefresh.listen((e) => _refresh()),
-        new NavNotifyElement(_notifications, queue: _r.queue)
+        new NavTopMenuElement(queue: _r.queue).element,
+        new NavVMMenuElement(_vm, _events, queue: _r.queue).element,
+        new NavIsolateMenuElement(_isolate, _events, queue: _r.queue).element,
+        (new NavRefreshElement(disabled: _store == null, queue: _r.queue)
+              ..onRefresh.listen((e) => _refresh()))
+            .element,
+        (new NavNotifyElement(_notifications, queue: _r.queue).element)
       ]),
       new DivElement()
         ..classes = ['content-centered-big']
@@ -126,7 +127,7 @@
                           ]
                       ])
                     .toList()),
-          new ViewFooterElement(queue: _r.queue)
+          new ViewFooterElement(queue: _r.queue).element
         ]
     ];
   }
diff --git a/runtime/observatory/lib/src/elements/observatory_application.dart b/runtime/observatory/lib/src/elements/observatory_application.dart
index 0e85692..49e1665 100644
--- a/runtime/observatory/lib/src/elements/observatory_application.dart
+++ b/runtime/observatory/lib/src/elements/observatory_application.dart
@@ -4,20 +4,19 @@
 
 library observatory_application_element;
 
-import 'dart:html';
 import 'package:observatory/app.dart';
 import 'package:observatory/src/elements/helpers/tag.dart';
 
 /// Main application tag. Responsible for instantiating an instance of
 /// [ObservatoryApplication] which is passed declaratively to all child
 /// elements.
-class ObservatoryApplicationElement extends HtmlElement {
+class ObservatoryApplicationElement extends CustomElement {
   static const tag =
       const Tag<ObservatoryApplicationElement>('observatory-application');
 
   ObservatoryApplication app;
 
-  ObservatoryApplicationElement.created() : super.created();
+  ObservatoryApplicationElement.created() : super.created(tag);
 
   @override
   void attached() {
diff --git a/runtime/observatory/lib/src/elements/pc_descriptors_ref.dart b/runtime/observatory/lib/src/elements/pc_descriptors_ref.dart
index 2629b9f..fa43bbe 100644
--- a/runtime/observatory/lib/src/elements/pc_descriptors_ref.dart
+++ b/runtime/observatory/lib/src/elements/pc_descriptors_ref.dart
@@ -9,7 +9,7 @@
 import 'package:observatory/src/elements/helpers/tag.dart';
 import 'package:observatory/src/elements/helpers/uris.dart';
 
-class PcDescriptorsRefElement extends HtmlElement implements Renderable {
+class PcDescriptorsRefElement extends CustomElement implements Renderable {
   static const tag = const Tag<PcDescriptorsRefElement>('pc-ref');
 
   RenderingScheduler<PcDescriptorsRefElement> _r;
@@ -28,14 +28,14 @@
       {RenderingQueue queue}) {
     assert(isolate != null);
     assert(descriptors != null);
-    PcDescriptorsRefElement e = document.createElement(tag.name);
+    PcDescriptorsRefElement e = new PcDescriptorsRefElement.created();
     e._r = new RenderingScheduler<PcDescriptorsRefElement>(e, queue: queue);
     e._isolate = isolate;
     e._descriptors = descriptors;
     return e;
   }
 
-  PcDescriptorsRefElement.created() : super.created();
+  PcDescriptorsRefElement.created() : super.created(tag);
 
   @override
   void attached() {
diff --git a/runtime/observatory/lib/src/elements/persistent_handles.dart b/runtime/observatory/lib/src/elements/persistent_handles.dart
index 57f6196..9a0d15d 100644
--- a/runtime/observatory/lib/src/elements/persistent_handles.dart
+++ b/runtime/observatory/lib/src/elements/persistent_handles.dart
@@ -25,7 +25,7 @@
 
 enum _SortingDirection { ascending, descending }
 
-class PersistentHandlesPageElement extends HtmlElement implements Renderable {
+class PersistentHandlesPageElement extends CustomElement implements Renderable {
   static const tag = const Tag<PersistentHandlesPageElement>(
       'persistent-handles-page',
       dependencies: const [
@@ -71,7 +71,7 @@
     assert(notifications != null);
     assert(repository != null);
     assert(objects != null);
-    PersistentHandlesPageElement e = document.createElement(tag.name);
+    PersistentHandlesPageElement e = new PersistentHandlesPageElement.created();
     e._r =
         new RenderingScheduler<PersistentHandlesPageElement>(e, queue: queue);
     e._vm = vm;
@@ -83,7 +83,7 @@
     return e;
   }
 
-  PersistentHandlesPageElement.created() : super.created();
+  PersistentHandlesPageElement.created() : super.created(tag);
 
   @override
   attached() {
@@ -102,13 +102,14 @@
   void render() {
     children = <Element>[
       navBar(<Element>[
-        new NavTopMenuElement(queue: _r.queue),
-        new NavVMMenuElement(_vm, _events, queue: _r.queue),
-        new NavIsolateMenuElement(_isolate, _events, queue: _r.queue),
+        new NavTopMenuElement(queue: _r.queue).element,
+        new NavVMMenuElement(_vm, _events, queue: _r.queue).element,
+        new NavIsolateMenuElement(_isolate, _events, queue: _r.queue).element,
         navMenu('persistent handles'),
-        new NavRefreshElement(queue: _r.queue)
-          ..onRefresh.listen((_) => _refresh()),
-        new NavNotifyElement(_notifications, queue: _r.queue)
+        (new NavRefreshElement(queue: _r.queue)
+              ..onRefresh.listen((_) => _refresh()))
+            .element,
+        new NavNotifyElement(_notifications, queue: _r.queue).element
       ])
     ]
       ..addAll(_createHandlers('Persistent Handles',
@@ -142,7 +143,8 @@
                 ..classes = ['content-centered-big']
                 ..text = 'Loading...')
               : new VirtualCollectionElement(create, update,
-                  items: items, createHeader: createHeader, queue: _r.queue)
+                      items: items, createHeader: createHeader, queue: _r.queue)
+                  .element
         ]
     ];
   }
diff --git a/runtime/observatory/lib/src/elements/ports.dart b/runtime/observatory/lib/src/elements/ports.dart
index 59d7952..6561ffe 100644
--- a/runtime/observatory/lib/src/elements/ports.dart
+++ b/runtime/observatory/lib/src/elements/ports.dart
@@ -18,7 +18,7 @@
 import 'package:observatory/src/elements/nav/vm_menu.dart';
 import 'package:observatory/src/elements/view_footer.dart';
 
-class PortsElement extends HtmlElement implements Renderable {
+class PortsElement extends CustomElement implements Renderable {
   static const tag = const Tag<PortsElement>('ports-page', dependencies: const [
     NavTopMenuElement.tag,
     NavVMMenuElement.tag,
@@ -60,7 +60,7 @@
     assert(notifications != null);
     assert(ports != null);
     assert(objects != null);
-    PortsElement e = document.createElement(tag.name);
+    PortsElement e = new PortsElement.created();
     e._r = new RenderingScheduler<PortsElement>(e, queue: queue);
     e._vm = vm;
     e._isolate = isolate;
@@ -71,7 +71,7 @@
     return e;
   }
 
-  PortsElement.created() : super.created();
+  PortsElement.created() : super.created(tag);
 
   int get portCount {
     return _isolatePorts == null ? 0 : _isolatePorts.elements.length;
@@ -94,13 +94,14 @@
   void render() {
     children = <Element>[
       navBar(<Element>[
-        new NavTopMenuElement(queue: _r.queue),
-        new NavVMMenuElement(_vm, _events, queue: _r.queue),
-        new NavIsolateMenuElement(_isolate, _events, queue: _r.queue),
+        new NavTopMenuElement(queue: _r.queue).element,
+        new NavVMMenuElement(_vm, _events, queue: _r.queue).element,
+        new NavIsolateMenuElement(_isolate, _events, queue: _r.queue).element,
         navMenu('ports'),
-        new NavRefreshElement(queue: _r.queue)
-          ..onRefresh.listen((_) => _refresh()),
-        new NavNotifyElement(_notifications, queue: _r.queue)
+        (new NavRefreshElement(queue: _r.queue)
+              ..onRefresh.listen((_) => _refresh()))
+            .element,
+        new NavNotifyElement(_notifications, queue: _r.queue).element
       ]),
       new DivElement()
         ..classes = ['content-centered']
@@ -110,7 +111,7 @@
           new BRElement(),
           new DivElement()..children = _createList(),
         ],
-      new ViewFooterElement(queue: _r.queue)
+      new ViewFooterElement(queue: _r.queue).element
     ];
   }
 
diff --git a/runtime/observatory/lib/src/elements/retaining_path.dart b/runtime/observatory/lib/src/elements/retaining_path.dart
index a72c728..0adfca5 100644
--- a/runtime/observatory/lib/src/elements/retaining_path.dart
+++ b/runtime/observatory/lib/src/elements/retaining_path.dart
@@ -11,7 +11,7 @@
 import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
 import 'package:observatory/src/elements/helpers/tag.dart';
 
-class RetainingPathElement extends HtmlElement implements Renderable {
+class RetainingPathElement extends CustomElement implements Renderable {
   static const tag = const Tag<RetainingPathElement>('retaining-path',
       dependencies: const [CurlyBlockElement.tag, InstanceRefElement.tag]);
 
@@ -36,7 +36,7 @@
     assert(object != null);
     assert(retainingPaths != null);
     assert(objects != null);
-    RetainingPathElement e = document.createElement(tag.name);
+    RetainingPathElement e = new RetainingPathElement.created();
     e._r = new RenderingScheduler<RetainingPathElement>(e, queue: queue);
     e._isolate = isolate;
     e._object = object;
@@ -45,7 +45,7 @@
     return e;
   }
 
-  RetainingPathElement.created() : super.created();
+  RetainingPathElement.created() : super.created(tag);
 
   @override
   void attached() {
@@ -72,7 +72,7 @@
               e.control.disabled = false;
             }
           });
-    children = <Element>[curlyBlock];
+    children = <Element>[curlyBlock.element];
     _r.waitFor([curlyBlock.onRendered.first]);
   }
 
diff --git a/runtime/observatory/lib/src/elements/sample_buffer_control.dart b/runtime/observatory/lib/src/elements/sample_buffer_control.dart
index 0d5b38c..97adb22 100644
--- a/runtime/observatory/lib/src/elements/sample_buffer_control.dart
+++ b/runtime/observatory/lib/src/elements/sample_buffer_control.dart
@@ -14,7 +14,7 @@
   SampleBufferControlChangedElement(this.element);
 }
 
-class SampleBufferControlElement extends HtmlElement implements Renderable {
+class SampleBufferControlElement extends CustomElement implements Renderable {
   static const tag =
       const Tag<SampleBufferControlElement>('sample-buffer-control');
 
@@ -57,7 +57,7 @@
     assert(progressStream != null);
     assert(selectedTag != null);
     assert(showTag != null);
-    SampleBufferControlElement e = document.createElement(tag.name);
+    SampleBufferControlElement e = new SampleBufferControlElement.created();
     e._r = new RenderingScheduler<SampleBufferControlElement>(e, queue: queue);
     e._vm = vm;
     e._progress = progress;
@@ -67,7 +67,7 @@
     return e;
   }
 
-  SampleBufferControlElement.created() : super.created();
+  SampleBufferControlElement.created() : super.created(tag);
 
   @override
   void attached() {
@@ -220,7 +220,11 @@
   List<Element> _createTagSelect() {
     var values = M.SampleProfileTag.values;
     if (!_profileVM) {
-      values = const [M.SampleProfileTag.userOnly, M.SampleProfileTag.vmOnly, M.SampleProfileTag.none];
+      values = const [
+        M.SampleProfileTag.userOnly,
+        M.SampleProfileTag.vmOnly,
+        M.SampleProfileTag.none
+      ];
     }
     var s;
     return [
diff --git a/runtime/observatory/lib/src/elements/script_inset.dart b/runtime/observatory/lib/src/elements/script_inset.dart
index 8d4bb5a..9c5ca8f 100644
--- a/runtime/observatory/lib/src/elements/script_inset.dart
+++ b/runtime/observatory/lib/src/elements/script_inset.dart
@@ -16,7 +16,7 @@
 import 'package:observatory/src/elements/helpers/uris.dart';
 import 'package:observatory/utils.dart';
 
-class ScriptInsetElement extends HtmlElement implements Renderable {
+class ScriptInsetElement extends CustomElement implements Renderable {
   static const tag = const Tag<ScriptInsetElement>('script-inset');
 
   RenderingScheduler _r;
@@ -58,7 +58,7 @@
     assert(events != null);
     assert(inDebuggerContext != null);
     assert(variables != null);
-    ScriptInsetElement e = document.createElement(tag.name);
+    ScriptInsetElement e = new ScriptInsetElement.created();
     e._r = new RenderingScheduler<ScriptInsetElement>(e, queue: queue);
     e._isolate = isolate;
     e._script = script;
@@ -73,7 +73,7 @@
     return e;
   }
 
-  ScriptInsetElement.created() : super.created();
+  ScriptInsetElement.created() : super.created(tag);
 
   bool get noSource => _startPos == -1 || _loadedScript.source == null;
 
@@ -1382,10 +1382,10 @@
       ..setAttribute(
           'd',
           'M17.65 6.35C16.2 4.9 14.21 4 12 4c-4.42 0-7.99 '
-          '3.58-7.99 8s3.57 8 7.99 8c3.73 0 6.84-2.55 '
-          '7.73-6h-2.08c-.82 2.33-3.04 4-5.65 4-3.31 '
-          '0-6-2.69-6-6s2.69-6 6-6c1.66 0 3.14.69 4.22 '
-          '1.78L13 11h7V4l-2.35 2.35z')
+              '3.58-7.99 8s3.57 8 7.99 8c3.73 0 6.84-2.55 '
+              '7.73-6h-2.08c-.82 2.33-3.04 4-5.65 4-3.31 '
+              '0-6-2.69-6-6s2.69-6 6-6c1.66 0 3.14.69 4.22 '
+              '1.78L13 11h7V4l-2.35 2.35z')
   ];
 
 final SvgSvgElement _iconWhatsHot = new SvgSvgElement()
@@ -1396,10 +1396,10 @@
       ..setAttribute(
           'd',
           'M13.5.67s.74 2.65.74 4.8c0 2.06-1.35 3.73-3.41 '
-          '3.73-2.07 0-3.63-1.67-3.63-3.73l.03-.36C5.21 7.51 '
-          '4 10.62 4 14c0 4.42 3.58 8 8 8s8-3.58 8-8C20 8.61 '
-          '17.41 3.8 13.5.67zM11.71 19c-1.78 '
-          '0-3.22-1.4-3.22-3.14 0-1.62 1.05-2.76 2.81-3.12 '
-          '1.77-.36 3.6-1.21 4.62-2.58.39 1.29.59 2.65.59 '
-          '4.04 0 2.65-2.15 4.8-4.8 4.8z')
+              '3.73-2.07 0-3.63-1.67-3.63-3.73l.03-.36C5.21 7.51 '
+              '4 10.62 4 14c0 4.42 3.58 8 8 8s8-3.58 8-8C20 8.61 '
+              '17.41 3.8 13.5.67zM11.71 19c-1.78 '
+              '0-3.22-1.4-3.22-3.14 0-1.62 1.05-2.76 2.81-3.12 '
+              '1.77-.36 3.6-1.21 4.62-2.58.39 1.29.59 2.65.59 '
+              '4.04 0 2.65-2.15 4.8-4.8 4.8z')
   ];
diff --git a/runtime/observatory/lib/src/elements/script_ref.dart b/runtime/observatory/lib/src/elements/script_ref.dart
index eb1cc99..1ed7453c 100644
--- a/runtime/observatory/lib/src/elements/script_ref.dart
+++ b/runtime/observatory/lib/src/elements/script_ref.dart
@@ -11,7 +11,7 @@
 import 'package:observatory/src/elements/helpers/tag.dart';
 import 'package:observatory/src/elements/helpers/uris.dart';
 
-class ScriptRefElement extends HtmlElement implements Renderable {
+class ScriptRefElement extends CustomElement implements Renderable {
   static const tag = const Tag<ScriptRefElement>('script-ref');
 
   RenderingScheduler _r;
@@ -28,14 +28,14 @@
       {RenderingQueue queue}) {
     assert(isolate != null);
     assert(script != null);
-    ScriptRefElement e = document.createElement(tag.name);
+    ScriptRefElement e = new ScriptRefElement.created();
     e._r = new RenderingScheduler<ScriptRefElement>(e, queue: queue);
     e._isolate = isolate;
     e._script = script;
     return e;
   }
 
-  ScriptRefElement.created() : super.created();
+  ScriptRefElement.created() : super.created(tag);
 
   @override
   void attached() {
diff --git a/runtime/observatory/lib/src/elements/script_view.dart b/runtime/observatory/lib/src/elements/script_view.dart
index c797360..7be611b 100644
--- a/runtime/observatory/lib/src/elements/script_view.dart
+++ b/runtime/observatory/lib/src/elements/script_view.dart
@@ -23,7 +23,7 @@
 import 'package:observatory/src/elements/script_inset.dart';
 import 'package:observatory/src/elements/view_footer.dart';
 
-class ScriptViewElement extends HtmlElement implements Renderable {
+class ScriptViewElement extends CustomElement implements Renderable {
   static const tag =
       const Tag<ScriptViewElement>('script-view', dependencies: const [
     ContextRefElement.tag,
@@ -86,7 +86,7 @@
     assert(references != null);
     assert(retainingPaths != null);
     assert(objects != null);
-    ScriptViewElement e = document.createElement(tag.name);
+    ScriptViewElement e = new ScriptViewElement.created();
     e._r = new RenderingScheduler<ScriptViewElement>(e, queue: queue);
     e._vm = vm;
     e._isolate = isolate;
@@ -103,7 +103,7 @@
     return e;
   }
 
-  ScriptViewElement.created() : super.created();
+  ScriptViewElement.created() : super.created(tag);
 
   @override
   attached() {
@@ -121,18 +121,20 @@
   void render() {
     children = <Element>[
       navBar(<Element>[
-        new NavTopMenuElement(queue: _r.queue),
-        new NavVMMenuElement(_vm, _events, queue: _r.queue),
-        new NavIsolateMenuElement(_isolate, _events, queue: _r.queue),
-        new NavLibraryMenuElement(_isolate, _script.library, queue: _r.queue),
+        new NavTopMenuElement(queue: _r.queue).element,
+        new NavVMMenuElement(_vm, _events, queue: _r.queue).element,
+        new NavIsolateMenuElement(_isolate, _events, queue: _r.queue).element,
+        new NavLibraryMenuElement(_isolate, _script.library, queue: _r.queue)
+            .element,
         navMenu('object'),
-        new NavRefreshElement(queue: _r.queue)
-          ..onRefresh.listen((e) async {
-            e.element.disabled = true;
-            _script = await _scripts.get(_isolate, _script.id);
-            _r.dirty();
-          }),
-        new NavNotifyElement(_notifications, queue: _r.queue)
+        (new NavRefreshElement(queue: _r.queue)
+              ..onRefresh.listen((e) async {
+                e.element.disabled = true;
+                _script = await _scripts.get(_isolate, _script.id);
+                _r.dirty();
+              }))
+            .element,
+        new NavNotifyElement(_notifications, queue: _r.queue).element
       ]),
       new DivElement()
         ..classes = ['content-centered-big']
@@ -140,8 +142,9 @@
           new HeadingElement.h2()..text = 'Script',
           new HRElement(),
           new ObjectCommonElement(_isolate, _script, _retainedSizes,
-              _reachableSizes, _references, _retainingPaths, _objects,
-              queue: _r.queue),
+                  _reachableSizes, _references, _retainingPaths, _objects,
+                  queue: _r.queue)
+              .element,
           new BRElement(),
           new DivElement()
             ..classes = ['memberList']
@@ -159,8 +162,9 @@
             ],
           new HRElement(),
           new ScriptInsetElement(_isolate, _script, _scripts, _objects, _events,
-              currentPos: _pos, queue: _r.queue),
-          new ViewFooterElement(queue: _r.queue)
+                  currentPos: _pos, queue: _r.queue)
+              .element,
+          new ViewFooterElement(queue: _r.queue).element
         ]
     ];
   }
diff --git a/runtime/observatory/lib/src/elements/sentinel_value.dart b/runtime/observatory/lib/src/elements/sentinel_value.dart
index 70ea4a3..b646d9e 100644
--- a/runtime/observatory/lib/src/elements/sentinel_value.dart
+++ b/runtime/observatory/lib/src/elements/sentinel_value.dart
@@ -2,13 +2,13 @@
 // for details. 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:html';
 import 'dart:async';
+
 import 'package:observatory/models.dart' as M show Sentinel, SentinelKind;
 import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
 import 'package:observatory/src/elements/helpers/tag.dart';
 
-class SentinelValueElement extends HtmlElement implements Renderable {
+class SentinelValueElement extends CustomElement implements Renderable {
   static const tag = const Tag<SentinelValueElement>('sentinel-value');
 
   RenderingScheduler<SentinelValueElement> _r;
@@ -21,13 +21,13 @@
 
   factory SentinelValueElement(M.Sentinel sentinel, {RenderingQueue queue}) {
     assert(sentinel != null);
-    SentinelValueElement e = document.createElement(tag.name);
+    SentinelValueElement e = new SentinelValueElement.created();
     e._r = new RenderingScheduler<SentinelValueElement>(e, queue: queue);
     e._sentinel = sentinel;
     return e;
   }
 
-  SentinelValueElement.created() : super.created();
+  SentinelValueElement.created() : super.created(tag);
 
   @override
   void attached() {
diff --git a/runtime/observatory/lib/src/elements/sentinel_view.dart b/runtime/observatory/lib/src/elements/sentinel_view.dart
index 9d9a2ad..496c930 100644
--- a/runtime/observatory/lib/src/elements/sentinel_view.dart
+++ b/runtime/observatory/lib/src/elements/sentinel_view.dart
@@ -15,7 +15,7 @@
 import 'package:observatory/src/elements/nav/vm_menu.dart';
 import 'package:observatory/src/elements/view_footer.dart';
 
-class SentinelViewElement extends HtmlElement implements Renderable {
+class SentinelViewElement extends CustomElement implements Renderable {
   static const tag =
       const Tag<SentinelViewElement>('sentinel-view', dependencies: const [
     NavTopMenuElement.tag,
@@ -49,7 +49,7 @@
     assert(sentinel != null);
     assert(events != null);
     assert(notifications != null);
-    SentinelViewElement e = document.createElement(tag.name);
+    SentinelViewElement e = new SentinelViewElement.created();
     e._r = new RenderingScheduler<SentinelViewElement>(e, queue: queue);
     e._vm = vm;
     e._isolate = isolate;
@@ -59,7 +59,7 @@
     return e;
   }
 
-  SentinelViewElement.created() : super.created();
+  SentinelViewElement.created() : super.created(tag);
 
   @override
   void attached() {
@@ -78,11 +78,11 @@
   void render() {
     children = <Element>[
       navBar(<Element>[
-        new NavTopMenuElement(queue: _r.queue),
-        new NavVMMenuElement(_vm, _events, queue: _r.queue),
-        new NavIsolateMenuElement(_isolate, _events, queue: _r.queue),
+        new NavTopMenuElement(queue: _r.queue).element,
+        new NavVMMenuElement(_vm, _events, queue: _r.queue).element,
+        new NavIsolateMenuElement(_isolate, _events, queue: _r.queue).element,
         navMenu('sentinel'),
-        new NavNotifyElement(_notifications, queue: _r.queue)
+        new NavNotifyElement(_notifications, queue: _r.queue).element
       ]),
       new DivElement()
         ..classes = ['content-centered-big']
@@ -92,7 +92,7 @@
           new HRElement(),
           new DivElement()..text = _sentinelKindToDescription(_sentinel.kind),
           new HRElement(),
-          new ViewFooterElement(queue: _r.queue)
+          new ViewFooterElement(queue: _r.queue).element
         ]
     ];
   }
diff --git a/runtime/observatory/lib/src/elements/singletargetcache_ref.dart b/runtime/observatory/lib/src/elements/singletargetcache_ref.dart
index 1e2e3dd..9b8dd33 100644
--- a/runtime/observatory/lib/src/elements/singletargetcache_ref.dart
+++ b/runtime/observatory/lib/src/elements/singletargetcache_ref.dart
@@ -10,7 +10,7 @@
 import 'package:observatory/src/elements/helpers/tag.dart';
 import 'package:observatory/src/elements/helpers/uris.dart';
 
-class SingleTargetCacheRefElement extends HtmlElement implements Renderable {
+class SingleTargetCacheRefElement extends CustomElement implements Renderable {
   static const tag =
       const Tag<SingleTargetCacheRefElement>('singletargetcache-ref');
 
@@ -30,14 +30,14 @@
       {RenderingQueue queue}) {
     assert(isolate != null);
     assert(singleTargetCache != null);
-    SingleTargetCacheRefElement e = document.createElement(tag.name);
+    SingleTargetCacheRefElement e = new SingleTargetCacheRefElement.created();
     e._r = new RenderingScheduler<SingleTargetCacheRefElement>(e, queue: queue);
     e._isolate = isolate;
     e._singleTargetCache = singleTargetCache;
     return e;
   }
 
-  SingleTargetCacheRefElement.created() : super.created();
+  SingleTargetCacheRefElement.created() : super.created(tag);
 
   @override
   void attached() {
diff --git a/runtime/observatory/lib/src/elements/singletargetcache_view.dart b/runtime/observatory/lib/src/elements/singletargetcache_view.dart
index 651c9ff..05a306a 100644
--- a/runtime/observatory/lib/src/elements/singletargetcache_view.dart
+++ b/runtime/observatory/lib/src/elements/singletargetcache_view.dart
@@ -19,7 +19,7 @@
 import 'package:observatory/src/elements/object_common.dart';
 import 'package:observatory/src/elements/view_footer.dart';
 
-class SingleTargetCacheViewElement extends HtmlElement implements Renderable {
+class SingleTargetCacheViewElement extends CustomElement implements Renderable {
   static const tag = const Tag<SingleTargetCacheViewElement>(
       'singletargetcache-view',
       dependencies: const [
@@ -79,7 +79,7 @@
     assert(references != null);
     assert(retainingPaths != null);
     assert(objects != null);
-    SingleTargetCacheViewElement e = document.createElement(tag.name);
+    SingleTargetCacheViewElement e = new SingleTargetCacheViewElement.created();
     e._r =
         new RenderingScheduler<SingleTargetCacheViewElement>(e, queue: queue);
     e._vm = vm;
@@ -96,7 +96,7 @@
     return e;
   }
 
-  SingleTargetCacheViewElement.created() : super.created();
+  SingleTargetCacheViewElement.created() : super.created(tag);
 
   @override
   attached() {
@@ -114,18 +114,19 @@
   void render() {
     children = <Element>[
       navBar(<Element>[
-        new NavTopMenuElement(queue: _r.queue),
-        new NavVMMenuElement(_vm, _events, queue: _r.queue),
-        new NavIsolateMenuElement(_isolate, _events, queue: _r.queue),
+        new NavTopMenuElement(queue: _r.queue).element,
+        new NavVMMenuElement(_vm, _events, queue: _r.queue).element,
+        new NavIsolateMenuElement(_isolate, _events, queue: _r.queue).element,
         navMenu('singleTargetCache'),
-        new NavRefreshElement(queue: _r.queue)
-          ..onRefresh.listen((e) async {
-            e.element.disabled = true;
-            _singleTargetCache =
-                await _singleTargetCaches.get(_isolate, _singleTargetCache.id);
-            _r.dirty();
-          }),
-        new NavNotifyElement(_notifications, queue: _r.queue)
+        (new NavRefreshElement(queue: _r.queue)
+              ..onRefresh.listen((e) async {
+                e.element.disabled = true;
+                _singleTargetCache = await _singleTargetCaches.get(
+                    _isolate, _singleTargetCache.id);
+                _r.dirty();
+              }))
+            .element,
+        new NavNotifyElement(_notifications, queue: _r.queue).element
       ]),
       new DivElement()
         ..classes = ['content-centered-big']
@@ -133,8 +134,9 @@
           new HeadingElement.h2()..text = 'SingleTargetCache',
           new HRElement(),
           new ObjectCommonElement(_isolate, _singleTargetCache, _retainedSizes,
-              _reachableSizes, _references, _retainingPaths, _objects,
-              queue: _r.queue),
+                  _reachableSizes, _references, _retainingPaths, _objects,
+                  queue: _r.queue)
+              .element,
           new DivElement()
             ..classes = ['memberList']
             ..children = <Element>[
@@ -179,7 +181,7 @@
                 ]
             ],
           new HRElement(),
-          new ViewFooterElement(queue: _r.queue)
+          new ViewFooterElement(queue: _r.queue).element
         ]
     ];
   }
diff --git a/runtime/observatory/lib/src/elements/source_inset.dart b/runtime/observatory/lib/src/elements/source_inset.dart
index 210ce2e..42d3d2b 100644
--- a/runtime/observatory/lib/src/elements/source_inset.dart
+++ b/runtime/observatory/lib/src/elements/source_inset.dart
@@ -11,7 +11,7 @@
 import 'package:observatory/src/elements/helpers/tag.dart';
 import 'package:observatory/src/elements/script_inset.dart';
 
-class SourceInsetElement extends HtmlElement implements Renderable {
+class SourceInsetElement extends CustomElement implements Renderable {
   static const tag = const Tag<SourceInsetElement>('source-inset');
 
   RenderingScheduler _r;
@@ -47,7 +47,7 @@
     assert(events != null);
     assert(inDebuggerContext != null);
     assert(variables != null);
-    SourceInsetElement e = document.createElement(tag.name);
+    SourceInsetElement e = new SourceInsetElement.created();
     e._r = new RenderingScheduler<SourceInsetElement>(e, queue: queue);
     e._isolate = isolate;
     e._location = location;
@@ -60,7 +60,7 @@
     return e;
   }
 
-  SourceInsetElement.created() : super.created();
+  SourceInsetElement.created() : super.created(tag);
 
   @override
   void attached() {
@@ -78,13 +78,14 @@
   void render() {
     children = <Element>[
       new ScriptInsetElement(
-          _isolate, _location.script, _scripts, _objects, _events,
-          startPos: _location.tokenPos,
-          endPos: _location.endTokenPos,
-          currentPos: _currentPos,
-          inDebuggerContext: _inDebuggerContext,
-          variables: _variables,
-          queue: _r.queue)
+              _isolate, _location.script, _scripts, _objects, _events,
+              startPos: _location.tokenPos,
+              endPos: _location.endTokenPos,
+              currentPos: _currentPos,
+              inDebuggerContext: _inDebuggerContext,
+              variables: _variables,
+              queue: _r.queue)
+          .element
     ];
   }
 }
diff --git a/runtime/observatory/lib/src/elements/source_link.dart b/runtime/observatory/lib/src/elements/source_link.dart
index a08adbd..c6f816e 100644
--- a/runtime/observatory/lib/src/elements/source_link.dart
+++ b/runtime/observatory/lib/src/elements/source_link.dart
@@ -12,7 +12,7 @@
 import 'package:observatory/src/elements/helpers/tag.dart';
 import 'package:observatory/src/elements/helpers/uris.dart';
 
-class SourceLinkElement extends HtmlElement implements Renderable {
+class SourceLinkElement extends CustomElement implements Renderable {
   static const tag = const Tag<SourceLinkElement>('source-link');
 
   RenderingScheduler _r;
@@ -32,7 +32,7 @@
       {RenderingQueue queue}) {
     assert(isolate != null);
     assert(location != null);
-    SourceLinkElement e = document.createElement(tag.name);
+    SourceLinkElement e = new SourceLinkElement.created();
     e._r = new RenderingScheduler<SourceLinkElement>(e, queue: queue);
     e._isolate = isolate;
     e._location = location;
@@ -40,7 +40,7 @@
     return e;
   }
 
-  SourceLinkElement.created() : super.created();
+  SourceLinkElement.created() : super.created(tag);
 
   @override
   void attached() {
diff --git a/runtime/observatory/lib/src/elements/stack_trace_tree_config.dart b/runtime/observatory/lib/src/elements/stack_trace_tree_config.dart
index 9aedfc6..396b938 100644
--- a/runtime/observatory/lib/src/elements/stack_trace_tree_config.dart
+++ b/runtime/observatory/lib/src/elements/stack_trace_tree_config.dart
@@ -18,7 +18,7 @@
   StackTraceTreeConfigChangedEvent(this.element);
 }
 
-class StackTraceTreeConfigElement extends HtmlElement implements Renderable {
+class StackTraceTreeConfigElement extends CustomElement implements Renderable {
   static const tag =
       const Tag<StackTraceTreeConfigElement>('stack-trace-tree-config');
 
@@ -78,7 +78,7 @@
     assert(mode != null);
     assert(direction != null);
     assert(filter != null);
-    StackTraceTreeConfigElement e = document.createElement(tag.name);
+    StackTraceTreeConfigElement e = new StackTraceTreeConfigElement.created();
     e._r = new RenderingScheduler<StackTraceTreeConfigElement>(e, queue: queue);
     e._showMode = showMode;
     e._showDirection = showDirection;
@@ -89,7 +89,7 @@
     return e;
   }
 
-  StackTraceTreeConfigElement.created() : super.created();
+  StackTraceTreeConfigElement.created() : super.created(tag);
 
   @override
   void attached() {
diff --git a/runtime/observatory/lib/src/elements/strongly_reachable_instances.dart b/runtime/observatory/lib/src/elements/strongly_reachable_instances.dart
index 8319596..73c0f9e 100644
--- a/runtime/observatory/lib/src/elements/strongly_reachable_instances.dart
+++ b/runtime/observatory/lib/src/elements/strongly_reachable_instances.dart
@@ -11,7 +11,7 @@
 import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
 import 'package:observatory/src/elements/helpers/tag.dart';
 
-class StronglyReachableInstancesElement extends HtmlElement
+class StronglyReachableInstancesElement extends CustomElement
     implements Renderable {
   static const tag = const Tag<StronglyReachableInstancesElement>(
       'strongly-reachable-instances',
@@ -42,7 +42,8 @@
     assert(cls != null);
     assert(stronglyReachable != null);
     assert(objects != null);
-    StronglyReachableInstancesElement e = document.createElement(tag.name);
+    StronglyReachableInstancesElement e =
+        new StronglyReachableInstancesElement.created();
     e._r = new RenderingScheduler<StronglyReachableInstancesElement>(e,
         queue: queue);
     e._isolate = isolate;
@@ -52,7 +53,7 @@
     return e;
   }
 
-  StronglyReachableInstancesElement.created() : super.created();
+  StronglyReachableInstancesElement.created() : super.created(tag);
 
   @override
   void attached() {
@@ -69,14 +70,15 @@
 
   void render() {
     children = <Element>[
-      new CurlyBlockElement(expanded: _expanded, queue: _r.queue)
-        ..content = _createContent()
-        ..onToggle.listen((e) async {
-          _expanded = e.control.expanded;
-          e.control.disabled = true;
-          await _refresh();
-          e.control.disabled = false;
-        })
+      (new CurlyBlockElement(expanded: _expanded, queue: _r.queue)
+            ..content = _createContent()
+            ..onToggle.listen((e) async {
+              _expanded = e.control.expanded;
+              e.control.disabled = true;
+              await _refresh();
+              e.control.disabled = false;
+            }))
+          .element
     ];
   }
 
diff --git a/runtime/observatory/lib/src/elements/subtypetestcache_ref.dart b/runtime/observatory/lib/src/elements/subtypetestcache_ref.dart
index fb7cf89..6d7085b 100644
--- a/runtime/observatory/lib/src/elements/subtypetestcache_ref.dart
+++ b/runtime/observatory/lib/src/elements/subtypetestcache_ref.dart
@@ -10,7 +10,7 @@
 import 'package:observatory/src/elements/helpers/tag.dart';
 import 'package:observatory/src/elements/helpers/uris.dart';
 
-class SubtypeTestCacheRefElement extends HtmlElement implements Renderable {
+class SubtypeTestCacheRefElement extends CustomElement implements Renderable {
   static const tag =
       const Tag<SubtypeTestCacheRefElement>('subtypetestcache-ref');
 
@@ -30,14 +30,14 @@
       {RenderingQueue queue}) {
     assert(isolate != null);
     assert(subtypeTestCache != null);
-    SubtypeTestCacheRefElement e = document.createElement(tag.name);
+    SubtypeTestCacheRefElement e = new SubtypeTestCacheRefElement.created();
     e._r = new RenderingScheduler<SubtypeTestCacheRefElement>(e, queue: queue);
     e._isolate = isolate;
     e._subtypeTestCache = subtypeTestCache;
     return e;
   }
 
-  SubtypeTestCacheRefElement.created() : super.created();
+  SubtypeTestCacheRefElement.created() : super.created(tag);
 
   @override
   void attached() {
diff --git a/runtime/observatory/lib/src/elements/subtypetestcache_view.dart b/runtime/observatory/lib/src/elements/subtypetestcache_view.dart
index 80c14fd..b53cb43 100644
--- a/runtime/observatory/lib/src/elements/subtypetestcache_view.dart
+++ b/runtime/observatory/lib/src/elements/subtypetestcache_view.dart
@@ -19,7 +19,7 @@
 import 'package:observatory/src/elements/object_common.dart';
 import 'package:observatory/src/elements/view_footer.dart';
 
-class SubtypeTestCacheViewElement extends HtmlElement implements Renderable {
+class SubtypeTestCacheViewElement extends CustomElement implements Renderable {
   static const tag = const Tag<SubtypeTestCacheViewElement>(
       'subtypetestcache-view',
       dependencies: const [
@@ -79,7 +79,7 @@
     assert(references != null);
     assert(retainingPaths != null);
     assert(objects != null);
-    SubtypeTestCacheViewElement e = document.createElement(tag.name);
+    SubtypeTestCacheViewElement e = new SubtypeTestCacheViewElement.created();
     e._r = new RenderingScheduler<SubtypeTestCacheViewElement>(e, queue: queue);
     e._vm = vm;
     e._isolate = isolate;
@@ -95,7 +95,7 @@
     return e;
   }
 
-  SubtypeTestCacheViewElement.created() : super.created();
+  SubtypeTestCacheViewElement.created() : super.created(tag);
 
   @override
   attached() {
@@ -113,18 +113,19 @@
   void render() {
     children = <Element>[
       navBar(<Element>[
-        new NavTopMenuElement(queue: _r.queue),
-        new NavVMMenuElement(_vm, _events, queue: _r.queue),
-        new NavIsolateMenuElement(_isolate, _events, queue: _r.queue),
+        new NavTopMenuElement(queue: _r.queue).element,
+        new NavVMMenuElement(_vm, _events, queue: _r.queue).element,
+        new NavIsolateMenuElement(_isolate, _events, queue: _r.queue).element,
         navMenu('subtypeTestCache'),
-        new NavRefreshElement(queue: _r.queue)
-          ..onRefresh.listen((e) async {
-            e.element.disabled = true;
-            _subtypeTestCache =
-                await _subtypeTestCaches.get(_isolate, _subtypeTestCache.id);
-            _r.dirty();
-          }),
-        new NavNotifyElement(_notifications, queue: _r.queue)
+        (new NavRefreshElement(queue: _r.queue)
+              ..onRefresh.listen((e) async {
+                e.element.disabled = true;
+                _subtypeTestCache = await _subtypeTestCaches.get(
+                    _isolate, _subtypeTestCache.id);
+                _r.dirty();
+              }))
+            .element,
+        new NavNotifyElement(_notifications, queue: _r.queue).element
       ]),
       new DivElement()
         ..classes = ['content-centered-big']
@@ -132,8 +133,9 @@
           new HeadingElement.h2()..text = 'SubtypeTestCache',
           new HRElement(),
           new ObjectCommonElement(_isolate, _subtypeTestCache, _retainedSizes,
-              _reachableSizes, _references, _retainingPaths, _objects,
-              queue: _r.queue),
+                  _reachableSizes, _references, _retainingPaths, _objects,
+                  queue: _r.queue)
+              .element,
           new DivElement()
             ..classes = ['memberList']
             ..children = <Element>[
@@ -152,7 +154,7 @@
                 ]
             ],
           new HRElement(),
-          new ViewFooterElement(queue: _r.queue)
+          new ViewFooterElement(queue: _r.queue).element
         ]
     ];
   }
diff --git a/runtime/observatory/lib/src/elements/timeline/dashboard.dart b/runtime/observatory/lib/src/elements/timeline/dashboard.dart
index dbac222..584d8b8 100644
--- a/runtime/observatory/lib/src/elements/timeline/dashboard.dart
+++ b/runtime/observatory/lib/src/elements/timeline/dashboard.dart
@@ -33,7 +33,7 @@
 ///   overlapping the related events.
 enum _TimelineView { strict, frame }
 
-class TimelineDashboardElement extends HtmlElement implements Renderable {
+class TimelineDashboardElement extends CustomElement implements Renderable {
   static const tag = const Tag<TimelineDashboardElement>('timeline-dashboard',
       dependencies: const [NavNotifyElement.tag]);
 
@@ -57,7 +57,7 @@
     assert(vm != null);
     assert(repository != null);
     assert(notifications != null);
-    TimelineDashboardElement e = document.createElement(tag.name);
+    TimelineDashboardElement e = new TimelineDashboardElement.created();
     e._r = new RenderingScheduler<TimelineDashboardElement>(e, queue: queue);
     e._vm = vm;
     e._repository = repository;
@@ -68,7 +68,7 @@
     return e;
   }
 
-  TimelineDashboardElement.created() : super.created();
+  TimelineDashboardElement.created() : super.created(tag);
 
   @override
   attached() {
@@ -105,12 +105,13 @@
             ? 'Logical view of the computation involved in each frame '
                 '(timestamps may not be preserved)'
             : 'Sequence of events generated during the execution '
-            '(timestamps are preserved)')
+                '(timestamps are preserved)')
     ];
     if (children.isEmpty) {
       children = <Element>[
-        navBar(
-            <Element>[new NavNotifyElement(_notifications, queue: _r.queue)]),
+        navBar(<Element>[
+          new NavNotifyElement(_notifications, queue: _r.queue).element
+        ]),
         _content,
         new DivElement()
           ..classes = ['iframe']
diff --git a/runtime/observatory/lib/src/elements/timeline_page.dart b/runtime/observatory/lib/src/elements/timeline_page.dart
index 5a51145..f912239 100644
--- a/runtime/observatory/lib/src/elements/timeline_page.dart
+++ b/runtime/observatory/lib/src/elements/timeline_page.dart
@@ -18,7 +18,7 @@
 import 'package:observatory/src/elements/nav/top_menu.dart';
 import 'package:observatory/src/elements/nav/vm_menu.dart';
 
-class TimelinePageElement extends HtmlElement implements Renderable {
+class TimelinePageElement extends CustomElement implements Renderable {
   static const tag =
       const Tag<TimelinePageElement>('timeline-page', dependencies: const [
     NavTopMenuElement.tag,
@@ -50,7 +50,7 @@
     assert(repository != null);
     assert(events != null);
     assert(notifications != null);
-    TimelinePageElement e = document.createElement(tag.name);
+    TimelinePageElement e = new TimelinePageElement.created();
     e._r = new RenderingScheduler<TimelinePageElement>(e, queue: queue);
     e._vm = vm;
     e._repository = repository;
@@ -59,7 +59,7 @@
     return e;
   }
 
-  TimelinePageElement.created() : super.created();
+  TimelinePageElement.created() : super.created(tag);
 
   @override
   attached() {
@@ -132,34 +132,38 @@
 
     children = <Element>[
       navBar(<Element>[
-        new NavTopMenuElement(queue: _r.queue),
-        new NavVMMenuElement(vm, _events, queue: _r.queue),
+        new NavTopMenuElement(queue: _r.queue).element,
+        new NavVMMenuElement(vm, _events, queue: _r.queue).element,
         navMenu('timeline', link: Uris.timeline()),
-        new NavRefreshElement(queue: _r.queue)
-          ..onRefresh.listen((e) async {
-            e.element.disabled = true;
-            await _refresh();
-            e.element.disabled = !usingVMRecorder;
-          }),
-        new NavRefreshElement(label: 'clear', queue: _r.queue)
-          ..onRefresh.listen((e) async {
-            e.element.disabled = true;
-            await _clear();
-            e.element.disabled = !usingVMRecorder;
-          }),
-        new NavRefreshElement(label: 'save', queue: _r.queue)
-          ..onRefresh.listen((e) async {
-            e.element.disabled = true;
-            await _save();
-            e.element.disabled = !usingVMRecorder;
-          }),
-        new NavRefreshElement(label: 'load', queue: _r.queue)
-          ..onRefresh.listen((e) async {
-            e.element.disabled = true;
-            await _load();
-            e.element.disabled = !usingVMRecorder;
-          }),
-        new NavNotifyElement(_notifications, queue: _r.queue)
+        (new NavRefreshElement(queue: _r.queue)
+              ..onRefresh.listen((e) async {
+                e.element.disabled = true;
+                await _refresh();
+                e.element.disabled = !usingVMRecorder;
+              }))
+            .element,
+        (new NavRefreshElement(label: 'clear', queue: _r.queue)
+              ..onRefresh.listen((e) async {
+                e.element.disabled = true;
+                await _clear();
+                e.element.disabled = !usingVMRecorder;
+              }))
+            .element,
+        (new NavRefreshElement(label: 'save', queue: _r.queue)
+              ..onRefresh.listen((e) async {
+                e.element.disabled = true;
+                await _save();
+                e.element.disabled = !usingVMRecorder;
+              }))
+            .element,
+        (new NavRefreshElement(label: 'load', queue: _r.queue)
+              ..onRefresh.listen((e) async {
+                e.element.disabled = true;
+                await _load();
+                e.element.disabled = !usingVMRecorder;
+              }))
+            .element,
+        new NavNotifyElement(_notifications, queue: _r.queue).element
       ]),
       _content,
       _createIFrameOrMessage(),
diff --git a/runtime/observatory/lib/src/elements/top_retaining_instances.dart b/runtime/observatory/lib/src/elements/top_retaining_instances.dart
index 4d63dde..31a84a5 100644
--- a/runtime/observatory/lib/src/elements/top_retaining_instances.dart
+++ b/runtime/observatory/lib/src/elements/top_retaining_instances.dart
@@ -12,7 +12,7 @@
 import 'package:observatory/src/elements/helpers/tag.dart';
 import 'package:observatory/utils.dart';
 
-class TopRetainingInstancesElement extends HtmlElement implements Renderable {
+class TopRetainingInstancesElement extends CustomElement implements Renderable {
   static const tag = const Tag<TopRetainingInstancesElement>(
       'top-retainig-instances',
       dependencies: const [CurlyBlockElement.tag, InstanceRefElement.tag]);
@@ -42,7 +42,7 @@
     assert(cls != null);
     assert(topRetainingInstances != null);
     assert(objects != null);
-    TopRetainingInstancesElement e = document.createElement(tag.name);
+    TopRetainingInstancesElement e = new TopRetainingInstancesElement.created();
     e._r =
         new RenderingScheduler<TopRetainingInstancesElement>(e, queue: queue);
     e._isolate = isolate;
@@ -52,7 +52,7 @@
     return e;
   }
 
-  TopRetainingInstancesElement.created() : super.created();
+  TopRetainingInstancesElement.created() : super.created(tag);
 
   @override
   void attached() {
@@ -69,20 +69,21 @@
 
   void render() {
     children = <Element>[
-      new CurlyBlockElement(expanded: _expanded, queue: _r.queue)
-        ..content = <Element>[
-          new DivElement()
-            ..classes = ['memberList']
-            ..children = _createContent()
-        ]
-        ..onToggle.listen((e) async {
-          _expanded = e.control.expanded;
-          if (_expanded) {
-            e.control.disabled = true;
-            await _refresh();
-            e.control.disabled = false;
-          }
-        })
+      (new CurlyBlockElement(expanded: _expanded, queue: _r.queue)
+            ..content = <Element>[
+              new DivElement()
+                ..classes = ['memberList']
+                ..children = _createContent()
+            ]
+            ..onToggle.listen((e) async {
+              _expanded = e.control.expanded;
+              if (_expanded) {
+                e.control.disabled = true;
+                await _refresh();
+                e.control.disabled = false;
+              }
+            }))
+          .element
     ];
   }
 
diff --git a/runtime/observatory/lib/src/elements/type_arguments_ref.dart b/runtime/observatory/lib/src/elements/type_arguments_ref.dart
index f29e560..c0c7ed1 100644
--- a/runtime/observatory/lib/src/elements/type_arguments_ref.dart
+++ b/runtime/observatory/lib/src/elements/type_arguments_ref.dart
@@ -9,7 +9,7 @@
 import 'package:observatory/src/elements/helpers/tag.dart';
 import 'package:observatory/src/elements/helpers/uris.dart';
 
-class TypeArgumentsRefElement extends HtmlElement implements Renderable {
+class TypeArgumentsRefElement extends CustomElement implements Renderable {
   static const tag = const Tag<TypeArgumentsRefElement>('type-arguments-ref');
 
   RenderingScheduler<TypeArgumentsRefElement> _r;
@@ -27,14 +27,14 @@
       {RenderingQueue queue}) {
     assert(isolate != null);
     assert(args != null);
-    TypeArgumentsRefElement e = document.createElement(tag.name);
+    TypeArgumentsRefElement e = new TypeArgumentsRefElement.created();
     e._r = new RenderingScheduler<TypeArgumentsRefElement>(e, queue: queue);
     e._isolate = isolate;
     e._arguments = args;
     return e;
   }
 
-  TypeArgumentsRefElement.created() : super.created();
+  TypeArgumentsRefElement.created() : super.created(tag);
 
   @override
   void attached() {
diff --git a/runtime/observatory/lib/src/elements/unknown_ref.dart b/runtime/observatory/lib/src/elements/unknown_ref.dart
index ff287c0..cad1136 100644
--- a/runtime/observatory/lib/src/elements/unknown_ref.dart
+++ b/runtime/observatory/lib/src/elements/unknown_ref.dart
@@ -9,7 +9,7 @@
 import 'package:observatory/src/elements/helpers/tag.dart';
 import 'package:observatory/src/elements/helpers/uris.dart';
 
-class UnknownObjectRefElement extends HtmlElement implements Renderable {
+class UnknownObjectRefElement extends CustomElement implements Renderable {
   static const tag = const Tag<UnknownObjectRefElement>('unknown-ref');
 
   RenderingScheduler<UnknownObjectRefElement> _r;
@@ -27,14 +27,14 @@
       {RenderingQueue queue}) {
     assert(isolate != null);
     assert(obj != null);
-    UnknownObjectRefElement e = document.createElement(tag.name);
+    UnknownObjectRefElement e = new UnknownObjectRefElement.created();
     e._r = new RenderingScheduler<UnknownObjectRefElement>(e, queue: queue);
     e._isolate = isolate;
     e._obj = obj;
     return e;
   }
 
-  UnknownObjectRefElement.created() : super.created();
+  UnknownObjectRefElement.created() : super.created(tag);
 
   @override
   void attached() {
diff --git a/runtime/observatory/lib/src/elements/unlinkedcall_ref.dart b/runtime/observatory/lib/src/elements/unlinkedcall_ref.dart
index 02a4434..9a13575 100644
--- a/runtime/observatory/lib/src/elements/unlinkedcall_ref.dart
+++ b/runtime/observatory/lib/src/elements/unlinkedcall_ref.dart
@@ -9,7 +9,7 @@
 import 'package:observatory/src/elements/helpers/tag.dart';
 import 'package:observatory/src/elements/helpers/uris.dart';
 
-class UnlinkedCallRefElement extends HtmlElement implements Renderable {
+class UnlinkedCallRefElement extends CustomElement implements Renderable {
   static const tag = const Tag<UnlinkedCallRefElement>('unlinkedcall-ref');
 
   RenderingScheduler<UnlinkedCallRefElement> _r;
@@ -27,14 +27,14 @@
       {RenderingQueue queue}) {
     assert(isolate != null);
     assert(unlinkedcall != null);
-    UnlinkedCallRefElement e = document.createElement(tag.name);
+    UnlinkedCallRefElement e = new UnlinkedCallRefElement.created();
     e._r = new RenderingScheduler<UnlinkedCallRefElement>(e, queue: queue);
     e._isolate = isolate;
     e._unlinkedcall = unlinkedcall;
     return e;
   }
 
-  UnlinkedCallRefElement.created() : super.created();
+  UnlinkedCallRefElement.created() : super.created(tag);
 
   @override
   void attached() {
diff --git a/runtime/observatory/lib/src/elements/unlinkedcall_view.dart b/runtime/observatory/lib/src/elements/unlinkedcall_view.dart
index d46f170..315c58b 100644
--- a/runtime/observatory/lib/src/elements/unlinkedcall_view.dart
+++ b/runtime/observatory/lib/src/elements/unlinkedcall_view.dart
@@ -19,7 +19,7 @@
 import 'package:observatory/src/elements/object_common.dart';
 import 'package:observatory/src/elements/view_footer.dart';
 
-class UnlinkedCallViewElement extends HtmlElement implements Renderable {
+class UnlinkedCallViewElement extends CustomElement implements Renderable {
   static const tag = const Tag<UnlinkedCallViewElement>('unlinkedcall-view',
       dependencies: const [
         CurlyBlockElement.tag,
@@ -78,7 +78,7 @@
     assert(references != null);
     assert(retainingPaths != null);
     assert(objects != null);
-    UnlinkedCallViewElement e = document.createElement(tag.name);
+    UnlinkedCallViewElement e = new UnlinkedCallViewElement.created();
     e._r = new RenderingScheduler<UnlinkedCallViewElement>(e, queue: queue);
     e._vm = vm;
     e._isolate = isolate;
@@ -94,7 +94,7 @@
     return e;
   }
 
-  UnlinkedCallViewElement.created() : super.created();
+  UnlinkedCallViewElement.created() : super.created(tag);
 
   @override
   attached() {
@@ -112,18 +112,19 @@
   void render() {
     children = <Element>[
       navBar(<Element>[
-        new NavTopMenuElement(queue: _r.queue),
-        new NavVMMenuElement(_vm, _events, queue: _r.queue),
-        new NavIsolateMenuElement(_isolate, _events, queue: _r.queue),
+        new NavTopMenuElement(queue: _r.queue).element,
+        new NavVMMenuElement(_vm, _events, queue: _r.queue).element,
+        new NavIsolateMenuElement(_isolate, _events, queue: _r.queue).element,
         navMenu('unlinkedcall'),
-        new NavRefreshElement(queue: _r.queue)
-          ..onRefresh.listen((e) async {
-            e.element.disabled = true;
-            _unlinkedcall =
-                await _unlinkedcalls.get(_isolate, _unlinkedcall.id);
-            _r.dirty();
-          }),
-        new NavNotifyElement(_notifications, queue: _r.queue)
+        (new NavRefreshElement(queue: _r.queue)
+              ..onRefresh.listen((e) async {
+                e.element.disabled = true;
+                _unlinkedcall =
+                    await _unlinkedcalls.get(_isolate, _unlinkedcall.id);
+                _r.dirty();
+              }))
+            .element,
+        new NavNotifyElement(_notifications, queue: _r.queue).element
       ]),
       new DivElement()
         ..classes = ['content-centered-big']
@@ -131,8 +132,9 @@
           new HeadingElement.h2()..text = 'UnlinkedCall',
           new HRElement(),
           new ObjectCommonElement(_isolate, _unlinkedcall, _retainedSizes,
-              _reachableSizes, _references, _retainingPaths, _objects,
-              queue: _r.queue),
+                  _reachableSizes, _references, _retainingPaths, _objects,
+                  queue: _r.queue)
+              .element,
           new DivElement()
             ..classes = ['memberList']
             ..children = <Element>[
@@ -164,7 +166,7 @@
                 ]
             ],
           new HRElement(),
-          new ViewFooterElement(queue: _r.queue)
+          new ViewFooterElement(queue: _r.queue).element
         ]
     ];
   }
diff --git a/runtime/observatory/lib/src/elements/view_footer.dart b/runtime/observatory/lib/src/elements/view_footer.dart
index a1a039b..d401bde 100644
--- a/runtime/observatory/lib/src/elements/view_footer.dart
+++ b/runtime/observatory/lib/src/elements/view_footer.dart
@@ -9,7 +9,7 @@
 import 'package:observatory/src/elements/helpers/tag.dart';
 import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
 
-class ViewFooterElement extends HtmlElement implements Renderable {
+class ViewFooterElement extends CustomElement implements Renderable {
   static const tag = const Tag<ViewFooterElement>('view-footer');
 
   RenderingScheduler _r;
@@ -17,12 +17,12 @@
   Stream<RenderedEvent<ViewFooterElement>> get onRendered => _r.onRendered;
 
   factory ViewFooterElement({RenderingQueue queue}) {
-    ViewFooterElement e = document.createElement(tag.name);
+    ViewFooterElement e = new ViewFooterElement.created();
     e._r = new RenderingScheduler<ViewFooterElement>(e, queue: queue);
     return e;
   }
 
-  ViewFooterElement.created() : super.created();
+  ViewFooterElement.created() : super.created(tag);
 
   @override
   void attached() {
diff --git a/runtime/observatory/lib/src/elements/vm_connect.dart b/runtime/observatory/lib/src/elements/vm_connect.dart
index c8cac11..576aa76 100644
--- a/runtime/observatory/lib/src/elements/vm_connect.dart
+++ b/runtime/observatory/lib/src/elements/vm_connect.dart
@@ -4,19 +4,19 @@
 
 library vm_connect_element;
 
-import 'dart:html';
 import 'dart:async';
-import 'dart:convert';
+import 'dart:html';
+
 import 'package:observatory/models.dart' as M;
-import 'package:observatory/src/elements/helpers/tag.dart';
-import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
 import 'package:observatory/src/elements/helpers/nav_bar.dart';
+import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
 import 'package:observatory/src/elements/nav/notify.dart';
 import 'package:observatory/src/elements/nav/top_menu.dart';
 import 'package:observatory/src/elements/view_footer.dart';
 import 'package:observatory/src/elements/vm_connect_target.dart';
 
-class VMConnectElement extends HtmlElement implements Renderable {
+class VMConnectElement extends CustomElement implements Renderable {
   static const tag =
       const Tag<VMConnectElement>('vm-connect', dependencies: const [
     NavTopMenuElement.tag,
@@ -41,7 +41,7 @@
     assert(address != null);
     assert(notifications != null);
     assert(targets != null);
-    VMConnectElement e = document.createElement(tag.name);
+    VMConnectElement e = new VMConnectElement.created();
     e._r = new RenderingScheduler<VMConnectElement>(e, queue: queue);
     e._address = address;
     e._notifications = notifications;
@@ -49,7 +49,7 @@
     return e;
   }
 
-  VMConnectElement.created() : super.created();
+  VMConnectElement.created() : super.created(tag);
 
   @override
   void attached() {
@@ -71,8 +71,8 @@
     final port = window.location.port;
     children = <Element>[
       navBar(<Element>[
-        new NavTopMenuElement(queue: _r.queue),
-        new NavNotifyElement(_notifications, queue: _r.queue)
+        new NavTopMenuElement(queue: _r.queue).element,
+        new NavNotifyElement(_notifications, queue: _r.queue).element
       ]),
       new DivElement()
         ..classes = ['content-centered']
@@ -93,10 +93,11 @@
                       final bool current = _targets.isConnectedVMTarget(target);
                       return new LIElement()
                         ..children = <Element>[
-                          new VMConnectTargetElement(target,
-                              current: current, queue: _r.queue)
-                            ..onConnect.listen(_connect)
-                            ..onDelete.listen(_delete)
+                          (new VMConnectTargetElement(target,
+                                  current: current, queue: _r.queue)
+                                ..onConnect.listen(_connect)
+                                ..onDelete.listen(_delete))
+                              .element
                         ];
                     }).toList(),
                   new HRElement(),
@@ -121,7 +122,7 @@
               new DivElement()..classes = ['flex-item-20-percent'],
             ],
         ],
-      new ViewFooterElement(queue: _r.queue)
+      new ViewFooterElement(queue: _r.queue).element
     ];
   }
 
diff --git a/runtime/observatory/lib/src/elements/vm_connect_target.dart b/runtime/observatory/lib/src/elements/vm_connect_target.dart
index 2a2dd81..0f6575b 100644
--- a/runtime/observatory/lib/src/elements/vm_connect_target.dart
+++ b/runtime/observatory/lib/src/elements/vm_connect_target.dart
@@ -14,7 +14,7 @@
   TargetEvent(this.target);
 }
 
-class VMConnectTargetElement extends HtmlElement implements Renderable {
+class VMConnectTargetElement extends CustomElement implements Renderable {
   static const tag = const Tag<VMConnectTargetElement>('vm-connect-target');
 
   RenderingScheduler<VMConnectTargetElement> _r;
@@ -38,14 +38,14 @@
       {bool current: false, RenderingQueue queue}) {
     assert(target != null);
     assert(current != null);
-    VMConnectTargetElement e = document.createElement(tag.name);
+    VMConnectTargetElement e = new VMConnectTargetElement.created();
     e._r = new RenderingScheduler<VMConnectTargetElement>(e, queue: queue);
     e._target = target;
     e._current = current;
     return e;
   }
 
-  VMConnectTargetElement.created() : super.created();
+  VMConnectTargetElement.created() : super.created(tag);
 
   @override
   void attached() {
diff --git a/runtime/observatory/lib/src/elements/vm_view.dart b/runtime/observatory/lib/src/elements/vm_view.dart
index 4e79116..f5f5609 100644
--- a/runtime/observatory/lib/src/elements/vm_view.dart
+++ b/runtime/observatory/lib/src/elements/vm_view.dart
@@ -19,7 +19,7 @@
 import 'package:observatory/src/elements/view_footer.dart';
 import 'package:observatory/utils.dart';
 
-class VMViewElement extends HtmlElement implements Renderable {
+class VMViewElement extends CustomElement implements Renderable {
   static const tag = const Tag<VMViewElement>('vm-view', dependencies: const [
     IsolateSummaryElement.tag,
     NavTopMenuElement.tag,
@@ -60,7 +60,7 @@
     assert(notifications != null);
     assert(isolates != null);
     assert(scripts != null);
-    VMViewElement e = document.createElement(tag.name);
+    VMViewElement e = new VMViewElement.created();
     e._r = new RenderingScheduler<VMViewElement>(e, queue: queue);
     e._vm = vm;
     e._vms = vms;
@@ -71,7 +71,7 @@
     return e;
   }
 
-  VMViewElement.created() : super.created();
+  VMViewElement.created() : super.created(tag);
 
   @override
   attached() {
@@ -100,15 +100,16 @@
     final isolates = _vm.isolates.toList();
     children = <Element>[
       navBar(<Element>[
-        new NavTopMenuElement(queue: _r.queue),
-        new NavVMMenuElement(_vm, _events, queue: _r.queue),
-        new NavRefreshElement(queue: _r.queue)
-          ..onRefresh.listen((e) async {
-            e.element.disabled = true;
-            _vm = await _vms.get(_vm);
-            _r.dirty();
-          }),
-        new NavNotifyElement(_notifications, queue: _r.queue)
+        new NavTopMenuElement(queue: _r.queue).element,
+        new NavVMMenuElement(_vm, _events, queue: _r.queue).element,
+        (new NavRefreshElement(queue: _r.queue)
+              ..onRefresh.listen((e) async {
+                e.element.disabled = true;
+                _vm = await _vms.get(_vm);
+                _r.dirty();
+              }))
+            .element,
+        new NavNotifyElement(_notifications, queue: _r.queue).element
       ]),
       new DivElement()
         ..classes = ['content-centered-big']
@@ -291,13 +292,14 @@
                         ..classes = ['list-group-item']
                         ..children = <Element>[
                           new IsolateSummaryElement(
-                              i, _isolates, _events, _scripts,
-                              queue: _r.queue)
+                                  i, _isolates, _events, _scripts,
+                                  queue: _r.queue)
+                              .element
                         ],
                       new HRElement()
                     ])
                 .toList(),
-          new ViewFooterElement(queue: _r.queue)
+          new ViewFooterElement(queue: _r.queue).element
         ]
     ];
   }
diff --git a/runtime/observatory/pubspec.yaml b/runtime/observatory/pubspec.yaml
index 76e6219..2059c3d 100644
--- a/runtime/observatory/pubspec.yaml
+++ b/runtime/observatory/pubspec.yaml
@@ -1,3 +1,3 @@
 name: observatory
 environment:
-  sdk: '>=2.0.0 <3.0.0'
+  sdk: '>=2.2.0 <3.0.0'
diff --git a/runtime/observatory/tests/observatory_ui/allocation_profile/element_test.dart b/runtime/observatory/tests/observatory_ui/allocation_profile/element_test.dart
deleted file mode 100644
index 3673da4..0000000
--- a/runtime/observatory/tests/observatory_ui/allocation_profile/element_test.dart
+++ /dev/null
@@ -1,184 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:html';
-import 'dart:async';
-import 'package:test/test.dart';
-import 'package:observatory/models.dart' as M;
-import 'package:observatory/src/elements/allocation_profile.dart';
-import 'package:observatory/src/elements/class_ref.dart';
-import 'package:observatory/src/elements/containers/virtual_collection.dart';
-import 'package:observatory/src/elements/nav/refresh.dart';
-import '../mocks.dart';
-
-main() {
-  AllocationProfileElement.tag.ensureRegistration();
-
-  final cTag = ClassRefElement.tag.name;
-  final rTag = NavRefreshElement.tag.name;
-  final vTag = VirtualCollectionElement.tag.name;
-
-  const vm = const VMMock();
-  const isolate = const IsolateRefMock();
-  final events = new EventRepositoryMock();
-  final notif = new NotificationRepositoryMock();
-  test('instantiation', () {
-    final repo = new AllocationProfileRepositoryMock();
-    final e = new AllocationProfileElement(vm, isolate, events, notif, repo);
-    expect(e, isNotNull, reason: 'element correctly created');
-  });
-  test('elements created', () async {
-    final completer = new Completer<AllocationProfileMock>();
-    final repo = new AllocationProfileRepositoryMock(
-        getter:
-            expectAsync4((M.IsolateRef i, bool gc, bool reset, bool combine) {
-      expect(i, equals(isolate));
-      expect(gc, isFalse);
-      expect(reset, isFalse);
-      expect(combine, isFalse);
-      return completer.future;
-    }, count: 1));
-    final e = new AllocationProfileElement(vm, isolate, events, notif, repo);
-    document.body.append(e);
-    await e.onRendered.first;
-    expect(e.children.length, isNonZero, reason: 'has elements');
-    expect(e.querySelectorAll(vTag).length, isZero);
-    completer.complete(const AllocationProfileMock());
-    await e.onRendered.first;
-    expect(e.querySelectorAll(vTag).length, equals(1));
-    e.remove();
-    await e.onRendered.first;
-    expect(e.children.length, isZero, reason: 'is empty');
-  });
-  group('reacts', () {
-    test('to refresh', () async {
-      final completer = new Completer<AllocationProfileMock>();
-      int step = 0;
-      final repo = new AllocationProfileRepositoryMock(
-          getter:
-              expectAsync4((M.IsolateRef i, bool gc, bool reset, bool combine) {
-        expect(i, equals(isolate));
-        expect(combine, isFalse);
-        switch (step) {
-          case 0:
-            expect(gc, isFalse);
-            expect(reset, isFalse);
-            break;
-          case 1:
-            expect(gc, isFalse);
-            expect(reset, isTrue);
-            break;
-          case 2:
-            expect(gc, isTrue);
-            expect(reset, isFalse);
-            break;
-          case 3:
-            expect(gc, isFalse);
-            expect(reset, isFalse);
-            break;
-        }
-        step++;
-        return completer.future;
-      }, count: 4));
-      final e = new AllocationProfileElement(vm, isolate, events, notif, repo);
-      document.body.append(e);
-      await e.onRendered.first;
-      completer.complete(const AllocationProfileMock());
-      await e.onRendered.first;
-      e
-          .querySelectorAll(rTag)
-          .sublist(1, 4)
-          .forEach((e) => (e as NavRefreshElement).refresh());
-      e.remove();
-      await e.onRendered.first;
-      expect(e.children.length, isZero, reason: 'is empty');
-    });
-    test('to gc', () async {
-      final events = new EventRepositoryMock();
-      final completer = new Completer<AllocationProfileMock>();
-      int count = 0;
-      final repo = new AllocationProfileRepositoryMock(
-          getter:
-              expectAsync4((M.IsolateRef i, bool gc, bool reset, bool combine) {
-        expect(i, equals(isolate));
-        expect(gc, isFalse);
-        expect(reset, isFalse);
-        expect(combine, isFalse);
-        count++;
-        return completer.future;
-      }, count: 2));
-      final e = new AllocationProfileElement(vm, isolate, events, notif, repo);
-      document.body.append(e);
-      await e.onRendered.first;
-      completer.complete(const AllocationProfileMock());
-      await e.onRendered.first;
-      e.querySelector('input[type=\'checkbox\']').click();
-      expect(events.onGCEventHasListener, isTrue);
-      events.add(new GCEventMock(isolate: isolate));
-      await e.onRendered.first;
-      expect(count, equals(2));
-      // shouldn't trigger
-      events.add(new GCEventMock(isolate: new IsolateRefMock(id: 'another')));
-      await (() async {}());
-      e.querySelector('input[type=\'checkbox\']').click();
-      // shouldn't trigger
-      events.add(new GCEventMock(isolate: isolate));
-      await (() async {}());
-      e.remove();
-      await e.onRendered.first;
-      expect(e.children.length, isZero, reason: 'is empty');
-    });
-    test('to sort change', () async {
-      const clazz1 = const ClassRefMock(name: 'class1');
-      const clazz2 = const ClassRefMock(name: 'class2');
-      const clazz3 = const ClassRefMock(name: 'class3');
-      const profile = const AllocationProfileMock(members: const [
-        const ClassHeapStatsMock(clazz: clazz1),
-        const ClassHeapStatsMock(
-            clazz: clazz2,
-            newSpace: const AllocationsMock(
-                current: const AllocationCountMock(bytes: 10)),
-            oldSpace: const AllocationsMock(
-                current: const AllocationCountMock(bytes: 2))),
-        const ClassHeapStatsMock(
-            clazz: clazz3,
-            newSpace: const AllocationsMock(
-                current: const AllocationCountMock(bytes: 5)),
-            oldSpace: const AllocationsMock(
-                current: const AllocationCountMock(bytes: 3)))
-      ]);
-      final completer = new Completer<AllocationProfileMock>();
-      final repo = new AllocationProfileRepositoryMock(
-          getter:
-              expectAsync4((M.IsolateRef i, bool gc, bool reset, bool combine) {
-        expect(i, equals(isolate));
-        expect(gc, isFalse);
-        expect(reset, isFalse);
-        expect(combine, isFalse);
-        return completer.future;
-      }, count: 1));
-      final e = new AllocationProfileElement(vm, isolate, events, notif, repo);
-      document.body.append(e);
-      await e.onRendered.first;
-      completer.complete(profile);
-      await e.onRendered.first;
-      expect((e.querySelector(cTag) as ClassRefElement).cls, equals(clazz2));
-      e.querySelector('button.name').click();
-      await e.onRendered.first;
-      expect((e.querySelector(cTag) as ClassRefElement).cls, equals(clazz1));
-      e.querySelector('button.name').click();
-      await e.onRendered.first;
-      expect((e.querySelector(cTag) as ClassRefElement).cls, equals(clazz3));
-      e.querySelectorAll('button.bytes').last.click();
-      await e.onRendered.first;
-      expect((e.querySelector(cTag) as ClassRefElement).cls, equals(clazz3));
-      e.querySelectorAll('button.bytes').last.click();
-      await e.onRendered.first;
-      expect((e.querySelector(cTag) as ClassRefElement).cls, equals(clazz1));
-      e.remove();
-      await e.onRendered.first;
-      expect(e.children.length, isZero, reason: 'is empty');
-    });
-  });
-}
diff --git a/runtime/observatory/tests/observatory_ui/allocation_profile/element_test.html b/runtime/observatory/tests/observatory_ui/allocation_profile/element_test.html
deleted file mode 100644
index f548be4..0000000
--- a/runtime/observatory/tests/observatory_ui/allocation_profile/element_test.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-  <meta http-equiv="X-UA-Compatible" content="IE=edge">
-  <meta name="dart.unittest" content="full-stack-traces">
-  <style>
-     .unittest-table { font-family:monospace; border:1px; }
-     .unittest-pass { background: #6b3;}
-     .unittest-fail { background: #d55;}
-     .unittest-error { background: #a11;}
-  </style>
-</head>
-<body>
-  <script type="text/javascript"
-      src="/root_dart/tools/testing/dart/test_controller.js"></script>
-  %TEST_SCRIPTS%
-</body>
-</html>
diff --git a/runtime/observatory/tests/observatory_ui/app_test.dart b/runtime/observatory/tests/observatory_ui/app_test.dart
new file mode 100644
index 0000000..0fab60c
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/app_test.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'package:logging/logging.dart';
+import 'package:observatory/elements.dart';
+import 'package:stack_trace/stack_trace.dart';
+
+main() async {
+  Chain.capture(() async {
+    Logger.root.level = Level.INFO;
+    Logger.root.onRecord.listen((LogRecord rec) {
+      print('${rec.level.name}: ${rec.time}: ${rec.message}');
+    });
+    Logger.root.info('Starting Observatory');
+    document.body.children
+        .insert(0, new ObservatoryApplicationElement.created().element);
+  });
+}
diff --git a/runtime/observatory/tests/observatory_ui/class_ref/element_test.dart b/runtime/observatory/tests/observatory_ui/class_ref/element_test.dart
deleted file mode 100644
index 3baccf5..0000000
--- a/runtime/observatory/tests/observatory_ui/class_ref/element_test.dart
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:html';
-import 'package:test/test.dart';
-import 'package:observatory/src/elements/class_ref.dart';
-import '../mocks.dart';
-
-main() {
-  ClassRefElement.tag.ensureRegistration();
-
-  const isolate = const IsolateRefMock();
-  const cls = const ClassRefMock();
-  test('instantiation', () {
-    final e = new ClassRefElement(isolate, cls);
-    expect(e, isNotNull, reason: 'element correctly created');
-    expect(e.isolate, equals(isolate));
-    expect(e.cls, equals(cls));
-  });
-  test('elements created after attachment', () async {
-    final e = new ClassRefElement(isolate, cls);
-    document.body.append(e);
-    await e.onRendered.first;
-    expect(e.children.length, isNonZero, reason: 'has elements');
-    e.remove();
-    await e.onRendered.first;
-    expect(e.children.length, isZero, reason: 'is empty');
-  });
-}
diff --git a/runtime/observatory/tests/observatory_ui/class_ref/element_test.html b/runtime/observatory/tests/observatory_ui/class_ref/element_test.html
deleted file mode 100644
index f548be4..0000000
--- a/runtime/observatory/tests/observatory_ui/class_ref/element_test.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-  <meta http-equiv="X-UA-Compatible" content="IE=edge">
-  <meta name="dart.unittest" content="full-stack-traces">
-  <style>
-     .unittest-table { font-family:monospace; border:1px; }
-     .unittest-pass { background: #6b3;}
-     .unittest-fail { background: #d55;}
-     .unittest-error { background: #a11;}
-  </style>
-</head>
-<body>
-  <script type="text/javascript"
-      src="/root_dart/tools/testing/dart/test_controller.js"></script>
-  %TEST_SCRIPTS%
-</body>
-</html>
diff --git a/runtime/observatory/tests/observatory_ui/class_tree/element_test.dart b/runtime/observatory/tests/observatory_ui/class_tree/element_test.dart
deleted file mode 100644
index ed05811..0000000
--- a/runtime/observatory/tests/observatory_ui/class_tree/element_test.dart
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:html';
-import 'package:test/test.dart';
-import 'package:observatory/src/elements/class_tree.dart';
-import 'package:observatory/src/elements/nav/notify.dart';
-import '../mocks.dart';
-
-main() {
-  ClassTreeElement.tag.ensureRegistration();
-
-  final nTag = NavNotifyElement.tag.name;
-  const vm = const VMMock();
-  const isolate = const IsolateRefMock();
-  final events = new EventRepositoryMock();
-  final notifications = new NotificationRepositoryMock();
-
-  group('instantiation', () {
-    test('default', () {
-      final e = new ClassTreeElement(
-          vm, isolate, events, notifications, new ClassRepositoryMock());
-      expect(e, isNotNull, reason: 'element correctly created');
-    });
-  });
-  group('elements', () {
-    test('created after attachment', () async {
-      const child2_id = 'c2-id';
-      const child1_1_id = 'c1_1-id';
-      const child1_id = 'c1-id';
-      const child2 = const ClassMock(id: child2_id);
-      const child1_1 = const ClassMock(id: child1_1_id);
-      const child1 =
-          const ClassMock(id: child1_id, subclasses: const [child1_1]);
-      const object =
-          const ClassMock(id: 'o-id', subclasses: const [child1, child2]);
-      const ids = const [child1_id, child1_1_id, child2_id];
-      bool rendered = false;
-      final e = new ClassTreeElement(
-          vm,
-          isolate,
-          events,
-          notifications,
-          new ClassRepositoryMock(
-              object: expectAsync1((i) async {
-                expect(i, equals(isolate));
-                expect(rendered, isFalse);
-                return object;
-              }, count: 1),
-              getter: expectAsync2((i, id) async {
-                expect(i, equals(isolate));
-                expect(ids.contains(id), isTrue);
-                switch (id) {
-                  case child1_id:
-                    return child1;
-                  case child1_1_id:
-                    return child1_1;
-                  case child2_id:
-                    return child2;
-                  default:
-                    return null;
-                }
-              }, count: 3)));
-      document.body.append(e);
-      await e.onRendered.first;
-      rendered = true;
-      expect(e.children.length, isNonZero, reason: 'has elements');
-      expect(e.querySelectorAll(nTag).length, equals(1));
-      e.remove();
-      await e.onRendered.first;
-      expect(e.children.length, isZero, reason: 'is empty');
-    });
-  });
-}
diff --git a/runtime/observatory/tests/observatory_ui/class_tree/element_test.html b/runtime/observatory/tests/observatory_ui/class_tree/element_test.html
deleted file mode 100644
index bc26958..0000000
--- a/runtime/observatory/tests/observatory_ui/class_tree/element_test.html
+++ /dev/null
@@ -1,24 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-  <meta http-equiv="X-UA-Compatible" content="IE=edge">
-  <meta name="dart.unittest" content="full-stack-traces">
-  <style>
-     .unittest-table { font-family:monospace; border:1px; }
-     .unittest-pass { background: #6b3;}
-     .unittest-fail { background: #d55;}
-     .unittest-error { background: #a11;}
-     class-tree virtual-tree .class-tree-item {
-       line-height: 25px;
-       height: 25px;
-       padding-left: 10%;
-       padding-right: 10%;
-     }
-  </style>
-</head>
-<body>
-  <script type="text/javascript"
-      src="/root_dart/tools/testing/dart/test_controller.js"></script>
-  %TEST_SCRIPTS%
-</body>
-</html>
diff --git a/runtime/observatory/tests/observatory_ui/code_ref/element_test.dart b/runtime/observatory/tests/observatory_ui/code_ref/element_test.dart
deleted file mode 100644
index 4f9e229..0000000
--- a/runtime/observatory/tests/observatory_ui/code_ref/element_test.dart
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:html';
-import 'package:test/test.dart';
-import 'package:observatory/src/elements/code_ref.dart';
-import '../mocks.dart';
-
-main() {
-  CodeRefElement.tag.ensureRegistration();
-
-  final isolate = new IsolateRefMock(id: 'i-id', name: 'i-name');
-  final code = new CodeRefMock(id: 'c-id', name: 'c-name');
-  test('instantiation', () {
-    final e = new CodeRefElement(isolate, code);
-    expect(e, isNotNull, reason: 'element correctly created');
-    expect(e.isolate, equals(isolate));
-    expect(e.code, equals(code));
-  });
-  test('elements created after attachment', () async {
-    final e = new CodeRefElement(isolate, code);
-    document.body.append(e);
-    await e.onRendered.first;
-    expect(e.children.length, isNonZero, reason: 'has elements');
-    e.remove();
-    await e.onRendered.first;
-    expect(e.children.length, isZero, reason: 'is empty');
-  });
-}
diff --git a/runtime/observatory/tests/observatory_ui/code_ref/element_test.html b/runtime/observatory/tests/observatory_ui/code_ref/element_test.html
deleted file mode 100644
index f548be4..0000000
--- a/runtime/observatory/tests/observatory_ui/code_ref/element_test.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-  <meta http-equiv="X-UA-Compatible" content="IE=edge">
-  <meta name="dart.unittest" content="full-stack-traces">
-  <style>
-     .unittest-table { font-family:monospace; border:1px; }
-     .unittest-pass { background: #6b3;}
-     .unittest-fail { background: #d55;}
-     .unittest-error { background: #a11;}
-  </style>
-</head>
-<body>
-  <script type="text/javascript"
-      src="/root_dart/tools/testing/dart/test_controller.js"></script>
-  %TEST_SCRIPTS%
-</body>
-</html>
diff --git a/runtime/observatory/tests/observatory_ui/context_ref/element_test.dart b/runtime/observatory/tests/observatory_ui/context_ref/element_test.dart
deleted file mode 100644
index 857f99b..0000000
--- a/runtime/observatory/tests/observatory_ui/context_ref/element_test.dart
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:html';
-import 'package:test/test.dart';
-import 'package:observatory/src/elements/context_ref.dart';
-import '../mocks.dart';
-
-main() {
-  ContextRefElement.tag.ensureRegistration();
-
-  const isolate = const IsolateRefMock();
-  const context = const ContextRefMock();
-  final objects = new ObjectRepositoryMock();
-
-  test('instantiation', () {
-    final e = new ContextRefElement(isolate, context, objects);
-    expect(e, isNotNull, reason: 'element correctly created');
-    expect(e.isolate, equals(isolate));
-    expect(e.context, equals(context));
-  });
-  test('elements created after attachment', () async {
-    final e = new ContextRefElement(isolate, context, objects);
-    document.body.append(e);
-    await e.onRendered.first;
-    expect(e.children.length, isNonZero, reason: 'has elements');
-    e.remove();
-    await e.onRendered.first;
-    expect(e.children.length, isZero, reason: 'is empty');
-  });
-}
diff --git a/runtime/observatory/tests/observatory_ui/context_ref/element_test.html b/runtime/observatory/tests/observatory_ui/context_ref/element_test.html
deleted file mode 100644
index f548be4..0000000
--- a/runtime/observatory/tests/observatory_ui/context_ref/element_test.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-  <meta http-equiv="X-UA-Compatible" content="IE=edge">
-  <meta name="dart.unittest" content="full-stack-traces">
-  <style>
-     .unittest-table { font-family:monospace; border:1px; }
-     .unittest-pass { background: #6b3;}
-     .unittest-fail { background: #d55;}
-     .unittest-error { background: #a11;}
-  </style>
-</head>
-<body>
-  <script type="text/javascript"
-      src="/root_dart/tools/testing/dart/test_controller.js"></script>
-  %TEST_SCRIPTS%
-</body>
-</html>
diff --git a/runtime/observatory/tests/observatory_ui/context_view/element_test.dart b/runtime/observatory/tests/observatory_ui/context_view/element_test.dart
deleted file mode 100644
index f2552d3..0000000
--- a/runtime/observatory/tests/observatory_ui/context_view/element_test.dart
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:html';
-import 'package:test/test.dart';
-import 'package:observatory/src/elements/context_view.dart';
-import 'package:observatory/src/elements/nav/refresh.dart';
-import 'package:observatory/src/elements/object_common.dart';
-import '../mocks.dart';
-
-main() {
-  ContextViewElement.tag.ensureRegistration();
-
-  final cTag = ObjectCommonElement.tag.name;
-  final rTag = NavRefreshElement.tag.name;
-
-  const vm = const VMMock();
-  const isolate = const IsolateRefMock();
-  final events = new EventRepositoryMock();
-  final notifs = new NotificationRepositoryMock();
-  final context = const ContextMock();
-  final contexts = new ContextRepositoryMock();
-  final reachableSizes = new ReachableSizeRepositoryMock();
-  final retainedSizes = new RetainedSizeRepositoryMock();
-  final inbounds = new InboundReferencesRepositoryMock();
-  final paths = new RetainingPathRepositoryMock();
-  final objects = new ObjectRepositoryMock();
-  test('instantiation', () {
-    final e = new ContextViewElement(vm, isolate, context, events, notifs,
-        contexts, retainedSizes, reachableSizes, inbounds, paths, objects);
-    expect(e, isNotNull, reason: 'element correctly created');
-    expect(e.isolate, equals(isolate));
-    expect(e.context, equals(context));
-  });
-  test('elements created after attachment', () async {
-    final contexts = new ContextRepositoryMock(
-        getter: expectAsync2((i, id) async {
-      expect(i, equals(isolate));
-      expect(id, equals(context.id));
-      return context;
-    }, count: 1));
-    final e = new ContextViewElement(vm, isolate, context, events, notifs,
-        contexts, retainedSizes, reachableSizes, inbounds, paths, objects);
-    document.body.append(e);
-    await e.onRendered.first;
-    expect(e.children.length, isNonZero, reason: 'has elements');
-    expect(e.querySelectorAll(cTag).length, equals(1));
-    (e.querySelector(rTag) as NavRefreshElement).refresh();
-    await e.onRendered.first;
-    e.remove();
-    await e.onRendered.first;
-    expect(e.children.length, isZero, reason: 'is empty');
-  });
-}
diff --git a/runtime/observatory/tests/observatory_ui/context_view/element_test.html b/runtime/observatory/tests/observatory_ui/context_view/element_test.html
deleted file mode 100644
index f548be4..0000000
--- a/runtime/observatory/tests/observatory_ui/context_view/element_test.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-  <meta http-equiv="X-UA-Compatible" content="IE=edge">
-  <meta name="dart.unittest" content="full-stack-traces">
-  <style>
-     .unittest-table { font-family:monospace; border:1px; }
-     .unittest-pass { background: #6b3;}
-     .unittest-fail { background: #d55;}
-     .unittest-error { background: #a11;}
-  </style>
-</head>
-<body>
-  <script type="text/javascript"
-      src="/root_dart/tools/testing/dart/test_controller.js"></script>
-  %TEST_SCRIPTS%
-</body>
-</html>
diff --git a/runtime/observatory/tests/observatory_ui/cpu_profile/element_test.dart b/runtime/observatory/tests/observatory_ui/cpu_profile/element_test.dart
deleted file mode 100644
index a596684..0000000
--- a/runtime/observatory/tests/observatory_ui/cpu_profile/element_test.dart
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:html';
-import 'dart:async';
-import 'package:test/test.dart';
-import 'package:observatory/models.dart' as M;
-import 'package:observatory/src/elements/cpu_profile.dart';
-import 'package:observatory/src/elements/cpu_profile/virtual_tree.dart';
-import 'package:observatory/src/elements/stack_trace_tree_config.dart';
-import 'package:observatory/src/elements/sample_buffer_control.dart';
-import '../mocks.dart';
-
-main() {
-  CpuProfileElement.tag.ensureRegistration();
-
-  final sTag = SampleBufferControlElement.tag.name;
-  final cTag = StackTraceTreeConfigElement.tag.name;
-  final tTag = CpuProfileVirtualTreeElement.tag.name;
-
-  const vm = const VMMock();
-  const isolate = const IsolateRefMock();
-  final events = new EventRepositoryMock();
-  final notifs = new NotificationRepositoryMock();
-  test('instantiation', () {
-    final profiles = new IsolateSampleProfileRepositoryMock();
-    final e = new CpuProfileElement(vm, isolate, events, notifs, profiles);
-    expect(e, isNotNull, reason: 'element correctly created');
-  });
-  test('elements created', () async {
-    final controller =
-        new StreamController<M.SampleProfileLoadingProgressEvent>.broadcast();
-    final profiles = new IsolateSampleProfileRepositoryMock(getter:
-        (M.IsolateRef i, M.SampleProfileTag t, bool clear, bool forceFetch) {
-      expect(i, equals(isolate));
-      expect(t, isNotNull);
-      expect(clear, isFalse);
-      expect(forceFetch, isFalse);
-      return controller.stream;
-    });
-    final e = new CpuProfileElement(vm, isolate, events, notifs, profiles);
-    document.body.append(e);
-    await e.onRendered.first;
-    expect(e.children.length, isNonZero, reason: 'has elements');
-    expect(e.querySelectorAll(sTag).length, isZero);
-    expect(e.querySelectorAll(cTag).length, isZero);
-    expect(e.querySelectorAll(tTag).length, isZero);
-    controller.add(new SampleProfileLoadingProgressEventMock(
-        progress: new SampleProfileLoadingProgressMock(
-            status: M.SampleProfileLoadingStatus.fetching)));
-    await e.onRendered.first;
-    expect(e.querySelectorAll(sTag).length, equals(1));
-    expect(e.querySelectorAll(cTag).length, isZero);
-    expect(e.querySelectorAll(tTag).length, isZero);
-    controller.add(new SampleProfileLoadingProgressEventMock(
-        progress: new SampleProfileLoadingProgressMock(
-            status: M.SampleProfileLoadingStatus.loading)));
-    controller.add(new SampleProfileLoadingProgressEventMock(
-        progress: new SampleProfileLoadingProgressMock(
-            status: M.SampleProfileLoadingStatus.loaded,
-            profile: new SampleProfileMock())));
-    controller.close();
-    await e.onRendered.first;
-    expect(e.querySelectorAll(sTag).length, equals(1));
-    expect(e.querySelectorAll(cTag).length, equals(1));
-    expect(e.querySelectorAll(tTag).length, equals(1));
-    e.remove();
-    await e.onRendered.first;
-    expect(e.children.length, isZero, reason: 'is empty');
-  });
-}
diff --git a/runtime/observatory/tests/observatory_ui/cpu_profile/element_test.html b/runtime/observatory/tests/observatory_ui/cpu_profile/element_test.html
deleted file mode 100644
index f548be4..0000000
--- a/runtime/observatory/tests/observatory_ui/cpu_profile/element_test.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-  <meta http-equiv="X-UA-Compatible" content="IE=edge">
-  <meta name="dart.unittest" content="full-stack-traces">
-  <style>
-     .unittest-table { font-family:monospace; border:1px; }
-     .unittest-pass { background: #6b3;}
-     .unittest-fail { background: #d55;}
-     .unittest-error { background: #a11;}
-  </style>
-</head>
-<body>
-  <script type="text/javascript"
-      src="/root_dart/tools/testing/dart/test_controller.js"></script>
-  %TEST_SCRIPTS%
-</body>
-</html>
diff --git a/runtime/observatory/tests/observatory_ui/cpu_profile/virtual-tree/element_test.dart b/runtime/observatory/tests/observatory_ui/cpu_profile/virtual-tree/element_test.dart
deleted file mode 100644
index 1f15445..0000000
--- a/runtime/observatory/tests/observatory_ui/cpu_profile/virtual-tree/element_test.dart
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:html';
-import 'package:test/test.dart';
-import 'package:observatory/models.dart' as M;
-import 'package:observatory/src/elements/cpu_profile/virtual_tree.dart';
-import '../../mocks.dart';
-
-main() {
-  CpuProfileVirtualTreeElement.tag.ensureRegistration();
-  const isolate = const IsolateRefMock();
-  group('instantiation', () {
-    final profile = new SampleProfileMock();
-    test('default', () {
-      final e = new CpuProfileVirtualTreeElement(isolate, profile);
-      expect(e, isNotNull, reason: 'element correctly created');
-      expect(e.isolate, equals(isolate));
-      expect(e.profile, equals(profile));
-      expect(e.mode, equals(ProfileTreeMode.function));
-      expect(e.direction, equals(M.ProfileTreeDirection.exclusive));
-    });
-    test('mode', () {
-      final e = new CpuProfileVirtualTreeElement(isolate, profile,
-          mode: ProfileTreeMode.code);
-      expect(e, isNotNull, reason: 'element correctly created');
-      expect(e.isolate, equals(isolate));
-      expect(e.profile, equals(profile));
-      expect(e.mode, equals(ProfileTreeMode.code));
-      expect(e.direction, equals(M.ProfileTreeDirection.exclusive));
-    });
-    test('direction', () {
-      final e = new CpuProfileVirtualTreeElement(isolate, profile,
-          direction: M.ProfileTreeDirection.inclusive);
-      expect(e, isNotNull, reason: 'element correctly created');
-      expect(e.isolate, equals(isolate));
-      expect(e.profile, equals(profile));
-      expect(e.mode, equals(ProfileTreeMode.function));
-      expect(e.direction, equals(M.ProfileTreeDirection.inclusive));
-    });
-  });
-  test('elements created after attachment', () async {
-    final profile = new SampleProfileMock();
-    final e = new CpuProfileVirtualTreeElement(isolate, profile);
-    document.body.append(e);
-    await e.onRendered.first;
-    expect(e.children.length, isNonZero, reason: 'has elements');
-    e.remove();
-    await e.onRendered.first;
-    expect(e.children.length, isZero, reason: 'is empty');
-  });
-}
diff --git a/runtime/observatory/tests/observatory_ui/cpu_profile/virtual-tree/element_test.html b/runtime/observatory/tests/observatory_ui/cpu_profile/virtual-tree/element_test.html
deleted file mode 100644
index f548be4..0000000
--- a/runtime/observatory/tests/observatory_ui/cpu_profile/virtual-tree/element_test.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-  <meta http-equiv="X-UA-Compatible" content="IE=edge">
-  <meta name="dart.unittest" content="full-stack-traces">
-  <style>
-     .unittest-table { font-family:monospace; border:1px; }
-     .unittest-pass { background: #6b3;}
-     .unittest-fail { background: #d55;}
-     .unittest-error { background: #a11;}
-  </style>
-</head>
-<body>
-  <script type="text/javascript"
-      src="/root_dart/tools/testing/dart/test_controller.js"></script>
-  %TEST_SCRIPTS%
-</body>
-</html>
diff --git a/runtime/observatory/tests/observatory_ui/cpu_profile_table/element_test.dart b/runtime/observatory/tests/observatory_ui/cpu_profile_table/element_test.dart
deleted file mode 100644
index 9857f12..0000000
--- a/runtime/observatory/tests/observatory_ui/cpu_profile_table/element_test.dart
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:html';
-import 'dart:async';
-import 'package:test/test.dart';
-import 'package:observatory/models.dart' as M;
-import 'package:observatory/src/elements/cpu_profile_table.dart';
-import 'package:observatory/src/elements/cpu_profile/virtual_tree.dart';
-import 'package:observatory/src/elements/stack_trace_tree_config.dart';
-import 'package:observatory/src/elements/sample_buffer_control.dart';
-import '../mocks.dart';
-
-main() {
-  CpuProfileTableElement.tag.ensureRegistration();
-
-  final sTag = SampleBufferControlElement.tag.name;
-  final cTag = StackTraceTreeConfigElement.tag.name;
-  final tTag = CpuProfileVirtualTreeElement.tag.name;
-
-  const vm = const VMMock();
-  const isolate = const IsolateRefMock();
-  final events = new EventRepositoryMock();
-  final notifs = new NotificationRepositoryMock();
-  test('instantiation', () {
-    final profiles = new IsolateSampleProfileRepositoryMock();
-    final e = new CpuProfileTableElement(vm, isolate, events, notifs, profiles);
-    expect(e, isNotNull, reason: 'element correctly created');
-  });
-  test('elements created', () async {
-    final controller =
-        new StreamController<M.SampleProfileLoadingProgressEvent>.broadcast();
-    final profiles = new IsolateSampleProfileRepositoryMock(getter:
-        (M.IsolateRef i, M.SampleProfileTag t, bool clear, bool forceFetch) {
-      expect(i, equals(isolate));
-      expect(t, isNotNull);
-      expect(clear, isFalse);
-      expect(forceFetch, isFalse);
-      return controller.stream;
-    });
-    final e = new CpuProfileTableElement(vm, isolate, events, notifs, profiles);
-    document.body.append(e);
-    await e.onRendered.first;
-    expect(e.children.length, isNonZero, reason: 'has elements');
-    expect(e.querySelectorAll(sTag).length, isZero);
-    expect(e.querySelectorAll(cTag).length, isZero);
-    expect(e.querySelectorAll(tTag).length, isZero);
-    controller.add(new SampleProfileLoadingProgressEventMock(
-        progress: new SampleProfileLoadingProgressMock(
-            status: M.SampleProfileLoadingStatus.fetching)));
-    await e.onRendered.first;
-    expect(e.querySelectorAll(sTag).length, equals(1));
-    expect(e.querySelectorAll(cTag).length, isZero);
-    expect(e.querySelectorAll(tTag).length, isZero);
-    controller.add(new SampleProfileLoadingProgressEventMock(
-        progress: new SampleProfileLoadingProgressMock(
-            status: M.SampleProfileLoadingStatus.loading)));
-    controller.add(new SampleProfileLoadingProgressEventMock(
-        progress: new SampleProfileLoadingProgressMock(
-            status: M.SampleProfileLoadingStatus.loaded,
-            profile: new SampleProfileMock())));
-    controller.close();
-    await e.onRendered.first;
-    expect(e.querySelectorAll(sTag).length, equals(1));
-    expect(e.querySelectorAll(cTag).length, equals(1));
-    expect(e.querySelectorAll(tTag).length, equals(1));
-    e.remove();
-    await e.onRendered.first;
-    expect(e.children.length, isZero, reason: 'is empty');
-  });
-}
diff --git a/runtime/observatory/tests/observatory_ui/cpu_profile_table/element_test.html b/runtime/observatory/tests/observatory_ui/cpu_profile_table/element_test.html
deleted file mode 100644
index f548be4..0000000
--- a/runtime/observatory/tests/observatory_ui/cpu_profile_table/element_test.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-  <meta http-equiv="X-UA-Compatible" content="IE=edge">
-  <meta name="dart.unittest" content="full-stack-traces">
-  <style>
-     .unittest-table { font-family:monospace; border:1px; }
-     .unittest-pass { background: #6b3;}
-     .unittest-fail { background: #d55;}
-     .unittest-error { background: #a11;}
-  </style>
-</head>
-<body>
-  <script type="text/javascript"
-      src="/root_dart/tools/testing/dart/test_controller.js"></script>
-  %TEST_SCRIPTS%
-</body>
-</html>
diff --git a/runtime/observatory/tests/observatory_ui/curly_block/element_test.dart b/runtime/observatory/tests/observatory_ui/curly_block/element_test.dart
deleted file mode 100644
index e647e5f..0000000
--- a/runtime/observatory/tests/observatory_ui/curly_block/element_test.dart
+++ /dev/null
@@ -1,176 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:html';
-import 'package:test/test.dart';
-import 'package:observatory/src/elements/curly_block.dart';
-
-main() {
-  CurlyBlockElement.tag.ensureRegistration();
-
-  group('instantiation', () {
-    test('default', () {
-      final e = new CurlyBlockElement();
-      expect(e, isNotNull, reason: 'element correctly created');
-      expect(e.expanded, isFalse);
-      expect(e.disabled, isFalse);
-    });
-    test('not expanded', () {
-      final e = new CurlyBlockElement(expanded: false);
-      expect(e, isNotNull, reason: 'element correctly created');
-      expect(e.expanded, isFalse);
-      expect(e.disabled, isFalse);
-    });
-    test('not expanded / not disabled', () {
-      final e = new CurlyBlockElement(expanded: false, disabled: false);
-      expect(e, isNotNull, reason: 'element correctly created');
-      expect(e.expanded, isFalse);
-      expect(e.disabled, isFalse);
-    });
-    test('not expanded / disabled', () {
-      final e = new CurlyBlockElement(expanded: false, disabled: true);
-      expect(e, isNotNull, reason: 'element correctly created');
-      expect(e.expanded, isFalse);
-      expect(e.disabled, isTrue);
-    });
-    test('expanded', () {
-      final e = new CurlyBlockElement(expanded: true);
-      expect(e, isNotNull, reason: 'element correctly created');
-      expect(e.expanded, isTrue);
-      expect(e.disabled, isFalse);
-    });
-    test('expanded / not disabled', () {
-      final e = new CurlyBlockElement(expanded: true, disabled: false);
-      expect(e, isNotNull, reason: 'element correctly created');
-      expect(e.expanded, isTrue);
-      expect(e.disabled, isFalse);
-    });
-    test('expanded / disabled', () {
-      final e = new CurlyBlockElement(expanded: true, disabled: true);
-      expect(e, isNotNull, reason: 'element correctly created');
-      expect(e.expanded, isTrue);
-      expect(e.disabled, isTrue);
-    });
-    test('not disabled', () {
-      final e = new CurlyBlockElement(disabled: false);
-      expect(e, isNotNull, reason: 'element correctly created');
-      expect(e.expanded, isFalse);
-      expect(e.disabled, isFalse);
-    });
-    test('disabled', () {
-      final e = new CurlyBlockElement(disabled: true);
-      expect(e, isNotNull, reason: 'element correctly created');
-      expect(e.expanded, isFalse);
-      expect(e.disabled, isTrue);
-    });
-  });
-  test('elements created', () async {
-    final e = new CurlyBlockElement();
-    expect(e.children, isEmpty, reason: 'is empty');
-    document.body.append(e);
-    await e.onRendered.first;
-    expect(e.children, isNotEmpty, reason: 'has elements');
-    e.remove();
-    await e.onRendered.first;
-    expect(e.children, isEmpty, reason: 'is empty');
-  });
-  group('content', () {
-    CurlyBlockElement e;
-    setUp(() async {
-      e = new CurlyBlockElement();
-      e.content = <Element>[document.createElement('content')];
-      document.body.append(e);
-      await e.onRendered.first;
-    });
-    tearDown(() {
-      e.remove();
-    });
-    test('toggles visibility', () async {
-      expect(e.querySelector('content'), isNull);
-      e.toggle();
-      await e.onRendered.first;
-      expect(e.querySelector('content'), isNotNull);
-      e.toggle();
-      await e.onRendered.first;
-      expect(e.querySelector('content'), isNull);
-      e.remove();
-    });
-    test('toggles visibility (manually)', () async {
-      expect(e.querySelector('content'), isNull);
-      e.expanded = true;
-      await e.onRendered.first;
-      expect(e.querySelector('content'), isNotNull);
-      e.expanded = false;
-      await e.onRendered.first;
-      expect(e.querySelector('content'), isNull);
-      e.remove();
-    });
-    test('does not toggle if disabled', () async {
-      e.disabled = true;
-      await e.onRendered.first;
-      expect(e.expanded, isFalse);
-      expect(e.querySelector('content'), isNull);
-      e.toggle();
-      await e.onRendered.first;
-      expect(e.expanded, isFalse);
-      expect(e.querySelector('content'), isNull);
-      e.disabled = false;
-      e.toggle();
-      await e.onRendered.first;
-      expect(e.expanded, isTrue);
-      expect(e.querySelector('content'), isNotNull);
-      e.disabled = true;
-      e.toggle();
-      await e.onRendered.first;
-      expect(e.expanded, isTrue);
-      expect(e.querySelector('content'), isNotNull);
-      e.remove();
-    });
-    test('toggles visibility (manually) if disabled', () async {
-      e.disabled = true;
-      await e.onRendered.first;
-      expect(e.querySelector('content'), isNull);
-      e.expanded = true;
-      await e.onRendered.first;
-      expect(e.querySelector('content'), isNotNull);
-      e.expanded = false;
-      await e.onRendered.first;
-      expect(e.querySelector('content'), isNull);
-      e.remove();
-    });
-  });
-  group('event', () {
-    CurlyBlockElement e;
-    setUp(() async {
-      e = new CurlyBlockElement();
-      document.body.append(e);
-      await e.onRendered.first;
-    });
-    tearDown(() async {
-      e.remove();
-      await e.onRendered.first;
-    });
-    test('fires on toggle', () async {
-      e.onToggle.listen(expectAsync1((CurlyBlockToggleEvent event) {
-        expect(event, isNotNull);
-        expect(event.control, equals(e));
-      }, count: 1));
-      e.toggle();
-      await e.onRendered.first;
-    });
-    test('fires on manual toggle', () async {
-      e.onToggle.listen(expectAsync1((CurlyBlockToggleEvent event) {
-        expect(event, isNotNull);
-        expect(event.control, equals(e));
-      }, count: 1));
-      e.expanded = !e.expanded;
-      await e.onRendered.first;
-    });
-    test('does not fire if setting same expanded value', () async {
-      e.onToggle.listen(expectAsync1((_) {}, count: 0));
-      e.expanded = e.expanded;
-      await e.onRendered.first;
-    });
-  });
-}
diff --git a/runtime/observatory/tests/observatory_ui/curly_block/element_test.html b/runtime/observatory/tests/observatory_ui/curly_block/element_test.html
deleted file mode 100644
index f548be4..0000000
--- a/runtime/observatory/tests/observatory_ui/curly_block/element_test.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-  <meta http-equiv="X-UA-Compatible" content="IE=edge">
-  <meta name="dart.unittest" content="full-stack-traces">
-  <style>
-     .unittest-table { font-family:monospace; border:1px; }
-     .unittest-pass { background: #6b3;}
-     .unittest-fail { background: #d55;}
-     .unittest-error { background: #a11;}
-  </style>
-</head>
-<body>
-  <script type="text/javascript"
-      src="/root_dart/tools/testing/dart/test_controller.js"></script>
-  %TEST_SCRIPTS%
-</body>
-</html>
diff --git a/runtime/observatory/tests/observatory_ui/error_ref/element_test.dart b/runtime/observatory/tests/observatory_ui/error_ref/element_test.dart
deleted file mode 100644
index 867b5f2..0000000
--- a/runtime/observatory/tests/observatory_ui/error_ref/element_test.dart
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:html';
-import 'package:test/test.dart';
-import 'package:observatory/src/elements/error_ref.dart';
-import '../mocks.dart';
-
-main() {
-  ErrorRefElement.tag.ensureRegistration();
-
-  final ref = new ErrorRefMock(id: 'id', message: 'fixed-error-m');
-  test('instantiation', () {
-    final ErrorRefElement e = new ErrorRefElement(ref);
-    expect(e, isNotNull, reason: 'element correctly created');
-    expect(e.error, equals(ref));
-  });
-  test('elements created after attachment', () async {
-    final ErrorRefElement e = new ErrorRefElement(ref);
-    document.body.append(e);
-    await e.onRendered.first;
-    expect(e.children.length, isNonZero, reason: 'has elements');
-    expect(e.innerHtml.contains(ref.message), isTrue,
-        reason: 'no message in the component');
-    e.remove();
-    await e.onRendered.first;
-    expect(e.children.length, isZero, reason: 'is empty');
-  });
-}
diff --git a/runtime/observatory/tests/observatory_ui/error_ref/element_test.html b/runtime/observatory/tests/observatory_ui/error_ref/element_test.html
deleted file mode 100644
index f548be4..0000000
--- a/runtime/observatory/tests/observatory_ui/error_ref/element_test.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-  <meta http-equiv="X-UA-Compatible" content="IE=edge">
-  <meta name="dart.unittest" content="full-stack-traces">
-  <style>
-     .unittest-table { font-family:monospace; border:1px; }
-     .unittest-pass { background: #6b3;}
-     .unittest-fail { background: #d55;}
-     .unittest-error { background: #a11;}
-  </style>
-</head>
-<body>
-  <script type="text/javascript"
-      src="/root_dart/tools/testing/dart/test_controller.js"></script>
-  %TEST_SCRIPTS%
-</body>
-</html>
diff --git a/runtime/observatory/tests/observatory_ui/error_view/element_test.dart b/runtime/observatory/tests/observatory_ui/error_view/element_test.dart
deleted file mode 100644
index e69fec7..0000000
--- a/runtime/observatory/tests/observatory_ui/error_view/element_test.dart
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:html';
-import 'package:test/test.dart';
-import 'package:observatory/src/elements/error_view.dart';
-import '../mocks.dart';
-
-main() {
-  ErrorViewElement.tag.ensureRegistration();
-
-  final notifs = new NotificationRepositoryMock();
-  final error = const ErrorMock();
-  test('instantiation', () {
-    final e = new ErrorViewElement(notifs, error);
-    expect(e, isNotNull, reason: 'element correctly created');
-    expect(e.error, equals(error));
-  });
-  test('elements created after attachment', () async {
-    final e = new ErrorViewElement(notifs, error);
-    document.body.append(e);
-    await e.onRendered.first;
-    expect(e.children.length, isNonZero, reason: 'has elements');
-    e.remove();
-    await e.onRendered.first;
-    expect(e.children.length, isZero, reason: 'is empty');
-  });
-}
diff --git a/runtime/observatory/tests/observatory_ui/error_view/element_test.html b/runtime/observatory/tests/observatory_ui/error_view/element_test.html
deleted file mode 100644
index f548be4..0000000
--- a/runtime/observatory/tests/observatory_ui/error_view/element_test.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-  <meta http-equiv="X-UA-Compatible" content="IE=edge">
-  <meta name="dart.unittest" content="full-stack-traces">
-  <style>
-     .unittest-table { font-family:monospace; border:1px; }
-     .unittest-pass { background: #6b3;}
-     .unittest-fail { background: #d55;}
-     .unittest-error { background: #a11;}
-  </style>
-</head>
-<body>
-  <script type="text/javascript"
-      src="/root_dart/tools/testing/dart/test_controller.js"></script>
-  %TEST_SCRIPTS%
-</body>
-</html>
diff --git a/runtime/observatory/tests/observatory_ui/field_ref/element_test.dart b/runtime/observatory/tests/observatory_ui/field_ref/element_test.dart
deleted file mode 100644
index 75df874..0000000
--- a/runtime/observatory/tests/observatory_ui/field_ref/element_test.dart
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:html';
-import 'package:test/test.dart';
-import 'package:observatory/models.dart' as M;
-import 'package:observatory/src/elements/field_ref.dart';
-import 'package:observatory/src/elements/instance_ref.dart';
-import '../mocks.dart';
-
-main() {
-  FieldRefElement.tag.ensureRegistration();
-
-  final iTag = InstanceRefElement.tag.name;
-
-  const isolate = const IsolateRefMock();
-  const field = const FieldRefMock();
-  const declaredType =
-      const InstanceMock(kind: M.InstanceKind.type, name: 'CustomObject');
-  const field_non_dynamic = const FieldRefMock(declaredType: declaredType);
-  final objects = new ObjectRepositoryMock();
-  test('instantiation', () {
-    final e = new FieldRefElement(isolate, field, objects);
-    expect(e, isNotNull, reason: 'element correctly created');
-    expect(e.isolate, equals(isolate));
-    expect(e.field, equals(field));
-  });
-  group('elements', () {
-    test('created after attachment (dynamic)', () async {
-      final e = new FieldRefElement(isolate, field, objects);
-      document.body.append(e);
-      await e.onRendered.first;
-      expect(e.children.length, isNonZero, reason: 'has elements');
-      expect(e.querySelectorAll(iTag).length, isZero);
-      e.remove();
-      await e.onRendered.first;
-      expect(e.children.length, isZero, reason: 'is empty');
-    });
-    test('created after attachment (non dynamic)', () async {
-      final e = new FieldRefElement(isolate, field_non_dynamic, objects);
-      document.body.append(e);
-      await e.onRendered.first;
-      expect(e.children.length, isNonZero, reason: 'has elements');
-      expect(e.querySelectorAll(iTag).length, equals(1));
-      e.remove();
-      await e.onRendered.first;
-      expect(e.children.length, isZero, reason: 'is empty');
-    });
-  });
-}
diff --git a/runtime/observatory/tests/observatory_ui/field_ref/element_test.html b/runtime/observatory/tests/observatory_ui/field_ref/element_test.html
deleted file mode 100644
index f548be4..0000000
--- a/runtime/observatory/tests/observatory_ui/field_ref/element_test.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-  <meta http-equiv="X-UA-Compatible" content="IE=edge">
-  <meta name="dart.unittest" content="full-stack-traces">
-  <style>
-     .unittest-table { font-family:monospace; border:1px; }
-     .unittest-pass { background: #6b3;}
-     .unittest-fail { background: #d55;}
-     .unittest-error { background: #a11;}
-  </style>
-</head>
-<body>
-  <script type="text/javascript"
-      src="/root_dart/tools/testing/dart/test_controller.js"></script>
-  %TEST_SCRIPTS%
-</body>
-</html>
diff --git a/runtime/observatory/tests/observatory_ui/flag_list/element_test.dart b/runtime/observatory/tests/observatory_ui/flag_list/element_test.dart
deleted file mode 100644
index 023f08a..0000000
--- a/runtime/observatory/tests/observatory_ui/flag_list/element_test.dart
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:html';
-import 'package:observatory/models.dart' as M;
-import 'package:test/test.dart';
-import 'package:observatory/src/elements/flag_list.dart';
-import 'package:observatory/src/elements/nav/notify.dart';
-import '../mocks.dart';
-
-main() {
-  FlagListElement.tag.ensureRegistration();
-
-  final nTag = NavNotifyElement.tag.name;
-  const vm = const VMMock();
-  final events = new EventRepositoryMock();
-  final notifications = new NotificationRepositoryMock();
-
-  group('instantiation', () {
-    test('default', () {
-      final e = new FlagListElement(
-          vm, events, new FlagsRepositoryMock(), notifications);
-      expect(e, isNotNull, reason: 'element correctly created');
-    });
-  });
-  group('elements', () {
-    test('created after attachment', () async {
-      const modified = const [
-        const FlagMock(name: 'f1', comment: 'c1', modified: true),
-      ];
-      const unmodifed = const [
-        const FlagMock(name: 'f2', comment: 'c2', modified: false),
-        const FlagMock(name: 'f3', comment: 'c3', modified: false),
-      ];
-      final flags = <M.Flag>[]..addAll(modified)..addAll(unmodifed);
-      final repository = new FlagsRepositoryMock(list: flags);
-      final e = new FlagListElement(vm, events, repository, notifications);
-      document.body.append(e);
-      expect(repository.isListInvoked, isFalse);
-      await e.onRendered.first;
-      expect(repository.isListInvoked, isTrue);
-      expect(e.children.length, isNonZero, reason: 'has elements');
-      expect(e.querySelectorAll(nTag).length, equals(1));
-      expect(e.querySelectorAll('.flag').length, equals(flags.length));
-      expect(
-          e.querySelectorAll('.flag.modified').length, equals(modified.length));
-      expect(e.querySelectorAll('.flag.unmodified').length,
-          equals(unmodifed.length));
-      expect(e.querySelectorAll('.flag').length, equals(flags.length));
-      expect(e.querySelectorAll('.comment').length, equals(flags.length));
-      expect(e.querySelectorAll('.name').length, equals(flags.length));
-      expect(e.querySelectorAll('.value').length, equals(flags.length));
-      e.remove();
-      await e.onRendered.first;
-      expect(e.children.length, isZero, reason: 'is empty');
-    });
-  });
-}
diff --git a/runtime/observatory/tests/observatory_ui/flag_list/element_test.html b/runtime/observatory/tests/observatory_ui/flag_list/element_test.html
deleted file mode 100644
index f548be4..0000000
--- a/runtime/observatory/tests/observatory_ui/flag_list/element_test.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-  <meta http-equiv="X-UA-Compatible" content="IE=edge">
-  <meta name="dart.unittest" content="full-stack-traces">
-  <style>
-     .unittest-table { font-family:monospace; border:1px; }
-     .unittest-pass { background: #6b3;}
-     .unittest-fail { background: #d55;}
-     .unittest-error { background: #a11;}
-  </style>
-</head>
-<body>
-  <script type="text/javascript"
-      src="/root_dart/tools/testing/dart/test_controller.js"></script>
-  %TEST_SCRIPTS%
-</body>
-</html>
diff --git a/runtime/observatory/tests/observatory_ui/function_ref/element_test.dart b/runtime/observatory/tests/observatory_ui/function_ref/element_test.dart
deleted file mode 100644
index 516b9d5..0000000
--- a/runtime/observatory/tests/observatory_ui/function_ref/element_test.dart
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:html';
-import 'package:test/test.dart';
-import 'package:observatory/src/elements/function_ref.dart';
-import '../mocks.dart';
-
-main() {
-  FunctionRefElement.tag.ensureRegistration();
-
-  final isolate = new IsolateRefMock(id: 'i-id', name: 'i-name');
-  final function = new FunctionRefMock(id: 'f-id', name: 'f-name');
-  test('instantiation', () {
-    final e = new FunctionRefElement(isolate, function);
-    expect(e, isNotNull, reason: 'element correctly created');
-    expect(e.isolate, equals(isolate));
-    expect(e.function, equals(function));
-  });
-  test('elements created after attachment', () async {
-    final e = new FunctionRefElement(isolate, function);
-    document.body.append(e);
-    await e.onRendered.first;
-    expect(e.children.length, isNonZero, reason: 'has elements');
-    e.remove();
-    await e.onRendered.first;
-    expect(e.children.length, isZero, reason: 'is empty');
-  });
-}
diff --git a/runtime/observatory/tests/observatory_ui/function_ref/element_test.html b/runtime/observatory/tests/observatory_ui/function_ref/element_test.html
deleted file mode 100644
index f548be4..0000000
--- a/runtime/observatory/tests/observatory_ui/function_ref/element_test.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-  <meta http-equiv="X-UA-Compatible" content="IE=edge">
-  <meta name="dart.unittest" content="full-stack-traces">
-  <style>
-     .unittest-table { font-family:monospace; border:1px; }
-     .unittest-pass { background: #6b3;}
-     .unittest-fail { background: #d55;}
-     .unittest-error { background: #a11;}
-  </style>
-</head>
-<body>
-  <script type="text/javascript"
-      src="/root_dart/tools/testing/dart/test_controller.js"></script>
-  %TEST_SCRIPTS%
-</body>
-</html>
diff --git a/runtime/observatory/tests/observatory_ui/general_error/element_test.dart b/runtime/observatory/tests/observatory_ui/general_error/element_test.dart
deleted file mode 100644
index 2509c92..0000000
--- a/runtime/observatory/tests/observatory_ui/general_error/element_test.dart
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:html';
-import 'package:test/test.dart';
-import 'package:observatory/src/elements/general_error.dart';
-import 'package:observatory/src/elements/nav/notify.dart';
-import '../mocks.dart';
-
-main() {
-  GeneralErrorElement.tag.ensureRegistration();
-
-  final nTag = NavNotifyElement.tag.name;
-  final notifications = new NotificationRepositoryMock();
-  final String message = 'content-of-the-message';
-
-  group('instantiation', () {
-    test('default', () {
-      final GeneralErrorElement e = new GeneralErrorElement(notifications);
-      expect(e, isNotNull, reason: 'element correctly created');
-      expect(e.message, isNotNull, reason: 'message should not be null');
-      expect(e.message, equals(''), reason: 'message should be empty');
-    });
-    test('message', () {
-      final GeneralErrorElement e =
-          new GeneralErrorElement(notifications, message: message);
-      expect(e, isNotNull, reason: 'element correctly created');
-      expect(e.message, isNotNull, reason: 'message should not be null');
-      expect(e.message, equals(message), reason: 'message should be the same');
-    });
-  });
-  group('elements', () {
-    test('created after attachment', () async {
-      final GeneralErrorElement e = new GeneralErrorElement(notifications);
-      document.body.append(e);
-      await e.onRendered.first;
-      expect(e.children.length, isNonZero, reason: 'has elements');
-      expect(e.querySelectorAll(nTag).length, equals(1));
-      e.remove();
-      await e.onRendered.first;
-      expect(e.children.length, isZero, reason: 'is empty');
-    });
-    test('react to message change', () async {
-      final GeneralErrorElement e = new GeneralErrorElement(notifications);
-      document.body.append(e);
-      await e.onRendered.first;
-      expect(e.innerHtml.contains(message), isFalse,
-          reason: 'should not contain');
-      e.message = message;
-      await e.onRendered.first;
-      expect(e.innerHtml.contains(message), isTrue, reason: 'should contain');
-      e.message = '';
-      await e.onRendered.first;
-      expect(e.innerHtml.contains(message), isFalse,
-          reason: 'should not contain');
-      e.remove();
-      await e.onRendered.first;
-    });
-  });
-}
diff --git a/runtime/observatory/tests/observatory_ui/general_error/element_test.html b/runtime/observatory/tests/observatory_ui/general_error/element_test.html
deleted file mode 100644
index f548be4..0000000
--- a/runtime/observatory/tests/observatory_ui/general_error/element_test.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-  <meta http-equiv="X-UA-Compatible" content="IE=edge">
-  <meta name="dart.unittest" content="full-stack-traces">
-  <style>
-     .unittest-table { font-family:monospace; border:1px; }
-     .unittest-pass { background: #6b3;}
-     .unittest-fail { background: #d55;}
-     .unittest-error { background: #a11;}
-  </style>
-</head>
-<body>
-  <script type="text/javascript"
-      src="/root_dart/tools/testing/dart/test_controller.js"></script>
-  %TEST_SCRIPTS%
-</body>
-</html>
diff --git a/runtime/observatory/tests/observatory_ui/heap_snapshot/element_test.dart b/runtime/observatory/tests/observatory_ui/heap_snapshot/element_test.dart
deleted file mode 100644
index 1907d27..0000000
--- a/runtime/observatory/tests/observatory_ui/heap_snapshot/element_test.dart
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:html';
-import 'dart:async';
-import 'package:test/test.dart';
-import 'package:observatory/models.dart' as M;
-import 'package:observatory/src/elements/containers/virtual_tree.dart';
-import 'package:observatory/src/elements/heap_snapshot.dart';
-import '../mocks.dart';
-
-main() {
-  HeapSnapshotElement.tag.ensureRegistration();
-
-  final tTag = VirtualTreeElement.tag.name;
-
-  const vm = const VMMock();
-  const isolate = const IsolateRefMock();
-  final events = new EventRepositoryMock();
-  final notifs = new NotificationRepositoryMock();
-  final snapshots = new HeapSnapshotRepositoryMock();
-  final objects = new ObjectRepositoryMock();
-  test('instantiation', () {
-    final e = new HeapSnapshotElement(
-        vm, isolate, events, notifs, snapshots, objects);
-    expect(e, isNotNull, reason: 'element correctly created');
-  });
-  test('elements created', () async {
-    final controller =
-        new StreamController<M.HeapSnapshotLoadingProgressEvent>.broadcast();
-    final snapshots =
-        new HeapSnapshotRepositoryMock(getter: (M.IsolateRef i, bool gc) {
-      expect(i, equals(isolate));
-      expect(gc, isFalse);
-      return controller.stream;
-    });
-    final e = new HeapSnapshotElement(
-        vm, isolate, events, notifs, snapshots, objects);
-    document.body.append(e);
-    await e.onRendered.first;
-    expect(e.children.length, isNonZero, reason: 'has elements');
-    expect(e.querySelectorAll(tTag).length, isZero);
-    controller.add(const HeapSnapshotLoadingProgressEventMock(
-        progress: const HeapSnapshotLoadingProgressMock(
-            status: M.HeapSnapshotLoadingStatus.fetching)));
-    await e.onRendered.first;
-    expect(e.querySelectorAll(tTag).length, isZero);
-    controller.add(const HeapSnapshotLoadingProgressEventMock(
-        progress: const HeapSnapshotLoadingProgressMock(
-            status: M.HeapSnapshotLoadingStatus.loading)));
-    controller.add(new HeapSnapshotLoadingProgressEventMock(
-        progress: new HeapSnapshotLoadingProgressMock(
-            status: M.HeapSnapshotLoadingStatus.loaded,
-            snapshot: new HeapSnapshotMock(timestamp: new DateTime.now()))));
-    controller.close();
-    await e.onRendered.first;
-    expect(e.querySelectorAll(tTag).length, equals(1));
-    e.remove();
-    await e.onRendered.first;
-    expect(e.children.length, isZero, reason: 'is empty');
-  });
-}
diff --git a/runtime/observatory/tests/observatory_ui/heap_snapshot/element_test.html b/runtime/observatory/tests/observatory_ui/heap_snapshot/element_test.html
deleted file mode 100644
index f548be4..0000000
--- a/runtime/observatory/tests/observatory_ui/heap_snapshot/element_test.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-  <meta http-equiv="X-UA-Compatible" content="IE=edge">
-  <meta name="dart.unittest" content="full-stack-traces">
-  <style>
-     .unittest-table { font-family:monospace; border:1px; }
-     .unittest-pass { background: #6b3;}
-     .unittest-fail { background: #d55;}
-     .unittest-error { background: #a11;}
-  </style>
-</head>
-<body>
-  <script type="text/javascript"
-      src="/root_dart/tools/testing/dart/test_controller.js"></script>
-  %TEST_SCRIPTS%
-</body>
-</html>
diff --git a/runtime/observatory/tests/observatory_ui/icdata_ref/element_test.dart b/runtime/observatory/tests/observatory_ui/icdata_ref/element_test.dart
deleted file mode 100644
index 263c4fb..0000000
--- a/runtime/observatory/tests/observatory_ui/icdata_ref/element_test.dart
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:html';
-import 'package:test/test.dart';
-import 'package:observatory/src/elements/instance_ref.dart';
-import '../mocks.dart';
-
-main() {
-  InstanceRefElement.tag.ensureRegistration();
-
-  const isolate = const IsolateRefMock();
-  const instance = const InstanceRefMock();
-  final objects = new ObjectRepositoryMock();
-  test('instantiation', () {
-    final e = new InstanceRefElement(isolate, instance, objects);
-    expect(e, isNotNull, reason: 'element correctly created');
-    expect(e.isolate, equals(isolate));
-    expect(e.instance, equals(instance));
-  });
-  test('elements created after attachment', () async {
-    final e = new InstanceRefElement(isolate, instance, objects);
-    document.body.append(e);
-    await e.onRendered.first;
-    expect(e.children.length, isNonZero, reason: 'has elements');
-    e.remove();
-    await e.onRendered.first;
-    expect(e.children.length, isZero, reason: 'is empty');
-  });
-}
diff --git a/runtime/observatory/tests/observatory_ui/icdata_ref/element_test.html b/runtime/observatory/tests/observatory_ui/icdata_ref/element_test.html
deleted file mode 100644
index f548be4..0000000
--- a/runtime/observatory/tests/observatory_ui/icdata_ref/element_test.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-  <meta http-equiv="X-UA-Compatible" content="IE=edge">
-  <meta name="dart.unittest" content="full-stack-traces">
-  <style>
-     .unittest-table { font-family:monospace; border:1px; }
-     .unittest-pass { background: #6b3;}
-     .unittest-fail { background: #d55;}
-     .unittest-error { background: #a11;}
-  </style>
-</head>
-<body>
-  <script type="text/javascript"
-      src="/root_dart/tools/testing/dart/test_controller.js"></script>
-  %TEST_SCRIPTS%
-</body>
-</html>
diff --git a/runtime/observatory/tests/observatory_ui/icdata_view/element_test.dart b/runtime/observatory/tests/observatory_ui/icdata_view/element_test.dart
deleted file mode 100644
index 3e4907b..0000000
--- a/runtime/observatory/tests/observatory_ui/icdata_view/element_test.dart
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:html';
-import 'package:test/test.dart';
-import 'package:observatory/src/elements/icdata_view.dart';
-import 'package:observatory/src/elements/nav/refresh.dart';
-import 'package:observatory/src/elements/object_common.dart';
-import '../mocks.dart';
-
-main() {
-  ICDataViewElement.tag.ensureRegistration();
-
-  final cTag = ObjectCommonElement.tag.name;
-  final rTag = NavRefreshElement.tag.name;
-
-  const vm = const VMMock();
-  const isolate = const IsolateRefMock();
-  final events = new EventRepositoryMock();
-  final notifs = new NotificationRepositoryMock();
-  final icdata = const ICDataMock();
-  final icdatas = new ICDataRepositoryMock();
-  final reachableSizes = new ReachableSizeRepositoryMock();
-  final retainedSizes = new RetainedSizeRepositoryMock();
-  final inbounds = new InboundReferencesRepositoryMock();
-  final paths = new RetainingPathRepositoryMock();
-  final objects = new ObjectRepositoryMock();
-  test('instantiation', () {
-    final e = new ICDataViewElement(vm, isolate, icdata, events, notifs,
-        icdatas, retainedSizes, reachableSizes, inbounds, paths, objects);
-    expect(e, isNotNull, reason: 'element correctly created');
-    expect(e.isolate, equals(isolate));
-    expect(e.icdata, equals(icdata));
-  });
-  test('elements created after attachment', () async {
-    final icdatas = new ICDataRepositoryMock(
-        getter: expectAsync2((i, id) async {
-      expect(i, equals(isolate));
-      expect(id, equals(icdata.id));
-      return icdata;
-    }, count: 1));
-    final e = new ICDataViewElement(vm, isolate, icdata, events, notifs,
-        icdatas, retainedSizes, reachableSizes, inbounds, paths, objects);
-    document.body.append(e);
-    await e.onRendered.first;
-    expect(e.children.length, isNonZero, reason: 'has elements');
-    expect(e.querySelectorAll(cTag).length, equals(1));
-    (e.querySelector(rTag) as NavRefreshElement).refresh();
-    await e.onRendered.first;
-    e.remove();
-    await e.onRendered.first;
-    expect(e.children.length, isZero, reason: 'is empty');
-  });
-}
diff --git a/runtime/observatory/tests/observatory_ui/icdata_view/element_test.html b/runtime/observatory/tests/observatory_ui/icdata_view/element_test.html
deleted file mode 100644
index f548be4..0000000
--- a/runtime/observatory/tests/observatory_ui/icdata_view/element_test.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-  <meta http-equiv="X-UA-Compatible" content="IE=edge">
-  <meta name="dart.unittest" content="full-stack-traces">
-  <style>
-     .unittest-table { font-family:monospace; border:1px; }
-     .unittest-pass { background: #6b3;}
-     .unittest-fail { background: #d55;}
-     .unittest-error { background: #a11;}
-  </style>
-</head>
-<body>
-  <script type="text/javascript"
-      src="/root_dart/tools/testing/dart/test_controller.js"></script>
-  %TEST_SCRIPTS%
-</body>
-</html>
diff --git a/runtime/observatory/tests/observatory_ui/inbound_references/element_test.dart b/runtime/observatory/tests/observatory_ui/inbound_references/element_test.dart
deleted file mode 100644
index aa0eac2..0000000
--- a/runtime/observatory/tests/observatory_ui/inbound_references/element_test.dart
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:html';
-import 'package:test/test.dart';
-import 'package:observatory/src/elements/curly_block.dart';
-import 'package:observatory/src/elements/inbound_references.dart';
-import 'package:observatory/src/elements/instance_ref.dart';
-import '../mocks.dart';
-
-main() {
-  InboundReferencesElement.tag.ensureRegistration();
-
-  final cTag = CurlyBlockElement.tag.name;
-  final iTag = InstanceRefElement.tag.name;
-  final rTag = InboundReferencesElement.tag.name;
-
-  const isolate = const IsolateRefMock();
-  const object = const InstanceRefMock();
-  final inbounds = new InboundReferencesRepositoryMock();
-  final objects = new ObjectRepositoryMock();
-  test('instantiation', () {
-    final e = new InboundReferencesElement(isolate, object, inbounds, objects);
-    expect(e, isNotNull, reason: 'element correctly created');
-    expect(e.isolate, equals(isolate));
-    expect(e.object, equals(object));
-  });
-  test('elements created after attachment', () async {
-    const source = const InstanceRefMock(id: 'source-id', name: 'source_name');
-    const references = const InboundReferencesMock(
-        elements: const [const InboundReferenceMock(source: source)]);
-    bool invoked = false;
-    final inbounds = new InboundReferencesRepositoryMock(
-        getter: expectAsync2((i, id) async {
-      expect(i, equals(isolate));
-      expect(id, equals(object.id));
-      invoked = true;
-      return references;
-    }, count: 1));
-    final objects = new ObjectRepositoryMock();
-    final e = new InboundReferencesElement(isolate, object, inbounds, objects);
-    document.body.append(e);
-    await e.onRendered.first;
-    expect(invoked, isFalse);
-    expect(e.children, isNotEmpty, reason: 'has elements');
-    expect(e.querySelectorAll(iTag).length, isZero);
-    (e.querySelector(cTag) as CurlyBlockElement).toggle();
-    await e.onRendered.first;
-    expect(invoked, isTrue);
-    expect(e.querySelectorAll(iTag).length, equals(1));
-    expect(e.querySelectorAll(rTag).length, equals(1));
-    e.remove();
-    await e.onRendered.first;
-    expect(e.children, isEmpty, reason: 'is empty');
-  });
-}
diff --git a/runtime/observatory/tests/observatory_ui/inbound_references/element_test.html b/runtime/observatory/tests/observatory_ui/inbound_references/element_test.html
deleted file mode 100644
index f548be4..0000000
--- a/runtime/observatory/tests/observatory_ui/inbound_references/element_test.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-  <meta http-equiv="X-UA-Compatible" content="IE=edge">
-  <meta name="dart.unittest" content="full-stack-traces">
-  <style>
-     .unittest-table { font-family:monospace; border:1px; }
-     .unittest-pass { background: #6b3;}
-     .unittest-fail { background: #d55;}
-     .unittest-error { background: #a11;}
-  </style>
-</head>
-<body>
-  <script type="text/javascript"
-      src="/root_dart/tools/testing/dart/test_controller.js"></script>
-  %TEST_SCRIPTS%
-</body>
-</html>
diff --git a/runtime/observatory/tests/observatory_ui/instance_ref/element_test.dart b/runtime/observatory/tests/observatory_ui/instance_ref/element_test.dart
deleted file mode 100644
index bbec367..0000000
--- a/runtime/observatory/tests/observatory_ui/instance_ref/element_test.dart
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:html';
-import 'package:test/test.dart';
-import 'package:observatory/src/elements/icdata_ref.dart';
-import '../mocks.dart';
-
-main() {
-  ICDataRefElement.tag.ensureRegistration();
-
-  const isolate = const IsolateRefMock();
-  const icdata = const ICDataRefMock();
-  test('instantiation', () {
-    final e = new ICDataRefElement(isolate, icdata);
-    expect(e, isNotNull, reason: 'element correctly created');
-    expect(e.isolate, equals(isolate));
-    expect(e.icdata, equals(icdata));
-  });
-  test('elements created after attachment', () async {
-    final e = new ICDataRefElement(isolate, icdata);
-    document.body.append(e);
-    await e.onRendered.first;
-    expect(e.children.length, isNonZero, reason: 'has elements');
-    e.remove();
-    await e.onRendered.first;
-    expect(e.children.length, isZero, reason: 'is empty');
-  });
-}
diff --git a/runtime/observatory/tests/observatory_ui/instance_ref/element_test.html b/runtime/observatory/tests/observatory_ui/instance_ref/element_test.html
deleted file mode 100644
index f548be4..0000000
--- a/runtime/observatory/tests/observatory_ui/instance_ref/element_test.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-  <meta http-equiv="X-UA-Compatible" content="IE=edge">
-  <meta name="dart.unittest" content="full-stack-traces">
-  <style>
-     .unittest-table { font-family:monospace; border:1px; }
-     .unittest-pass { background: #6b3;}
-     .unittest-fail { background: #d55;}
-     .unittest-error { background: #a11;}
-  </style>
-</head>
-<body>
-  <script type="text/javascript"
-      src="/root_dart/tools/testing/dart/test_controller.js"></script>
-  %TEST_SCRIPTS%
-</body>
-</html>
diff --git a/runtime/observatory/tests/observatory_ui/isolate/counter_chart/element_test.dart b/runtime/observatory/tests/observatory_ui/isolate/counter_chart/element_test.dart
deleted file mode 100644
index af3b05f..0000000
--- a/runtime/observatory/tests/observatory_ui/isolate/counter_chart/element_test.dart
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:html';
-import 'package:test/test.dart';
-import 'package:observatory/src/elements/isolate/counter_chart.dart';
-
-main() {
-  IsolateCounterChartElement.tag.ensureRegistration();
-
-  test('instantiation', () {
-    final e = new IsolateCounterChartElement({});
-    expect(e, isNotNull, reason: 'element correctly created');
-  });
-  test('elements created', () async {
-    final e = new IsolateCounterChartElement({});
-    document.body.append(e);
-    await e.onRendered.first;
-    expect(e.children.length, isNonZero, reason: 'has elements');
-    e.remove();
-    await e.onRendered.first;
-    expect(e.children.length, isZero, reason: 'is empty');
-  });
-}
diff --git a/runtime/observatory/tests/observatory_ui/isolate/counter_chart/element_test.html b/runtime/observatory/tests/observatory_ui/isolate/counter_chart/element_test.html
deleted file mode 100644
index f548be4..0000000
--- a/runtime/observatory/tests/observatory_ui/isolate/counter_chart/element_test.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-  <meta http-equiv="X-UA-Compatible" content="IE=edge">
-  <meta name="dart.unittest" content="full-stack-traces">
-  <style>
-     .unittest-table { font-family:monospace; border:1px; }
-     .unittest-pass { background: #6b3;}
-     .unittest-fail { background: #d55;}
-     .unittest-error { background: #a11;}
-  </style>
-</head>
-<body>
-  <script type="text/javascript"
-      src="/root_dart/tools/testing/dart/test_controller.js"></script>
-  %TEST_SCRIPTS%
-</body>
-</html>
diff --git a/runtime/observatory/tests/observatory_ui/isolate/isolate-shared-summary/element_test.dart b/runtime/observatory/tests/observatory_ui/isolate/isolate-shared-summary/element_test.dart
deleted file mode 100644
index fbbfaf1..0000000
--- a/runtime/observatory/tests/observatory_ui/isolate/isolate-shared-summary/element_test.dart
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:html';
-import 'package:test/test.dart';
-import 'package:observatory/src/elements/isolate/counter_chart.dart';
-import 'package:observatory/src/elements/isolate/shared_summary.dart';
-import '../../mocks.dart';
-
-main() {
-  IsolateSharedSummaryElement.tag.ensureRegistration();
-
-  final cTag = IsolateCounterChartElement.tag.name;
-
-  const isolate = const IsolateMock();
-  final events = new EventRepositoryMock();
-  test('instantiation', () {
-    final e = new IsolateSharedSummaryElement(isolate, events);
-    expect(e, isNotNull, reason: 'element correctly created');
-  });
-  test('elements created', () async {
-    final e = new IsolateSharedSummaryElement(isolate, events);
-    document.body.append(e);
-    await e.onRendered.first;
-    expect(e.children.length, isNonZero, reason: 'has elements');
-    expect(e.querySelectorAll(cTag).length, equals(1));
-    e.remove();
-    await e.onRendered.first;
-    expect(e.children.length, isZero, reason: 'is empty');
-  });
-}
diff --git a/runtime/observatory/tests/observatory_ui/isolate/isolate-shared-summary/element_test.html b/runtime/observatory/tests/observatory_ui/isolate/isolate-shared-summary/element_test.html
deleted file mode 100644
index f548be4..0000000
--- a/runtime/observatory/tests/observatory_ui/isolate/isolate-shared-summary/element_test.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-  <meta http-equiv="X-UA-Compatible" content="IE=edge">
-  <meta name="dart.unittest" content="full-stack-traces">
-  <style>
-     .unittest-table { font-family:monospace; border:1px; }
-     .unittest-pass { background: #6b3;}
-     .unittest-fail { background: #d55;}
-     .unittest-error { background: #a11;}
-  </style>
-</head>
-<body>
-  <script type="text/javascript"
-      src="/root_dart/tools/testing/dart/test_controller.js"></script>
-  %TEST_SCRIPTS%
-</body>
-</html>
diff --git a/runtime/observatory/tests/observatory_ui/isolate_reconnect/element_test.dart b/runtime/observatory/tests/observatory_ui/isolate_reconnect/element_test.dart
deleted file mode 100644
index 10ba984..0000000
--- a/runtime/observatory/tests/observatory_ui/isolate_reconnect/element_test.dart
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:html';
-import 'package:test/test.dart';
-import 'package:observatory/src/elements/isolate_reconnect.dart';
-import 'package:observatory/src/elements/nav/notify.dart';
-import '../mocks.dart';
-
-main() {
-  IsolateReconnectElement.tag.ensureRegistration();
-
-  final nTag = NavNotifyElement.tag.name;
-
-  EventRepositoryMock events;
-  NotificationRepositoryMock notifications;
-  Uri uri;
-  const vm = const VMMock(isolates: const [
-    const IsolateMock(id: 'i-1-id'),
-    const IsolateMock(id: 'i-2-id')
-  ]);
-  const missing = 'missing-id';
-  setUp(() {
-    events = new EventRepositoryMock();
-    notifications = new NotificationRepositoryMock();
-    uri = new Uri(path: 'path');
-  });
-  test('instantiation', () {
-    final e =
-        new IsolateReconnectElement(vm, events, notifications, missing, uri);
-    expect(e, isNotNull, reason: 'element correctly created');
-    expect(e.vm, equals(vm));
-    expect(e.missing, equals(missing));
-    expect(e.uri, equals(uri));
-  });
-  test('elements created after attachment', () async {
-    final e =
-        new IsolateReconnectElement(vm, events, notifications, missing, uri);
-    document.body.append(e);
-    await e.onRendered.first;
-    expect(e.children.length, isNonZero, reason: 'has elements');
-    expect(e.querySelector(nTag), isNotNull, reason: 'has notifications');
-    expect(
-        e.querySelectorAll('.isolate-link').length, equals(vm.isolates.length),
-        reason: 'has links');
-    e.remove();
-    await e.onRendered.first;
-    expect(e.children.length, isZero, reason: 'is empty');
-  });
-  group('updates', () {
-    test('are correctly listen', () async {
-      final e =
-          new IsolateReconnectElement(vm, events, notifications, missing, uri);
-      expect(events.onVMUpdateHasListener, isFalse);
-      document.body.append(e);
-      await e.onRendered.first;
-      expect(events.onVMUpdateHasListener, isTrue);
-      e.remove();
-      await e.onRendered.first;
-      expect(events.onVMUpdateHasListener, isFalse);
-    });
-    test('have effects', () async {
-      final e =
-          new IsolateReconnectElement(vm, events, notifications, missing, uri);
-      const vm2 = const VMMock(isolates: const [
-        const IsolateMock(id: 'i-1-id'),
-        const IsolateMock(id: 'i-2-id'),
-        const IsolateMock(id: 'i-3-id')
-      ]);
-      document.body.append(e);
-      await e.onRendered.first;
-      expect(e.querySelectorAll('.isolate-link').length,
-          equals(vm.isolates.length));
-      events.add(new VMUpdateEventMock(vm: vm2));
-      await e.onRendered.first;
-      expect(e.querySelectorAll('.isolate-link').length,
-          equals(vm2.isolates.length));
-      e.remove();
-      await e.onRendered.first;
-    });
-  });
-}
diff --git a/runtime/observatory/tests/observatory_ui/isolate_reconnect/element_test.html b/runtime/observatory/tests/observatory_ui/isolate_reconnect/element_test.html
deleted file mode 100644
index f548be4..0000000
--- a/runtime/observatory/tests/observatory_ui/isolate_reconnect/element_test.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-  <meta http-equiv="X-UA-Compatible" content="IE=edge">
-  <meta name="dart.unittest" content="full-stack-traces">
-  <style>
-     .unittest-table { font-family:monospace; border:1px; }
-     .unittest-pass { background: #6b3;}
-     .unittest-fail { background: #d55;}
-     .unittest-error { background: #a11;}
-  </style>
-</head>
-<body>
-  <script type="text/javascript"
-      src="/root_dart/tools/testing/dart/test_controller.js"></script>
-  %TEST_SCRIPTS%
-</body>
-</html>
diff --git a/runtime/observatory/tests/observatory_ui/isolate_ref/element_test.dart b/runtime/observatory/tests/observatory_ui/isolate_ref/element_test.dart
deleted file mode 100644
index 7dd81cc..0000000
--- a/runtime/observatory/tests/observatory_ui/isolate_ref/element_test.dart
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:html';
-import 'package:test/test.dart';
-import 'package:observatory/src/elements/isolate_ref.dart';
-import '../mocks.dart';
-
-main() {
-  IsolateRefElement.tag.ensureRegistration();
-
-  final ref = new IsolateRefMock(id: 'id', name: 'old-name');
-  final events = new EventRepositoryMock();
-  final obj = new IsolateMock(id: 'id', name: 'new-name');
-  group('instantiation', () {
-    test('IsolateRef', () {
-      final e = new IsolateRefElement(ref, events);
-      expect(e, isNotNull, reason: 'element correctly created');
-      expect(e.isolate, equals(ref));
-    });
-    test('Isolate', () {
-      final e = new IsolateRefElement(obj, events);
-      expect(e, isNotNull, reason: 'element correctly created');
-      expect(e.isolate, equals(obj));
-    });
-  });
-  test('elements created after attachment', () async {
-    final e = new IsolateRefElement(ref, events);
-    document.body.append(e);
-    await e.onRendered.first;
-    expect(e.children.length, isNonZero, reason: 'has elements');
-    e.remove();
-    await e.onRendered.first;
-    expect(e.children.length, isZero, reason: 'is empty');
-  });
-  group('updates', () {
-    test('are correctly listen', () async {
-      final e = new IsolateRefElement(ref, events);
-      expect(events.onIsolateUpdateHasListener, isFalse);
-      document.body.append(e);
-      await e.onRendered.first;
-      expect(events.onIsolateUpdateHasListener, isTrue);
-      e.remove();
-      await e.onRendered.first;
-      expect(events.onIsolateUpdateHasListener, isFalse);
-    });
-    test('have effects', () async {
-      final e = new IsolateRefElement(ref, events);
-      document.body.append(e);
-      await e.onRendered.first;
-      expect(e.innerHtml.contains(ref.id), isTrue);
-      events.add(new IsolateUpdateEventMock(isolate: obj));
-      await e.onRendered.first;
-      expect(e.innerHtml.contains(ref.name), isFalse);
-      expect(e.innerHtml.contains(obj.name), isTrue);
-      e.remove();
-    });
-  });
-}
diff --git a/runtime/observatory/tests/observatory_ui/isolate_ref/element_test.html b/runtime/observatory/tests/observatory_ui/isolate_ref/element_test.html
deleted file mode 100644
index f548be4..0000000
--- a/runtime/observatory/tests/observatory_ui/isolate_ref/element_test.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-  <meta http-equiv="X-UA-Compatible" content="IE=edge">
-  <meta name="dart.unittest" content="full-stack-traces">
-  <style>
-     .unittest-table { font-family:monospace; border:1px; }
-     .unittest-pass { background: #6b3;}
-     .unittest-fail { background: #d55;}
-     .unittest-error { background: #a11;}
-  </style>
-</head>
-<body>
-  <script type="text/javascript"
-      src="/root_dart/tools/testing/dart/test_controller.js"></script>
-  %TEST_SCRIPTS%
-</body>
-</html>
diff --git a/runtime/observatory/tests/observatory_ui/library_ref/element_test.dart b/runtime/observatory/tests/observatory_ui/library_ref/element_test.dart
deleted file mode 100644
index 53d176d..0000000
--- a/runtime/observatory/tests/observatory_ui/library_ref/element_test.dart
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:html';
-import 'package:test/test.dart';
-import 'package:observatory/src/elements/library_ref.dart';
-import '../mocks.dart';
-
-main() {
-  LibraryRefElement.tag.ensureRegistration();
-
-  const isolate = const IsolateRefMock(id: 'i-id', name: 'i-name');
-  const library = const LibraryRefMock(id: 'c-id', name: 'c-name');
-  test('instantiation', () {
-    final e = new LibraryRefElement(isolate, library);
-    expect(e, isNotNull, reason: 'element correctly created');
-    expect(e.isolate, equals(isolate));
-    expect(e.library, equals(library));
-  });
-  test('elements created after attachment', () async {
-    final e = new LibraryRefElement(isolate, library);
-    document.body.append(e);
-    await e.onRendered.first;
-    expect(e.children.length, isNonZero, reason: 'has elements');
-    e.remove();
-    await e.onRendered.first;
-    expect(e.children.length, isZero, reason: 'is empty');
-  });
-}
diff --git a/runtime/observatory/tests/observatory_ui/library_ref/element_test.html b/runtime/observatory/tests/observatory_ui/library_ref/element_test.html
deleted file mode 100644
index f548be4..0000000
--- a/runtime/observatory/tests/observatory_ui/library_ref/element_test.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-  <meta http-equiv="X-UA-Compatible" content="IE=edge">
-  <meta name="dart.unittest" content="full-stack-traces">
-  <style>
-     .unittest-table { font-family:monospace; border:1px; }
-     .unittest-pass { background: #6b3;}
-     .unittest-fail { background: #d55;}
-     .unittest-error { background: #a11;}
-  </style>
-</head>
-<body>
-  <script type="text/javascript"
-      src="/root_dart/tools/testing/dart/test_controller.js"></script>
-  %TEST_SCRIPTS%
-</body>
-</html>
diff --git a/runtime/observatory/tests/observatory_ui/local_var_descriptor_ref/element_test.dart b/runtime/observatory/tests/observatory_ui/local_var_descriptor_ref/element_test.dart
deleted file mode 100644
index eeae150..0000000
--- a/runtime/observatory/tests/observatory_ui/local_var_descriptor_ref/element_test.dart
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:html';
-import 'package:test/test.dart';
-import 'package:observatory/src/elements/local_var_descriptors_ref.dart';
-import '../mocks.dart';
-
-main() {
-  LocalVarDescriptorsRefElement.tag.ensureRegistration();
-
-  const isolate = const IsolateRefMock();
-  const localVar = const LocalVarDescriptorsRefMock();
-  test('instantiation', () {
-    final e = new LocalVarDescriptorsRefElement(isolate, localVar);
-    expect(e, isNotNull, reason: 'element correctly created');
-    expect(e.isolate, equals(isolate));
-    expect(e.localVar, equals(localVar));
-  });
-  test('elements created after attachment', () async {
-    final e = new LocalVarDescriptorsRefElement(isolate, localVar);
-    document.body.append(e);
-    await e.onRendered.first;
-    expect(e.children.length, isNonZero, reason: 'has elements');
-    e.remove();
-    await e.onRendered.first;
-    expect(e.children.length, isZero, reason: 'is empty');
-  });
-}
diff --git a/runtime/observatory/tests/observatory_ui/local_var_descriptor_ref/element_test.html b/runtime/observatory/tests/observatory_ui/local_var_descriptor_ref/element_test.html
deleted file mode 100644
index f548be4..0000000
--- a/runtime/observatory/tests/observatory_ui/local_var_descriptor_ref/element_test.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-  <meta http-equiv="X-UA-Compatible" content="IE=edge">
-  <meta name="dart.unittest" content="full-stack-traces">
-  <style>
-     .unittest-table { font-family:monospace; border:1px; }
-     .unittest-pass { background: #6b3;}
-     .unittest-fail { background: #d55;}
-     .unittest-error { background: #a11;}
-  </style>
-</head>
-<body>
-  <script type="text/javascript"
-      src="/root_dart/tools/testing/dart/test_controller.js"></script>
-  %TEST_SCRIPTS%
-</body>
-</html>
diff --git a/runtime/observatory/tests/observatory_ui/megamorphiccache_ref/element_test.dart b/runtime/observatory/tests/observatory_ui/megamorphiccache_ref/element_test.dart
deleted file mode 100644
index 7a48808..0000000
--- a/runtime/observatory/tests/observatory_ui/megamorphiccache_ref/element_test.dart
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:html';
-import 'package:test/test.dart';
-import 'package:observatory/src/elements/megamorphiccache_ref.dart';
-import '../mocks.dart';
-
-main() {
-  MegamorphicCacheRefElement.tag.ensureRegistration();
-
-  const isolate = const IsolateRefMock();
-  const cache = const MegamorphicCacheRefMock();
-  test('instantiation', () {
-    final e = new MegamorphicCacheRefElement(isolate, cache);
-    expect(e, isNotNull, reason: 'element correctly created');
-    expect(e.isolate, equals(isolate));
-    expect(e.cache, equals(cache));
-  });
-  test('elements created after attachment', () async {
-    final e = new MegamorphicCacheRefElement(isolate, cache);
-    document.body.append(e);
-    await e.onRendered.first;
-    expect(e.children.length, isNonZero, reason: 'has elements');
-    e.remove();
-    await e.onRendered.first;
-    expect(e.children.length, isZero, reason: 'is empty');
-  });
-}
diff --git a/runtime/observatory/tests/observatory_ui/megamorphiccache_ref/element_test.html b/runtime/observatory/tests/observatory_ui/megamorphiccache_ref/element_test.html
deleted file mode 100644
index f548be4..0000000
--- a/runtime/observatory/tests/observatory_ui/megamorphiccache_ref/element_test.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-  <meta http-equiv="X-UA-Compatible" content="IE=edge">
-  <meta name="dart.unittest" content="full-stack-traces">
-  <style>
-     .unittest-table { font-family:monospace; border:1px; }
-     .unittest-pass { background: #6b3;}
-     .unittest-fail { background: #d55;}
-     .unittest-error { background: #a11;}
-  </style>
-</head>
-<body>
-  <script type="text/javascript"
-      src="/root_dart/tools/testing/dart/test_controller.js"></script>
-  %TEST_SCRIPTS%
-</body>
-</html>
diff --git a/runtime/observatory/tests/observatory_ui/megamorphiccache_view/element_test.dart b/runtime/observatory/tests/observatory_ui/megamorphiccache_view/element_test.dart
deleted file mode 100644
index 81dc1cd..0000000
--- a/runtime/observatory/tests/observatory_ui/megamorphiccache_view/element_test.dart
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:html';
-import 'package:test/test.dart';
-import 'package:observatory/src/elements/megamorphiccache_view.dart';
-import 'package:observatory/src/elements/nav/refresh.dart';
-import 'package:observatory/src/elements/object_common.dart';
-import '../mocks.dart';
-
-main() {
-  MegamorphicCacheViewElement.tag.ensureRegistration();
-
-  final cTag = ObjectCommonElement.tag.name;
-  final rTag = NavRefreshElement.tag.name;
-
-  const vm = const VMMock();
-  const isolate = const IsolateRefMock();
-  final events = new EventRepositoryMock();
-  final notifs = new NotificationRepositoryMock();
-  final cache = const MegamorphicCacheMock();
-  final caches = new MegamorphicCacheRepositoryMock();
-  final reachableSizes = new ReachableSizeRepositoryMock();
-  final retainedSizes = new RetainedSizeRepositoryMock();
-  final inbounds = new InboundReferencesRepositoryMock();
-  final paths = new RetainingPathRepositoryMock();
-  final objects = new ObjectRepositoryMock();
-  test('instantiation', () {
-    final e = new MegamorphicCacheViewElement(
-        vm,
-        isolate,
-        cache,
-        events,
-        notifs,
-        caches,
-        retainedSizes,
-        reachableSizes,
-        inbounds,
-        paths,
-        objects);
-    expect(e, isNotNull, reason: 'element correctly created');
-    expect(e.isolate, equals(isolate));
-    expect(e.cache, equals(cache));
-  });
-  test('elements created after attachment', () async {
-    final caches = new MegamorphicCacheRepositoryMock(
-        getter: expectAsync2((i, id) async {
-      expect(i, equals(isolate));
-      expect(id, equals(cache.id));
-      return cache;
-    }, count: 1));
-    final e = new MegamorphicCacheViewElement(
-        vm,
-        isolate,
-        cache,
-        events,
-        notifs,
-        caches,
-        retainedSizes,
-        reachableSizes,
-        inbounds,
-        paths,
-        objects);
-    document.body.append(e);
-    await e.onRendered.first;
-    expect(e.children.length, isNonZero, reason: 'has elements');
-    expect(e.querySelectorAll(cTag).length, equals(1));
-    (e.querySelector(rTag) as NavRefreshElement).refresh();
-    await e.onRendered.first;
-    e.remove();
-    await e.onRendered.first;
-    expect(e.children.length, isZero, reason: 'is empty');
-  });
-}
diff --git a/runtime/observatory/tests/observatory_ui/megamorphiccache_view/element_test.html b/runtime/observatory/tests/observatory_ui/megamorphiccache_view/element_test.html
deleted file mode 100644
index f548be4..0000000
--- a/runtime/observatory/tests/observatory_ui/megamorphiccache_view/element_test.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-  <meta http-equiv="X-UA-Compatible" content="IE=edge">
-  <meta name="dart.unittest" content="full-stack-traces">
-  <style>
-     .unittest-table { font-family:monospace; border:1px; }
-     .unittest-pass { background: #6b3;}
-     .unittest-fail { background: #d55;}
-     .unittest-error { background: #a11;}
-  </style>
-</head>
-<body>
-  <script type="text/javascript"
-      src="/root_dart/tools/testing/dart/test_controller.js"></script>
-  %TEST_SCRIPTS%
-</body>
-</html>
diff --git a/runtime/observatory/tests/observatory_ui/mocks.dart b/runtime/observatory/tests/observatory_ui/mocks.dart
deleted file mode 100644
index 23efa86..0000000
--- a/runtime/observatory/tests/observatory_ui/mocks.dart
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library mocks;
-
-import 'dart:async';
-
-import 'package:observatory/models.dart' as M;
-
-part 'mocks/exceptions/connection_exception.dart';
-
-part 'mocks/objects/allocation_profile.dart';
-part 'mocks/objects/error.dart';
-part 'mocks/objects/code.dart';
-part 'mocks/objects/context.dart';
-part 'mocks/objects/event.dart';
-part 'mocks/objects/class.dart';
-part 'mocks/objects/field.dart';
-part 'mocks/objects/flag.dart';
-part 'mocks/objects/function.dart';
-part 'mocks/objects/guarded.dart';
-part 'mocks/objects/heap_snapshot.dart';
-part 'mocks/objects/heap_space.dart';
-part 'mocks/objects/icdata.dart';
-part 'mocks/objects/inbound_references.dart';
-part 'mocks/objects/instance.dart';
-part 'mocks/objects/isolate.dart';
-part 'mocks/objects/library.dart';
-part 'mocks/objects/local_var_descriptors.dart';
-part 'mocks/objects/megamorphiccache.dart';
-part 'mocks/objects/notification.dart';
-part 'mocks/objects/objectpool.dart';
-part 'mocks/objects/objectstore.dart';
-part 'mocks/objects/pc_descriptors.dart';
-part 'mocks/objects/persistent_handles.dart';
-part 'mocks/objects/ports.dart';
-part 'mocks/objects/retaining_path.dart';
-part 'mocks/objects/sample_profile.dart';
-part 'mocks/objects/script.dart';
-part 'mocks/objects/sentinel.dart';
-part 'mocks/objects/source_location.dart';
-part 'mocks/objects/target.dart';
-part 'mocks/objects/unknown.dart';
-part 'mocks/objects/vm.dart';
-
-part 'mocks/repositories/allocation_profile.dart';
-part 'mocks/repositories/class.dart';
-part 'mocks/repositories/context.dart';
-part 'mocks/repositories/event.dart';
-part 'mocks/repositories/eval.dart';
-part 'mocks/repositories/field.dart';
-part 'mocks/repositories/flag.dart';
-part 'mocks/repositories/heap_snapshot.dart';
-part 'mocks/repositories/icdata.dart';
-part 'mocks/repositories/inbound_references.dart';
-part 'mocks/repositories/instance.dart';
-part 'mocks/repositories/library.dart';
-part 'mocks/repositories/megamorphiccache.dart';
-part 'mocks/repositories/notification.dart';
-part 'mocks/repositories/object.dart';
-part 'mocks/repositories/objectpool.dart';
-part 'mocks/repositories/objectstore.dart';
-part 'mocks/repositories/ports.dart';
-part 'mocks/repositories/persistent_handles.dart';
-part 'mocks/repositories/reachable_size.dart';
-part 'mocks/repositories/retained_size.dart';
-part 'mocks/repositories/retaining_path.dart';
-part 'mocks/repositories/sample_profile.dart';
-part 'mocks/repositories/script.dart';
-part 'mocks/repositories/target.dart';
diff --git a/runtime/observatory/tests/observatory_ui/mocks/exceptions/connection_exception.dart b/runtime/observatory/tests/observatory_ui/mocks/exceptions/connection_exception.dart
deleted file mode 100644
index d036951..0000000
--- a/runtime/observatory/tests/observatory_ui/mocks/exceptions/connection_exception.dart
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-part of mocks;
-
-class ConnectionExceptionMock implements M.ConnectionException {
-  final String message;
-  const ConnectionExceptionMock({this.message});
-}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/objects/allocation_profile.dart b/runtime/observatory/tests/observatory_ui/mocks/objects/allocation_profile.dart
deleted file mode 100644
index c61989e..0000000
--- a/runtime/observatory/tests/observatory_ui/mocks/objects/allocation_profile.dart
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file
-
-part of mocks;
-
-class AllocationProfileMock implements M.AllocationProfile {
-  final DateTime lastServiceGC;
-  final DateTime lastAccumulatorReset;
-  final M.HeapSpace newSpace;
-  final M.HeapSpace oldSpace;
-  final Iterable<M.ClassHeapStats> members;
-
-  const AllocationProfileMock(
-      {this.lastServiceGC,
-      this.lastAccumulatorReset,
-      this.newSpace: const HeapSpaceMock(),
-      this.oldSpace: const HeapSpaceMock(),
-      this.members: const []});
-}
-
-class ClassHeapStatsMock implements M.ClassHeapStats {
-  final M.ClassRef clazz;
-  final String displayName;
-  final M.Allocations newSpace;
-  final M.Allocations oldSpace;
-  final int promotedInstances;
-  final int promotedBytes;
-
-  const ClassHeapStatsMock(
-      {this.clazz: const ClassRefMock(),
-      this.displayName: null,
-      this.newSpace: const AllocationsMock(),
-      this.oldSpace: const AllocationsMock(),
-      this.promotedInstances: 0,
-      this.promotedBytes: 0});
-}
-
-class AllocationsMock implements M.Allocations {
-  final M.AllocationCount accumulated;
-  final M.AllocationCount current;
-
-  const AllocationsMock(
-      {this.accumulated: const AllocationCountMock(),
-      this.current: const AllocationCountMock()});
-}
-
-class AllocationCountMock implements M.AllocationCount {
-  final int instances;
-  final int bytes;
-
-  const AllocationCountMock({this.instances: 0, this.bytes: 0});
-}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/objects/class.dart b/runtime/observatory/tests/observatory_ui/mocks/objects/class.dart
deleted file mode 100644
index 22febf2..0000000
--- a/runtime/observatory/tests/observatory_ui/mocks/objects/class.dart
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-part of mocks;
-
-class ClassRefMock implements M.ClassRef {
-  final String id;
-  final String name;
-  const ClassRefMock({this.id, this.name});
-}
-
-class ClassMock implements M.Class {
-  final String id;
-  final String name;
-  final String vmName;
-  final M.ClassRef clazz;
-  final int size;
-  final M.ErrorRef error;
-  final bool isAbstract;
-  final bool isConst;
-  final bool isPatch;
-  final M.LibraryRef library;
-  final M.SourceLocation location;
-  final M.ClassRef superclass;
-  final M.InstanceRef superType;
-  final Iterable<M.InstanceRef> interfaces;
-  final Iterable<M.FieldRef> fields;
-  final Iterable<M.FunctionRef> functions;
-  final M.InstanceRef mixin;
-  final Iterable<M.ClassRef> subclasses;
-  final M.Allocations newSpace;
-  final M.Allocations oldSpace;
-  final bool hasAllocations;
-  bool get hasNoAllocations => !hasAllocations;
-  final bool traceAllocations;
-  const ClassMock(
-      {this.id: 'c-id',
-      this.name: 'c-name',
-      this.vmName: 'c-name',
-      this.clazz,
-      this.size,
-      this.error,
-      this.isAbstract: false,
-      this.isConst: false,
-      this.isPatch: false,
-      this.library,
-      this.location,
-      this.superclass,
-      this.superType,
-      this.interfaces: const [],
-      this.fields: const [],
-      this.functions: const [],
-      this.mixin,
-      this.subclasses: const [],
-      this.hasAllocations: false,
-      this.newSpace,
-      this.oldSpace,
-      this.traceAllocations: false});
-}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/objects/code.dart b/runtime/observatory/tests/observatory_ui/mocks/objects/code.dart
deleted file mode 100644
index 4bfd950..0000000
--- a/runtime/observatory/tests/observatory_ui/mocks/objects/code.dart
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-part of mocks;
-
-class CodeRefMock implements M.CodeRef {
-  final String id;
-  final String name;
-  final M.CodeKind kind;
-  final bool isOptimized;
-
-  const CodeRefMock({this.id, this.name, this.kind, this.isOptimized: false});
-}
-
-class CodeMock implements M.Code {
-  final String id;
-  final String name;
-  final String vmName;
-  final M.ClassRef clazz;
-  final int size;
-  final M.CodeKind kind;
-  final bool isOptimized;
-  final M.FunctionRef function;
-  final M.ObjectPoolRef objectPool;
-  final Iterable<M.FunctionRef> inlinedFunctions;
-
-  const CodeMock(
-      {this.id: 'code-id',
-      this.name: 'code-name',
-      this.vmName: 'code-vmName',
-      this.clazz,
-      this.size,
-      this.kind: M.CodeKind.dart,
-      this.isOptimized: false,
-      this.function: const FunctionRefMock(),
-      this.objectPool: const ObjectPoolRefMock(),
-      this.inlinedFunctions: const []});
-}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/objects/context.dart b/runtime/observatory/tests/observatory_ui/mocks/objects/context.dart
deleted file mode 100644
index 529ac68..0000000
--- a/runtime/observatory/tests/observatory_ui/mocks/objects/context.dart
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-part of mocks;
-
-class ContextRefMock implements M.ContextRef {
-  final String id;
-  final int length;
-
-  const ContextRefMock({this.id: 'context-id', this.length});
-}
-
-class ContextMock implements M.Context {
-  final String id;
-  final M.ClassRef clazz;
-  final String vmName;
-  final int size;
-  final int length;
-  final M.Context parentContext;
-  final Iterable<M.ContextElement> variables;
-
-  const ContextMock(
-      {this.id: 'context-id',
-      this.vmName: 'context-vmName',
-      this.clazz: const ClassMock(),
-      this.size: 0,
-      this.length,
-      this.parentContext,
-      this.variables: const []});
-}
-
-class ContextElementMock implements M.ContextElement {
-  final GuardedMock<M.InstanceRef> value;
-
-  const ContextElementMock(
-      {this.value: const GuardedMock.fromValue(const InstanceRefMock())});
-}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/objects/error.dart b/runtime/observatory/tests/observatory_ui/mocks/objects/error.dart
deleted file mode 100644
index 5c76981..0000000
--- a/runtime/observatory/tests/observatory_ui/mocks/objects/error.dart
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-part of mocks;
-
-class ErrorRefMock implements M.ErrorRef {
-  final String id;
-  final M.ErrorKind kind;
-  final String message;
-
-  const ErrorRefMock(
-      {this.id: 'error-ref',
-      this.kind: M.ErrorKind.internalError,
-      this.message: 'Error Message'});
-}
-
-class ErrorMock implements M.Error {
-  final String id;
-  final M.ClassRef clazz;
-  final String vmName;
-  final int size;
-  final M.ErrorKind kind;
-  final String message;
-
-  const ErrorMock(
-      {this.id: 'error-id',
-      this.vmName: 'error-vmName',
-      this.clazz: const ClassMock(),
-      this.size: 0,
-      this.kind: M.ErrorKind.internalError,
-      this.message: 'Error Message'});
-}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/objects/event.dart b/runtime/observatory/tests/observatory_ui/mocks/objects/event.dart
deleted file mode 100644
index 5e9e470..0000000
--- a/runtime/observatory/tests/observatory_ui/mocks/objects/event.dart
+++ /dev/null
@@ -1,175 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-part of mocks;
-
-class VMUpdateEventMock implements M.VMUpdateEvent {
-  final M.VMRef vm;
-  final DateTime timestamp;
-  const VMUpdateEventMock({this.timestamp, this.vm});
-}
-
-class IsolateStartEventMock implements M.IsolateStartEvent {
-  final DateTime timestamp;
-  final M.IsolateRef isolate;
-  const IsolateStartEventMock({this.timestamp, this.isolate});
-}
-
-class IsolateRunnableEventMock implements M.IsolateRunnableEvent {
-  final DateTime timestamp;
-  final M.IsolateRef isolate;
-  const IsolateRunnableEventMock({this.timestamp, this.isolate});
-}
-
-class IsolateExitEventMock implements M.IsolateExitEvent {
-  final DateTime timestamp;
-  final M.IsolateRef isolate;
-  const IsolateExitEventMock({this.timestamp, this.isolate});
-}
-
-class IsolateUpdateEventMock implements M.IsolateUpdateEvent {
-  final DateTime timestamp;
-  final M.IsolateRef isolate;
-  const IsolateUpdateEventMock({this.timestamp, this.isolate});
-}
-
-class IsolateRealodEventMock implements M.IsolateReloadEvent {
-  final DateTime timestamp;
-  final M.IsolateRef isolate;
-  final M.Error error;
-  const IsolateRealodEventMock({this.timestamp, this.isolate, this.error});
-}
-
-class ServiceExtensionAddedEventMock implements M.ServiceExtensionAddedEvent {
-  final DateTime timestamp;
-  final M.IsolateRef isolate;
-  final String extensionRPC;
-  const ServiceExtensionAddedEventMock(
-      {this.extensionRPC, this.isolate, this.timestamp});
-}
-
-class DebuggerSettingsUpdateEventMock implements M.PauseStartEvent {
-  final DateTime timestamp;
-  final M.IsolateRef isolate;
-  const DebuggerSettingsUpdateEventMock({this.isolate, this.timestamp});
-}
-
-class PauseStartEventMock implements M.PauseStartEvent {
-  final DateTime timestamp;
-  final M.IsolateRef isolate;
-  const PauseStartEventMock({this.isolate, this.timestamp});
-}
-
-class PauseExitEventMock implements M.PauseExitEvent {
-  final DateTime timestamp;
-  final M.IsolateRef isolate;
-  const PauseExitEventMock({this.isolate, this.timestamp});
-}
-
-class PauseBreakpointEventMock implements M.PauseBreakpointEvent {
-  final DateTime timestamp;
-  final M.IsolateRef isolate;
-  final M.Breakpoint breakpoint;
-  final List<M.Breakpoint> pauseBreakpoints;
-  final M.Frame topFrame;
-  final bool atAsyncSuspension;
-  const PauseBreakpointEventMock(
-      {this.timestamp,
-      this.isolate,
-      this.breakpoint,
-      this.pauseBreakpoints,
-      this.topFrame,
-      this.atAsyncSuspension});
-}
-
-class PauseInterruptedEventMock implements M.PauseInterruptedEvent {
-  final DateTime timestamp;
-  final M.IsolateRef isolate;
-  final M.Frame topFrame;
-  final bool atAsyncSuspension;
-  const PauseInterruptedEventMock(
-      {this.timestamp, this.isolate, this.topFrame, this.atAsyncSuspension});
-}
-
-class PauseExceptionEventMock implements M.PauseExceptionEvent {
-  final DateTime timestamp;
-  final M.IsolateRef isolate;
-  final M.Frame topFrame;
-  final M.InstanceRef exception;
-  const PauseExceptionEventMock(
-      {this.timestamp, this.isolate, this.topFrame, this.exception});
-}
-
-class ResumeEventMock implements M.ResumeEvent {
-  final DateTime timestamp;
-  final M.IsolateRef isolate;
-  final M.Frame topFrame;
-  const ResumeEventMock({this.timestamp, this.isolate, this.topFrame});
-}
-
-class BreakpointAddedEventMock implements M.BreakpointAddedEvent {
-  final DateTime timestamp;
-  final M.IsolateRef isolate;
-  final M.Breakpoint breakpoint;
-  const BreakpointAddedEventMock(
-      {this.timestamp, this.isolate, this.breakpoint});
-}
-
-class BreakpointResolvedEventMock implements M.BreakpointResolvedEvent {
-  final DateTime timestamp;
-  final M.IsolateRef isolate;
-  final M.Breakpoint breakpoint;
-  const BreakpointResolvedEventMock(
-      {this.timestamp, this.isolate, this.breakpoint});
-}
-
-class BreakpointRemovedEventMock implements M.BreakpointRemovedEvent {
-  final DateTime timestamp;
-  final M.IsolateRef isolate;
-  final M.Breakpoint breakpoint;
-  const BreakpointRemovedEventMock(
-      {this.timestamp, this.isolate, this.breakpoint});
-}
-
-class InspectEventMock implements M.InspectEvent {
-  final DateTime timestamp;
-  final M.IsolateRef isolate;
-  final M.InstanceRef inspectee;
-  const InspectEventMock({this.timestamp, this.isolate, this.inspectee});
-}
-
-class NoneEventMock implements M.NoneEvent {
-  final DateTime timestamp;
-  final M.IsolateRef isolate;
-  const NoneEventMock({this.timestamp, this.isolate});
-}
-
-class GCEventMock implements M.GCEvent {
-  final DateTime timestamp;
-  final M.IsolateRef isolate;
-  const GCEventMock({this.timestamp, this.isolate});
-}
-
-class ExtensionEventMock implements M.ExtensionEvent {
-  final DateTime timestamp;
-  final M.IsolateRef isolate;
-  final String extensionKind;
-  final M.ExtensionData extensionData;
-  const ExtensionEventMock(
-      {this.timestamp, this.isolate, this.extensionKind, this.extensionData});
-}
-
-class TimelineEventsEventMock implements M.TimelineEventsEvent {
-  final DateTime timestamp;
-  final M.IsolateRef isolate;
-  final List<M.TimelineEvent> timelineEvents;
-  const TimelineEventsEventMock(
-      {this.timestamp, this.isolate, this.timelineEvents});
-}
-
-class ConnectionClockedEventMock implements M.ConnectionClosedEvent {
-  final DateTime timestamp;
-  final String reason;
-  const ConnectionClockedEventMock({this.timestamp, this.reason});
-}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/objects/field.dart b/runtime/observatory/tests/observatory_ui/mocks/objects/field.dart
deleted file mode 100644
index ec3b8f5..0000000
--- a/runtime/observatory/tests/observatory_ui/mocks/objects/field.dart
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file
-
-part of mocks;
-
-class FieldRefMock implements M.FieldRef {
-  final String id;
-  final String name;
-  final M.ObjectRef dartOwner;
-  final M.InstanceRef declaredType;
-  final bool isConst;
-  final bool isFinal;
-  final bool isStatic;
-
-  const FieldRefMock(
-      {this.id: 'field-id',
-      this.name: 'field-name',
-      this.dartOwner,
-      this.declaredType: const InstanceRefMock(name: 'dynamic'),
-      this.isConst: false,
-      this.isFinal: false,
-      this.isStatic: false});
-}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/objects/flag.dart b/runtime/observatory/tests/observatory_ui/mocks/objects/flag.dart
deleted file mode 100644
index 1b250ff..0000000
--- a/runtime/observatory/tests/observatory_ui/mocks/objects/flag.dart
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file
-
-part of mocks;
-
-class FlagMock implements M.Flag {
-  final String name;
-  final String comment;
-  final bool modified;
-  final String valueAsString;
-
-  const FlagMock({this.name, this.comment, this.modified, this.valueAsString});
-}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/objects/function.dart b/runtime/observatory/tests/observatory_ui/mocks/objects/function.dart
deleted file mode 100644
index 00f3ca5..0000000
--- a/runtime/observatory/tests/observatory_ui/mocks/objects/function.dart
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-part of mocks;
-
-class FunctionRefMock implements M.FunctionRef {
-  final String id;
-  final String name;
-  final M.ObjectRef dartOwner;
-  final bool isStatic;
-  final bool isConst;
-  final M.FunctionKind kind;
-
-  const FunctionRefMock(
-      {this.id,
-      this.name,
-      this.dartOwner,
-      this.isStatic: false,
-      this.isConst: false,
-      this.kind});
-}
-
-class FunctionMock implements M.ServiceFunction {
-  final String id;
-  final String name;
-  final M.ClassRef clazz;
-  final int size;
-  final M.ObjectRef dartOwner;
-  final bool isStatic;
-  final bool isConst;
-  final M.FunctionKind kind;
-  final M.SourceLocation location;
-  final M.CodeRef code;
-  final M.CodeRef unoptimizedCode;
-  final M.CodeRef bytecode;
-  final M.FieldRef field;
-  final int usageCounter;
-  final M.InstanceRef icDataArray;
-  final int deoptimizations;
-  final bool isOptimizable;
-  final bool isInlinable;
-  final bool hasIntrinsic;
-  final bool isRecognized;
-  final bool isNative;
-  final String vmName;
-  const FunctionMock({
-    this.id,
-    this.name,
-    this.clazz,
-    this.size,
-    this.dartOwner,
-    this.isStatic: false,
-    this.isConst: false,
-    this.kind,
-    this.location,
-    this.code,
-    this.unoptimizedCode,
-    this.bytecode,
-    this.field,
-    this.usageCounter: 0,
-    this.icDataArray: const InstanceRefMock(),
-    this.deoptimizations: 0,
-    this.isOptimizable: false,
-    this.isInlinable: false,
-    this.hasIntrinsic: false,
-    this.isRecognized: false,
-    this.isNative: false,
-    this.vmName: 'function-vm-name',
-  });
-}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/objects/guarded.dart b/runtime/observatory/tests/observatory_ui/mocks/objects/guarded.dart
deleted file mode 100644
index 8e4ccc0..0000000
--- a/runtime/observatory/tests/observatory_ui/mocks/objects/guarded.dart
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-part of mocks;
-
-class GuardedMock<T> implements M.Guarded<T> {
-  bool get isSentinel => asSentinel != null;
-  bool get isValue => asValue != null;
-  final T asValue;
-  final M.Sentinel asSentinel;
-
-  const GuardedMock.fromValue(this.asValue) : asSentinel = null;
-
-  const GuardedMock.fromSentinel(this.asSentinel) : asValue = null;
-}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/objects/heap_snapshot.dart b/runtime/observatory/tests/observatory_ui/mocks/objects/heap_snapshot.dart
deleted file mode 100644
index 0b32af1..0000000
--- a/runtime/observatory/tests/observatory_ui/mocks/objects/heap_snapshot.dart
+++ /dev/null
@@ -1,81 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-part of mocks;
-
-class HeapSnapshotMock implements M.HeapSnapshot {
-  final DateTime timestamp;
-  final int objects;
-  final int references;
-  final int size;
-  final M.HeapSnapshotDominatorNode dominatorTree;
-  final M.HeapSnapshotMergedDominatorNode mergedDominatorTree = null;
-  final Iterable<M.HeapSnapshotClassReferences> classReferences;
-  final Iterable<M.HeapSnapshotOwnershipClass> ownershipClasses;
-
-  const HeapSnapshotMock(
-      {this.timestamp,
-      this.objects: 0,
-      this.references: 0,
-      this.size: 0,
-      this.dominatorTree: const HeapSnapshotDominatorNodeMock(),
-      this.classReferences: const [],
-      this.ownershipClasses: const []});
-}
-
-class HeapSnapshotDominatorNodeMock implements M.HeapSnapshotDominatorNode {
-  final int shallowSize;
-  final int retainedSize;
-  final bool isStack = false;
-  final Future<M.ObjectRef> object;
-  final Iterable<M.HeapSnapshotDominatorNode> children;
-
-  const HeapSnapshotDominatorNodeMock(
-      {this.shallowSize: 1,
-      this.retainedSize: 1,
-      this.object,
-      this.children: const []});
-}
-
-class HeapSnapshotClassReferencesMock implements M.HeapSnapshotClassReferences {
-  final M.ClassRef clazz;
-  final int instances;
-  final int shallowSize;
-  final int retainedSize;
-  final Iterable<M.HeapSnapshotClassInbound> inbounds;
-  final Iterable<M.HeapSnapshotClassOutbound> outbounds;
-
-  const HeapSnapshotClassReferencesMock(
-      {this.clazz: const ClassRefMock(),
-      this.instances: 1,
-      this.shallowSize: 1,
-      this.retainedSize: 2,
-      this.inbounds: const [],
-      this.outbounds: const []});
-}
-
-class HeapSnapshotClassInboundMock implements M.HeapSnapshotClassInbound {
-  final M.ClassRef source;
-  final int count;
-  final int shallowSize;
-  final int retainedSize;
-
-  const HeapSnapshotClassInboundMock(
-      {this.source: const ClassRefMock(),
-      this.count: 1,
-      this.shallowSize: 1,
-      this.retainedSize: 2});
-}
-
-class HeapSnapshotClassOutboundMock implements M.HeapSnapshotClassOutbound {
-  final M.ClassRef target;
-  final int count;
-  final int shallowSize;
-  final int retainedSize;
-  const HeapSnapshotClassOutboundMock(
-      {this.target: const ClassRefMock(),
-      this.count: 1,
-      this.shallowSize: 1,
-      this.retainedSize: 2});
-}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/objects/heap_space.dart b/runtime/observatory/tests/observatory_ui/mocks/objects/heap_space.dart
deleted file mode 100644
index da930a1..0000000
--- a/runtime/observatory/tests/observatory_ui/mocks/objects/heap_space.dart
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-part of mocks;
-
-class HeapSpaceMock implements M.HeapSpace {
-  final int used;
-  final int capacity;
-  final int collections;
-  final int external;
-  final Duration avgCollectionTime;
-  final Duration totalCollectionTime;
-  final Duration avgCollectionPeriod;
-  const HeapSpaceMock(
-      {this.used: 0,
-      this.capacity: 1,
-      this.collections: 0,
-      this.external: 1,
-      this.avgCollectionTime: const Duration(),
-      this.totalCollectionTime: const Duration(),
-      this.avgCollectionPeriod: const Duration()});
-}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/objects/icdata.dart b/runtime/observatory/tests/observatory_ui/mocks/objects/icdata.dart
deleted file mode 100644
index d1474e3..0000000
--- a/runtime/observatory/tests/observatory_ui/mocks/objects/icdata.dart
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-part of mocks;
-
-class ICDataRefMock implements M.ICDataRef {
-  final String id;
-  final String selector;
-
-  const ICDataRefMock({this.id: 'icdata-id', this.selector});
-}
-
-class ICDataMock implements M.ICData {
-  final String id;
-  final M.ClassRef clazz;
-  final String vmName;
-  final int size;
-  final String selector;
-  final M.ObjectRef dartOwner;
-  final M.InstanceRef argumentsDescriptor;
-  final M.InstanceRef entries;
-
-  const ICDataMock(
-      {this.id: 'icdata-id',
-      this.vmName: 'icdata-vmName',
-      this.clazz: const ClassRefMock(),
-      this.size: 0,
-      this.selector,
-      this.dartOwner,
-      this.argumentsDescriptor,
-      this.entries});
-}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/objects/inbound_references.dart b/runtime/observatory/tests/observatory_ui/mocks/objects/inbound_references.dart
deleted file mode 100644
index 34f0479..0000000
--- a/runtime/observatory/tests/observatory_ui/mocks/objects/inbound_references.dart
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-part of mocks;
-
-class InboundReferencesMock implements M.InboundReferences {
-  final Iterable<M.InboundReference> elements;
-
-  const InboundReferencesMock({this.elements: const []});
-}
-
-class InboundReferenceMock implements M.InboundReference {
-  final M.ObjectRef source;
-  final M.ObjectRef parentField;
-  final int parentListIndex;
-  final int parentWordOffset;
-
-  const InboundReferenceMock(
-      {this.source: const InstanceRefMock(),
-      this.parentField,
-      this.parentListIndex,
-      this.parentWordOffset});
-}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/objects/instance.dart b/runtime/observatory/tests/observatory_ui/mocks/objects/instance.dart
deleted file mode 100644
index df07d2c..0000000
--- a/runtime/observatory/tests/observatory_ui/mocks/objects/instance.dart
+++ /dev/null
@@ -1,113 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-part of mocks;
-
-class InstanceRefMock implements M.InstanceRef {
-  final String id;
-  final String name;
-  final M.InstanceKind kind;
-  final M.ClassRef clazz;
-  final String valueAsString;
-  final bool valueAsStringIsTruncated;
-  final int length;
-  final M.ClassRef typeClass;
-  final M.ClassRef parameterizedClass;
-  final M.InstanceRef pattern;
-  final M.FunctionRef closureFunction;
-  final M.ContextRef closureContext;
-
-  const InstanceRefMock(
-      {this.id: 'instance-id',
-      this.name: 'instance-name',
-      this.kind: M.InstanceKind.vNull,
-      this.clazz,
-      this.valueAsString: 'null',
-      this.valueAsStringIsTruncated,
-      this.length,
-      this.typeClass,
-      this.parameterizedClass,
-      this.pattern,
-      this.closureFunction,
-      this.closureContext});
-}
-
-class InstanceMock implements M.Instance {
-  final String id;
-  final String name;
-  final String vmName;
-  final M.InstanceKind kind;
-  final M.ClassRef clazz;
-  final int size;
-  final String valueAsString;
-  final bool valueAsStringIsTruncated;
-  final int length;
-  final M.ClassRef typeClass;
-  final M.ClassRef parameterizedClass;
-  final M.InstanceRef pattern;
-  final M.FunctionRef closureFunction;
-  final M.ContextRef closureContext;
-  final int offset;
-  final int count;
-  final List<dynamic> typedElements;
-  final Iterable<M.BoundField> fields;
-  final Iterable<M.NativeField> nativeFields;
-  final Iterable<M.Guarded<M.ObjectRef>> elements;
-  final Iterable<M.MapAssociation> associations;
-  final M.InstanceRef key;
-  final M.InstanceRef value;
-  final M.InstanceRef referent;
-  final M.TypeArguments typeArguments;
-  final int parameterIndex;
-  final M.InstanceRef targetType;
-  final M.InstanceRef bound;
-  final M.Breakpoint activationBreakpoint;
-  final bool isCaseSensitive;
-  final bool isMultiLine;
-  final M.FunctionRef oneByteFunction;
-  final M.FunctionRef twoByteFunction;
-  final M.FunctionRef externalOneByteFunction;
-  final M.FunctionRef externalTwoByteFunction;
-  final M.InstanceRef oneByteBytecode;
-  final M.InstanceRef twoByteBytecode;
-
-  const InstanceMock(
-      {this.id: 'instance-id',
-      this.name: 'instance-name',
-      this.vmName: 'instance-vmName',
-      this.kind: M.InstanceKind.vNull,
-      this.clazz: const ClassRefMock(),
-      this.size: 0,
-      this.valueAsString: 'null',
-      this.valueAsStringIsTruncated,
-      this.length,
-      this.typeClass,
-      this.parameterizedClass,
-      this.pattern,
-      this.closureFunction,
-      this.closureContext,
-      this.offset,
-      this.count,
-      this.typedElements,
-      this.fields,
-      this.nativeFields,
-      this.elements,
-      this.associations,
-      this.key,
-      this.value,
-      this.referent,
-      this.typeArguments,
-      this.parameterIndex,
-      this.targetType,
-      this.bound,
-      this.activationBreakpoint,
-      this.isCaseSensitive,
-      this.isMultiLine,
-      this.oneByteFunction,
-      this.twoByteFunction,
-      this.externalOneByteFunction,
-      this.externalTwoByteFunction,
-      this.oneByteBytecode,
-      this.twoByteBytecode});
-}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/objects/isolate.dart b/runtime/observatory/tests/observatory_ui/mocks/objects/isolate.dart
deleted file mode 100644
index 310e8fb..0000000
--- a/runtime/observatory/tests/observatory_ui/mocks/objects/isolate.dart
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-part of mocks;
-
-class IsolateRefMock implements M.IsolateRef {
-  final String id;
-  final int number;
-  final String name;
-
-  const IsolateRefMock({this.id: 'i-id', this.number, this.name: 'i-name'});
-
-  Future collectAllGarbage() async {
-    throw "Unimplemented";
-  }
-}
-
-class IsolateMock implements M.Isolate {
-  final String id;
-  final int number;
-  final String name;
-  final DateTime startTime;
-  final bool runnable;
-  final Iterable<M.LibraryRef> libraries;
-  final M.Error error;
-  final Iterable<String> extensionRPCs;
-  final Map counters;
-  final M.HeapSpace newSpace;
-  final M.HeapSpace oldSpace;
-  final M.IsolateStatus status;
-  final M.DebugEvent pauseEvent;
-  final M.LibraryRef rootLibrary;
-  final M.FunctionRef entry;
-  final Iterable<M.Thread> threads = null;
-  final int zoneHighWatermark = 0;
-  final int numZoneHandles = 0;
-  final int numScopedHandles = 0;
-
-  const IsolateMock(
-      {this.id: 'i-id',
-      this.number,
-      this.name: 'i-name',
-      this.startTime,
-      this.runnable: true,
-      this.libraries: const [],
-      this.error,
-      this.extensionRPCs: const [],
-      this.counters: const {},
-      this.newSpace: const HeapSpaceMock(),
-      this.oldSpace: const HeapSpaceMock(),
-      this.status: M.IsolateStatus.loading,
-      this.pauseEvent,
-      this.rootLibrary,
-      this.entry});
-
-  Future collectAllGarbage() async {
-    throw "Unimplemented";
-  }
-}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/objects/library.dart b/runtime/observatory/tests/observatory_ui/mocks/objects/library.dart
deleted file mode 100644
index 4d4f67f..0000000
--- a/runtime/observatory/tests/observatory_ui/mocks/objects/library.dart
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-part of mocks;
-
-class LibraryRefMock implements M.LibraryRef {
-  final String id;
-  final String name;
-  final String uri;
-  const LibraryRefMock({this.id, this.name, this.uri});
-}
-
-class LibraryMock implements M.Library {
-  final String id;
-  final String name;
-  final String vmName;
-  final M.ClassRef clazz;
-  final int size;
-  final String uri;
-  final bool debuggable;
-  final Iterable<M.LibraryDependency> dependencies;
-  final Iterable<M.ScriptRef> scripts;
-  final Iterable<M.ClassRef> classes;
-  final Iterable<M.FieldRef> variables;
-  final Iterable<M.FunctionRef> functions;
-  final M.ScriptRef rootScript;
-
-  const LibraryMock(
-      {this.id: 'library-id',
-      this.name: 'library-name',
-      this.vmName: 'library-vmName',
-      this.clazz,
-      this.size,
-      this.uri,
-      this.debuggable,
-      this.dependencies: const [],
-      this.scripts: const [],
-      this.classes: const [],
-      this.variables: const [],
-      this.functions: const [],
-      this.rootScript: const ScriptRefMock()});
-}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/objects/local_var_descriptors.dart b/runtime/observatory/tests/observatory_ui/mocks/objects/local_var_descriptors.dart
deleted file mode 100644
index b60e505..0000000
--- a/runtime/observatory/tests/observatory_ui/mocks/objects/local_var_descriptors.dart
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-part of mocks;
-
-class LocalVarDescriptorsRefMock implements M.LocalVarDescriptorsRef {
-  final String id;
-  final String name;
-  const LocalVarDescriptorsRefMock(
-      {this.id: 'local-var-id', this.name: 'local_var_name'});
-}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/objects/megamorphiccache.dart b/runtime/observatory/tests/observatory_ui/mocks/objects/megamorphiccache.dart
deleted file mode 100644
index 4e077f2..0000000
--- a/runtime/observatory/tests/observatory_ui/mocks/objects/megamorphiccache.dart
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-part of mocks;
-
-class MegamorphicCacheRefMock implements M.MegamorphicCacheRef {
-  final String id;
-  final String selector;
-
-  const MegamorphicCacheRefMock(
-      {this.id: 'megamorphiccache-id', this.selector: 'selector'});
-}
-
-class MegamorphicCacheMock implements M.MegamorphicCache {
-  final String id;
-  final M.ClassRef clazz;
-  final String vmName;
-  final int size;
-  final String selector;
-  final int mask;
-  final M.InstanceRef buckets;
-  final M.InstanceRef argumentsDescriptor;
-
-  const MegamorphicCacheMock(
-      {this.id: 'megamorphiccache-id',
-      this.vmName: 'megamorphiccache-vmName',
-      this.clazz: const ClassRefMock(),
-      this.size: 1,
-      this.selector: 'selector',
-      this.mask: 0,
-      this.buckets: const InstanceRefMock(),
-      this.argumentsDescriptor: const InstanceRefMock()});
-}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/objects/notification.dart b/runtime/observatory/tests/observatory_ui/mocks/objects/notification.dart
deleted file mode 100644
index d452cee..0000000
--- a/runtime/observatory/tests/observatory_ui/mocks/objects/notification.dart
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-part of mocks;
-
-class ExceptionNotificationMock implements M.ExceptionNotification {
-  final Exception exception;
-  final StackTrace stacktrace;
-  const ExceptionNotificationMock({this.exception, this.stacktrace});
-}
-
-class EventNotificationMock implements M.EventNotification {
-  final M.Event event;
-  const EventNotificationMock({this.event});
-}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/objects/objectpool.dart b/runtime/observatory/tests/observatory_ui/mocks/objects/objectpool.dart
deleted file mode 100644
index 3b6c115..0000000
--- a/runtime/observatory/tests/observatory_ui/mocks/objects/objectpool.dart
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-part of mocks;
-
-class ObjectPoolRefMock implements M.ObjectPoolRef {
-  final String id;
-  final int length;
-
-  const ObjectPoolRefMock({this.id: 'objectpool-id', this.length: 0});
-}
-
-class ObjectPoolMock implements M.ObjectPool {
-  final String id;
-  final M.ClassRef clazz;
-  final String vmName;
-  final int size;
-  final int length;
-  final Iterable<M.ObjectPoolEntry> entries;
-
-  const ObjectPoolMock(
-      {this.id: 'objectpool-id',
-      this.vmName: 'objpool-vmName',
-      this.clazz: const ClassRefMock(),
-      this.size: 1,
-      this.length: 0,
-      this.entries: const []});
-}
-
-class ObjectPoolEntryMock implements M.ObjectPoolEntry {
-  final int offset;
-  final M.ObjectPoolEntryKind kind;
-  final M.ObjectRef asObject;
-  final int asInteger;
-
-  const ObjectPoolEntryMock(
-      {this.offset: 0,
-      this.kind: M.ObjectPoolEntryKind.object,
-      this.asObject: const InstanceRefMock(),
-      this.asInteger: null});
-}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/objects/objectstore.dart b/runtime/observatory/tests/observatory_ui/mocks/objects/objectstore.dart
deleted file mode 100644
index 7cd62a7..0000000
--- a/runtime/observatory/tests/observatory_ui/mocks/objects/objectstore.dart
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-part of mocks;
-
-class ObjectStoreMock implements M.ObjectStore {
-  final Iterable<M.NamedField> fields;
-
-  const ObjectStoreMock({this.fields: const []});
-}
-
-class NamedFieldMock implements M.NamedField {
-  final String name;
-  final M.ObjectRef value;
-
-  const NamedFieldMock(
-      {this.name: 'field-name', this.value: const InstanceRefMock()});
-}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/objects/pc_descriptors.dart b/runtime/observatory/tests/observatory_ui/mocks/objects/pc_descriptors.dart
deleted file mode 100644
index 563704c..0000000
--- a/runtime/observatory/tests/observatory_ui/mocks/objects/pc_descriptors.dart
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-part of mocks;
-
-class PcDescriptorsRefMock implements M.PcDescriptorsRef {
-  final String id;
-  final String name;
-
-  const PcDescriptorsRefMock(
-      {this.id: 'pcdescriptors-id', this.name: 'pcdescriptors-name'});
-}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/objects/persistent_handles.dart b/runtime/observatory/tests/observatory_ui/mocks/objects/persistent_handles.dart
deleted file mode 100644
index 6926449..0000000
--- a/runtime/observatory/tests/observatory_ui/mocks/objects/persistent_handles.dart
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-part of mocks;
-
-class PersistentHandlesMock implements M.PersistentHandles {
-  final Iterable<M.PersistentHandle> elements;
-  final Iterable<M.WeakPersistentHandle> weakElements;
-
-  const PersistentHandlesMock(
-      {this.elements: const [], this.weakElements: const []});
-}
-
-class PersistentHandleMock implements M.PersistentHandle {
-  final M.ObjectRef object;
-
-  const PersistentHandleMock({this.object: const InstanceRefMock()});
-}
-
-class WeakPersistentHandleMock implements M.WeakPersistentHandle {
-  final M.ObjectRef object;
-  final int externalSize;
-  final String peer;
-  final String callbackSymbolName;
-  final String callbackAddress;
-
-  const WeakPersistentHandleMock(
-      {this.object: const InstanceRefMock(),
-      this.externalSize: 0,
-      this.peer: '0x0',
-      this.callbackSymbolName: 'dart::Something()',
-      this.callbackAddress: '0x123456'});
-}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/objects/ports.dart b/runtime/observatory/tests/observatory_ui/mocks/objects/ports.dart
deleted file mode 100644
index 2149a4f..0000000
--- a/runtime/observatory/tests/observatory_ui/mocks/objects/ports.dart
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-part of mocks;
-
-class PortsAndHandlesMock implements M.Ports, M.PersistentHandles {
-  final Iterable<PortMock> elements;
-
-  const PortsAndHandlesMock({this.elements: const []});
-
-  @override
-  Iterable<M.WeakPersistentHandle> get weakElements =>
-      throw new UnimplementedError();
-}
-
-class PortMock implements M.Port, M.PersistentHandle {
-  final String name;
-  final M.ObjectRef handler;
-
-  const PortMock(
-      {this.name: 'port-name', this.handler: const InstanceRefMock()});
-
-  @override
-  M.ObjectRef get object => throw new UnimplementedError();
-}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/objects/retaining_path.dart b/runtime/observatory/tests/observatory_ui/mocks/objects/retaining_path.dart
deleted file mode 100644
index 36b7b68..0000000
--- a/runtime/observatory/tests/observatory_ui/mocks/objects/retaining_path.dart
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-part of mocks;
-
-class RetainingPathMock implements M.RetainingPath {
-  final Iterable<M.RetainingPathItem> elements;
-
-  const RetainingPathMock({this.elements: const []});
-}
-
-class RetainingPathItemMock implements M.RetainingPathItem {
-  final M.ObjectRef source;
-  final M.ObjectRef parentField;
-  final int parentListIndex;
-  final int parentWordOffset;
-
-  const RetainingPathItemMock(
-      {this.source: const InstanceRefMock(),
-      this.parentField,
-      this.parentListIndex,
-      this.parentWordOffset});
-}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/objects/sample_profile.dart b/runtime/observatory/tests/observatory_ui/mocks/objects/sample_profile.dart
deleted file mode 100644
index 9dd386e..0000000
--- a/runtime/observatory/tests/observatory_ui/mocks/objects/sample_profile.dart
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file
-
-part of mocks;
-
-typedef M.FunctionCallTree SampleProfileMockLoadFunctionTreeCallback(
-    M.ProfileTreeDirection direction);
-typedef M.CodeCallTree SampleProfileMockLoadCodeTreeCallback(
-    M.ProfileTreeDirection direction);
-
-class SampleProfileMock implements M.SampleProfile {
-  final SampleProfileMockLoadFunctionTreeCallback _loadFunctionTree;
-  final SampleProfileMockLoadCodeTreeCallback _loadCodeTree;
-
-  final int sampleCount;
-  final int stackDepth;
-  final double sampleRate;
-  final double timeSpan;
-  final Iterable<M.ProfileCode> codes;
-  final Iterable<M.ProfileFunction> functions;
-
-  M.FunctionCallTree loadFunctionTree(M.ProfileTreeDirection direction) {
-    if (_loadFunctionTree != null) {
-      return _loadFunctionTree(direction);
-    }
-    return null;
-  }
-
-  M.CodeCallTree loadCodeTree(M.ProfileTreeDirection direction) {
-    if (_loadCodeTree != null) {
-      return _loadCodeTree(direction);
-    }
-    return null;
-  }
-
-  SampleProfileMock(
-      {this.sampleCount: 0,
-      this.stackDepth: 0,
-      this.sampleRate: 1.0,
-      this.timeSpan: 1.0,
-      this.codes: const [],
-      this.functions: const [],
-      SampleProfileMockLoadFunctionTreeCallback loadFunctionTree,
-      SampleProfileMockLoadCodeTreeCallback loadCodeTree})
-      : _loadFunctionTree = loadFunctionTree,
-        _loadCodeTree = loadCodeTree;
-}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/objects/script.dart b/runtime/observatory/tests/observatory_ui/mocks/objects/script.dart
deleted file mode 100644
index 699ec59..0000000
--- a/runtime/observatory/tests/observatory_ui/mocks/objects/script.dart
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-part of mocks;
-
-class ScriptRefMock implements M.ScriptRef {
-  final String id;
-  final String uri;
-
-  const ScriptRefMock({this.id, this.uri});
-}
-
-typedef int TokenToInt(int token);
-
-class ScriptMock implements M.Script {
-  final String id;
-  final M.ClassRef clazz;
-  final String vmName;
-  final int size;
-  final String uri;
-  final String source;
-  final M.LibraryRef library;
-
-  final TokenToInt _tokenToLine;
-  final TokenToInt _tokenToCol;
-
-  final DateTime loadTime;
-  final int firstTokenPos;
-  final int lastTokenPos;
-  final int lineOffset;
-  final int columnOffset;
-
-  int tokenToLine(int token) => _tokenToLine(token);
-  int tokenToCol(int token) => _tokenToCol(token);
-
-  const ScriptMock(
-      {this.id: 'script-id',
-      this.vmName: 'script-vmNmae',
-      this.clazz,
-      this.size,
-      this.uri,
-      this.source,
-      this.library: const LibraryRefMock(),
-      TokenToInt tokenToLine,
-      TokenToInt tokenToCol,
-      this.loadTime,
-      this.firstTokenPos,
-      this.lastTokenPos,
-      this.lineOffset,
-      this.columnOffset})
-      : _tokenToLine = tokenToLine,
-        _tokenToCol = tokenToCol;
-}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/objects/sentinel.dart b/runtime/observatory/tests/observatory_ui/mocks/objects/sentinel.dart
deleted file mode 100644
index 8ca0b41..0000000
--- a/runtime/observatory/tests/observatory_ui/mocks/objects/sentinel.dart
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-part of mocks;
-
-class SentinelMock implements M.Sentinel {
-  final M.SentinelKind kind;
-  final String valueAsString;
-
-  const SentinelMock(
-      {this.kind: M.SentinelKind.collected,
-      this.valueAsString: 'sentinel-value'});
-}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/objects/source_location.dart b/runtime/observatory/tests/observatory_ui/mocks/objects/source_location.dart
deleted file mode 100644
index a795589..0000000
--- a/runtime/observatory/tests/observatory_ui/mocks/objects/source_location.dart
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-part of mocks;
-
-class SourceLocationMock implements M.SourceLocation {
-  final M.ScriptRef script;
-  final int tokenPos;
-  final int endTokenPos;
-
-  const SourceLocationMock({this.script, this.tokenPos, this.endTokenPos});
-}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/objects/target.dart b/runtime/observatory/tests/observatory_ui/mocks/objects/target.dart
deleted file mode 100644
index 0d15e5c..0000000
--- a/runtime/observatory/tests/observatory_ui/mocks/objects/target.dart
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-part of mocks;
-
-class TargetMock implements M.Target {
-  final String name;
-  const TargetMock({this.name});
-}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/objects/unknown.dart b/runtime/observatory/tests/observatory_ui/mocks/objects/unknown.dart
deleted file mode 100644
index 05730a3..0000000
--- a/runtime/observatory/tests/observatory_ui/mocks/objects/unknown.dart
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-part of mocks;
-
-class UnknownObjectRefMock implements M.UnknownObjectRef {
-  final String id;
-  final String vmType;
-  const UnknownObjectRefMock(
-      {this.id: 'literal-token-id', this.vmType: 'vmType'});
-}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/objects/vm.dart b/runtime/observatory/tests/observatory_ui/mocks/objects/vm.dart
deleted file mode 100644
index c19ba56..0000000
--- a/runtime/observatory/tests/observatory_ui/mocks/objects/vm.dart
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-part of mocks;
-
-class VMRefMock implements M.VMRef {
-  final String name;
-  final String displayName;
-  const VMRefMock({this.name: 'vm-name', this.displayName: 'vm-display-name'});
-}
-
-class VMMock implements M.VM {
-  final String name;
-  final String displayName;
-  final int architectureBits;
-  final String targetCPU;
-  final String hostCPU;
-  final String version;
-  final String embedder;
-  final int pid;
-  final int maxRSS;
-  final int currentRSS;
-  final DateTime startTime;
-  final Iterable<M.IsolateRef> isolates;
-  final int nativeZoneMemoryUsage = 0;
-  final int heapAllocatedMemoryUsage = 0;
-  final int heapAllocationCount = 0;
-
-  Future<dynamic> invokeRpc(String method, Map params) {
-    return null;
-  }
-
-  Future enableProfiler() {
-    return null;
-  }
-
-  const VMMock(
-      {this.name: 'vm-name',
-      this.displayName: 'vm-display-name',
-      this.architectureBits,
-      this.targetCPU,
-      this.hostCPU,
-      this.version,
-      this.embedder,
-      this.pid: 0,
-      this.maxRSS: 0,
-      this.currentRSS: 0,
-      this.startTime,
-      this.isolates: const []});
-}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/repositories/allocation_profile.dart b/runtime/observatory/tests/observatory_ui/mocks/repositories/allocation_profile.dart
deleted file mode 100644
index 8e9f278..0000000
--- a/runtime/observatory/tests/observatory_ui/mocks/repositories/allocation_profile.dart
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-part of mocks;
-
-typedef Future<
-    M
-        .AllocationProfile> AllocationProfileRepositoryMockGetterCallback(
-    M.Isolate id, bool gc, bool force, bool combine);
-
-class AllocationProfileRepositoryMock implements M.AllocationProfileRepository {
-  final AllocationProfileRepositoryMockGetterCallback _get;
-
-  AllocationProfileRepositoryMock(
-      {AllocationProfileRepositoryMockGetterCallback getter})
-      : _get = getter;
-
-  Future<M.AllocationProfile> get(M.IsolateRef id,
-      {bool gc: false, bool reset: false, bool combine: false}) {
-    if (_get != null) {
-      return _get(id, gc, reset, combine);
-    }
-    return new Future.value(null);
-  }
-}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/repositories/class.dart b/runtime/observatory/tests/observatory_ui/mocks/repositories/class.dart
deleted file mode 100644
index b798fca..0000000
--- a/runtime/observatory/tests/observatory_ui/mocks/repositories/class.dart
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-part of mocks;
-
-typedef Future<M.Class> ClassRepositoryMockObjectCallback(M.Isolate isolate);
-typedef Future<M.Class> ClassRepositoryMockGetterCallback(
-    M.Isolate isolate, String id);
-
-class ClassRepositoryMock implements M.ClassRepository {
-  final ClassRepositoryMockObjectCallback _object;
-  final ClassRepositoryMockGetterCallback _get;
-
-  ClassRepositoryMock(
-      {ClassRepositoryMockObjectCallback object,
-      ClassRepositoryMockGetterCallback getter})
-      : _object = object,
-        _get = getter;
-
-  Future<M.Class> getObject(M.IsolateRef i) {
-    if (_object != null) {
-      return _object(i);
-    }
-    return new Future.value(null);
-  }
-
-  Future<M.Class> get(M.IsolateRef i, String id) {
-    if (_get != null) {
-      return _get(i, id);
-    }
-    return new Future.value(null);
-  }
-}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/repositories/context.dart b/runtime/observatory/tests/observatory_ui/mocks/repositories/context.dart
deleted file mode 100644
index bf0c9e9..0000000
--- a/runtime/observatory/tests/observatory_ui/mocks/repositories/context.dart
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-part of mocks;
-
-typedef Future<M.Context> ContextRepositoryMockCallback(
-    M.IsolateRef isolate, String id);
-
-class ContextRepositoryMock implements M.ContextRepository {
-  final ContextRepositoryMockCallback _get;
-
-  ContextRepositoryMock({ContextRepositoryMockCallback getter}) : _get = getter;
-
-  Future<M.Context> get(M.IsolateRef isolate, String id) {
-    if (_get != null) {
-      return _get(isolate, id);
-    }
-    return new Future.value(null);
-  }
-}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/repositories/eval.dart b/runtime/observatory/tests/observatory_ui/mocks/repositories/eval.dart
deleted file mode 100644
index 0b7a072..0000000
--- a/runtime/observatory/tests/observatory_ui/mocks/repositories/eval.dart
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-part of mocks;
-
-typedef Future<M.Object> EvalRepositoryMockCallback(
-    M.IsolateRef isolate, M.ObjectRef context, String expression,
-    {bool disableBreakpoints});
-
-class EvalRepositoryMock implements M.EvalRepository {
-  final EvalRepositoryMockCallback _get;
-
-  EvalRepositoryMock({EvalRepositoryMockCallback getter}) : _get = getter;
-
-  Future<M.Object> evaluate(
-      M.IsolateRef isolate, M.ObjectRef context, String expression,
-      {bool disableBreakpoints: false}) {
-    if (_get != null) {
-      return _get(isolate, context, expression,
-          disableBreakpoints: disableBreakpoints);
-    }
-    return new Future.value(null);
-  }
-}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/repositories/event.dart b/runtime/observatory/tests/observatory_ui/mocks/repositories/event.dart
deleted file mode 100644
index 8b74218..0000000
--- a/runtime/observatory/tests/observatory_ui/mocks/repositories/event.dart
+++ /dev/null
@@ -1,209 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-part of mocks;
-
-class EventRepositoryMock implements M.EventRepository {
-  final _onEvent = new StreamController<M.Event>.broadcast();
-  Stream<M.Event> get onEvent => _onEvent.stream;
-  get onEventHasListener => _onEvent.hasListener;
-
-  final _onVMEvent = new StreamController<M.VMEvent>.broadcast();
-  Stream<M.VMEvent> get onVMEvent => _onVMEvent.stream;
-  get onVMEventHasListener => _onVMEvent.hasListener;
-
-  final _onVMUpdate = new StreamController<M.VMUpdateEvent>.broadcast();
-  Stream<M.VMUpdateEvent> get onVMUpdate => _onVMUpdate.stream;
-  get onVMUpdateHasListener => _onVMUpdate.hasListener;
-
-  final _onIsolateEvent = new StreamController<M.IsolateEvent>.broadcast();
-  Stream<M.IsolateEvent> get onIsolateEvent => _onIsolateEvent.stream;
-  get onIsolateEventHasListener => _onIsolateEvent.hasListener;
-
-  final _onIsolateStart = new StreamController<M.IsolateStartEvent>.broadcast();
-  Stream<M.IsolateStartEvent> get onIsolateStart => _onIsolateStart.stream;
-  get onIsolateStartHasListener => _onIsolateStart.hasListener;
-
-  final _onIsolateRunnable =
-      new StreamController<M.IsolateRunnableEvent>.broadcast();
-  Stream<M.IsolateRunnableEvent> get onIsolateRunnable =>
-      _onIsolateRunnable.stream;
-  get onIsolateRunnableHasListener => _onIsolateRunnable.hasListener;
-
-  final _onIsolateExit = new StreamController<M.IsolateExitEvent>.broadcast();
-  Stream<M.IsolateExitEvent> get onIsolateExit => _onIsolateExit.stream;
-  get onIsolateExitHasListener => _onIsolateExit.hasListener;
-
-  final _onIsolateUpdate =
-      new StreamController<M.IsolateUpdateEvent>.broadcast();
-  Stream<M.IsolateUpdateEvent> get onIsolateUpdate => _onIsolateUpdate.stream;
-  get onIsolateUpdateHasListener => _onIsolateUpdate.hasListener;
-
-  final _onIsolateReload =
-      new StreamController<M.IsolateReloadEvent>.broadcast();
-  Stream<M.IsolateReloadEvent> get onIsolateReload => _onIsolateReload.stream;
-  get onIsolateReloadHasListener => _onIsolateReload.hasListener;
-
-  final _onServiceExtensionAdded =
-      new StreamController<M.ServiceExtensionAddedEvent>.broadcast();
-  Stream<M.ServiceExtensionAddedEvent> get onServiceExtensionAdded =>
-      _onServiceExtensionAdded.stream;
-  get onServiceExtensionAddedHasListener =>
-      _onServiceExtensionAdded.hasListener;
-
-  final _onDebugEvent = new StreamController<M.DebugEvent>.broadcast();
-  Stream<M.DebugEvent> get onDebugEvent => _onDebugEvent.stream;
-  get onDebugEventHasListener => _onDebugEvent.hasListener;
-
-  final _onPauseStart = new StreamController<M.PauseStartEvent>.broadcast();
-  Stream<M.PauseStartEvent> get onPauseStart => _onPauseStart.stream;
-  get onPauseStartHasListener => _onPauseStart.hasListener;
-
-  final _onPauseExit = new StreamController<M.PauseExitEvent>.broadcast();
-  Stream<M.PauseExitEvent> get onPauseExit => _onPauseExit.stream;
-  get onPauseExitHasListener => _onPauseExit.hasListener;
-
-  final _onPauseBreakpoint =
-      new StreamController<M.PauseBreakpointEvent>.broadcast();
-  Stream<M.PauseBreakpointEvent> get onPauseBreakpoint =>
-      _onPauseBreakpoint.stream;
-  get onPauseBreakpointHasListener => _onPauseBreakpoint.hasListener;
-
-  final _onPauseInterrupted =
-      new StreamController<M.PauseInterruptedEvent>.broadcast();
-  Stream<M.PauseInterruptedEvent> get onPauseInterrupted =>
-      _onPauseInterrupted.stream;
-  get onPauseInterruptedHasListener => _onPauseInterrupted.hasListener;
-
-  final _onPauseException =
-      new StreamController<M.PauseExceptionEvent>.broadcast();
-  Stream<M.PauseExceptionEvent> get onPauseException =>
-      _onPauseException.stream;
-  get onPauseExceptionHasListener => _onPauseException.hasListener;
-
-  final _onResume = new StreamController<M.ResumeEvent>.broadcast();
-  Stream<M.ResumeEvent> get onResume => _onResume.stream;
-  get onResumeHasListener => _onResume.hasListener;
-
-  final _onBreakpointAdded =
-      new StreamController<M.BreakpointAddedEvent>.broadcast();
-  Stream<M.BreakpointAddedEvent> get onBreakpointAdded =>
-      _onBreakpointAdded.stream;
-  get onBreakpointAddedHasListener => _onBreakpointAdded.hasListener;
-
-  final _onBreakpointResolved =
-      new StreamController<M.BreakpointResolvedEvent>.broadcast();
-  Stream<M.BreakpointResolvedEvent> get onBreakpointResolved =>
-      _onBreakpointResolved.stream;
-  get onBreakpointResolvedHasListener => _onBreakpointResolved.hasListener;
-
-  final _onBreakpointRemoved =
-      new StreamController<M.BreakpointRemovedEvent>.broadcast();
-  Stream<M.BreakpointRemovedEvent> get onBreakpointRemoved =>
-      _onBreakpointRemoved.stream;
-  get onBreakpointRemovedHasListener => _onBreakpointRemoved.hasListener;
-
-  final _onInspect = new StreamController<M.InspectEvent>.broadcast();
-  Stream<M.InspectEvent> get onInspect => _onInspect.stream;
-  get onInspectHasListener => _onInspect.hasListener;
-
-  final _onGCEvent = new StreamController<M.GCEvent>.broadcast();
-  Stream<M.GCEvent> get onGCEvent => _onGCEvent.stream;
-  get onGCEventHasListener => _onGCEvent.hasListener;
-
-  final _onLoggingEvent = new StreamController<M.LoggingEvent>.broadcast();
-  Stream<M.LoggingEvent> get onLoggingEvent => _onLoggingEvent.stream;
-  get onLoggingEventHasListener => _onLoggingEvent.hasListener;
-
-  final _onExtensionEvent = new StreamController<M.ExtensionEvent>.broadcast();
-  Stream<M.ExtensionEvent> get onExtensionEvent => _onExtensionEvent.stream;
-  get onExtensionEventHasListener => _onExtensionEvent.hasListener;
-
-  final _onTimelineEvents =
-      new StreamController<M.TimelineEventsEvent>.broadcast();
-  Stream<M.TimelineEventsEvent> get onTimelineEvents =>
-      _onTimelineEvents.stream;
-  get onTimelineEventsEventHasListener => _onTimelineEvents.hasListener;
-
-  final _onConnectionClosed =
-      new StreamController<M.ConnectionClosedEvent>.broadcast();
-  Stream<M.ConnectionClosedEvent> get onConnectionClosed =>
-      _onConnectionClosed.stream;
-  get onConnectionClosedHasListener => _onConnectionClosed.hasListener;
-
-  final _onServiceEvent = new StreamController<M.ServiceEvent>.broadcast();
-  Stream<M.ServiceEvent> get onServiceEvent => _onServiceEvent.stream;
-  get onServiceEventHasListener => _onServiceEvent.hasListener;
-
-  final _onServiceRegistered =
-      new StreamController<M.ServiceRegisteredEvent>.broadcast();
-  Stream<M.ServiceRegisteredEvent> get onServiceRegistered =>
-      _onServiceRegistered.stream;
-  get onServiceRegisteredHasListener => _onServiceRegistered.hasListener;
-
-  final _onServiceUnregistered =
-      new StreamController<M.ServiceUnregisteredEvent>.broadcast();
-  Stream<M.ServiceUnregisteredEvent> get onServiceUnregistered =>
-      _onServiceUnregistered.stream;
-  get onServiceUnregisteredHasListener => _onServiceUnregistered.hasListener;
-
-  void add(M.Event event) {
-    _onEvent.add(event);
-    if (event is M.VMEvent) {
-      _onVMEvent.add(event);
-      if (event is M.VMUpdateEvent) {
-        _onVMUpdate.add(event);
-      }
-    } else if (event is M.IsolateEvent) {
-      _onIsolateEvent.add(event);
-      if (event is M.IsolateStartEvent) {
-        _onIsolateStart.add(event);
-      } else if (event is M.IsolateRunnableEvent) {
-        _onIsolateRunnable.add(event);
-      } else if (event is M.IsolateExitEvent) {
-        _onIsolateExit.add(event);
-      } else if (event is M.IsolateUpdateEvent) {
-        _onIsolateUpdate.add(event);
-      } else if (event is M.ServiceExtensionAddedEvent) {
-        _onServiceExtensionAdded.add(event);
-      }
-    } else if (event is M.DebugEvent) {
-      _onDebugEvent.add(event);
-      if (event is M.PauseStartEvent) {
-        _onPauseStart.add(event);
-      } else if (event is M.PauseExitEvent) {
-        _onPauseExit.add(event);
-      } else if (event is M.PauseBreakpointEvent) {
-        _onPauseBreakpoint.add(event);
-      } else if (event is M.PauseInterruptedEvent) {
-        _onPauseInterrupted.add(event);
-      } else if (event is M.PauseExceptionEvent) {
-        _onPauseException.add(event);
-      } else if (event is M.ResumeEvent) {
-        _onResume.add(event);
-      } else if (event is M.BreakpointAddedEvent) {
-        _onBreakpointAdded.add(event);
-      } else if (event is M.BreakpointResolvedEvent) {
-        _onBreakpointResolved.add(event);
-      } else if (event is M.BreakpointRemovedEvent) {
-        _onBreakpointRemoved.add(event);
-      } else if (event is M.InspectEvent) {
-        _onInspect.add(event);
-      }
-    } else if (event is M.GCEvent) {
-      _onGCEvent.add(event);
-    } else if (event is M.ExtensionEvent) {
-      _onExtensionEvent.add(event);
-    } else if (event is M.TimelineEventsEvent) {
-      _onTimelineEvents.add(event);
-    } else if (event is M.ServiceEvent) {
-      _onServiceEvent.add(event);
-      if (event is M.ServiceRegisteredEvent) {
-        _onServiceRegistered.add(event);
-      } else if (event is M.ServiceUnregisteredEvent) {
-        _onServiceUnregistered.add(event);
-      }
-    }
-  }
-}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/repositories/field.dart b/runtime/observatory/tests/observatory_ui/mocks/repositories/field.dart
deleted file mode 100644
index 8e8a038..0000000
--- a/runtime/observatory/tests/observatory_ui/mocks/repositories/field.dart
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-part of mocks;
-
-typedef Future<M.Field> FieldRepositoryMockCallback(
-    M.IsolateRef isolate, String id);
-
-class FieldRepositoryMock implements M.FieldRepository {
-  final FieldRepositoryMockCallback _get;
-
-  FieldRepositoryMock({FieldRepositoryMockCallback getter}) : _get = getter;
-
-  Future<M.Field> get(M.IsolateRef isolate, String id) {
-    if (_get != null) {
-      return _get(isolate, id);
-    }
-    return new Future.value(null);
-  }
-}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/repositories/flag.dart b/runtime/observatory/tests/observatory_ui/mocks/repositories/flag.dart
deleted file mode 100644
index 578c034..0000000
--- a/runtime/observatory/tests/observatory_ui/mocks/repositories/flag.dart
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file
-
-part of mocks;
-
-class FlagsRepositoryMock implements M.FlagsRepository {
-  final Iterable<M.Flag> _list;
-  bool isListInvoked = false;
-
-  Future<Iterable<M.Flag>> list() async {
-    await null;
-    isListInvoked = true;
-    return _list;
-  }
-
-  FlagsRepositoryMock({Iterable<M.Flag> list: const []})
-      : _list = new List.unmodifiable(list);
-}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/repositories/heap_snapshot.dart b/runtime/observatory/tests/observatory_ui/mocks/repositories/heap_snapshot.dart
deleted file mode 100644
index de7dec0..0000000
--- a/runtime/observatory/tests/observatory_ui/mocks/repositories/heap_snapshot.dart
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file
-
-part of mocks;
-
-class HeapSnapshotLoadingProgressEventMock
-    implements M.HeapSnapshotLoadingProgressEvent {
-  final M.HeapSnapshotLoadingProgress progress;
-
-  const HeapSnapshotLoadingProgressEventMock(
-      {this.progress: const HeapSnapshotLoadingProgressMock()});
-}
-
-class HeapSnapshotLoadingProgressMock implements M.HeapSnapshotLoadingProgress {
-  final M.HeapSnapshotLoadingStatus status;
-  final String stepDescription;
-  final double progress;
-  final Duration fetchingTime;
-  final Duration loadingTime;
-  final M.HeapSnapshot snapshot;
-
-  const HeapSnapshotLoadingProgressMock(
-      {this.status: M.HeapSnapshotLoadingStatus.fetching,
-      this.progress: 0.0,
-      this.stepDescription: '',
-      this.fetchingTime,
-      this.loadingTime,
-      this.snapshot});
-}
-
-typedef Stream<
-    M
-        .HeapSnapshotLoadingProgressEvent> HeapSnapshotRepositoryMockCallback(
-    M.IsolateRef cls, bool gc);
-
-class HeapSnapshotRepositoryMock implements M.HeapSnapshotRepository {
-  final HeapSnapshotRepositoryMockCallback _get;
-
-  Stream<M.HeapSnapshotLoadingProgressEvent> get(M.IsolateRef isolate,
-      {M.HeapSnapshotRoots roots: M.HeapSnapshotRoots.vm, bool gc: false}) {
-    if (_get != null) {
-      return _get(isolate, gc);
-    }
-    return null;
-  }
-
-  HeapSnapshotRepositoryMock({HeapSnapshotRepositoryMockCallback getter})
-      : _get = getter;
-}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/repositories/icdata.dart b/runtime/observatory/tests/observatory_ui/mocks/repositories/icdata.dart
deleted file mode 100644
index ae440ef..0000000
--- a/runtime/observatory/tests/observatory_ui/mocks/repositories/icdata.dart
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-part of mocks;
-
-typedef Future<M.ICData> ICDataRepositoryMockCallback(
-    M.IsolateRef isolate, String id);
-
-class ICDataRepositoryMock implements M.ICDataRepository {
-  final ICDataRepositoryMockCallback _get;
-
-  ICDataRepositoryMock({ICDataRepositoryMockCallback getter}) : _get = getter;
-
-  Future<M.ICData> get(M.IsolateRef isolate, String id, {int count}) {
-    if (_get != null) {
-      return _get(isolate, id);
-    }
-    return new Future.value(null);
-  }
-}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/repositories/inbound_references.dart b/runtime/observatory/tests/observatory_ui/mocks/repositories/inbound_references.dart
deleted file mode 100644
index 9920048..0000000
--- a/runtime/observatory/tests/observatory_ui/mocks/repositories/inbound_references.dart
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file
-
-part of mocks;
-
-typedef Future<M.InboundReferences> InboundReferencesRepositoryMockGetter(
-    M.IsolateRef i, String id);
-
-class InboundReferencesRepositoryMock implements M.InboundReferencesRepository {
-  final InboundReferencesRepositoryMockGetter _getter;
-
-  Future<M.InboundReferences> get(M.IsolateRef i, String id) {
-    if (_getter != null) {
-      return _getter(i, id);
-    }
-    return new Future.value(new InboundReferencesMock());
-  }
-
-  InboundReferencesRepositoryMock(
-      {InboundReferencesRepositoryMockGetter getter})
-      : _getter = getter;
-}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/repositories/instance.dart b/runtime/observatory/tests/observatory_ui/mocks/repositories/instance.dart
deleted file mode 100644
index 7e13055..0000000
--- a/runtime/observatory/tests/observatory_ui/mocks/repositories/instance.dart
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-part of mocks;
-
-typedef Future<M.Instance> InstanceRepositoryMockCallback(
-    M.IsolateRef isolate, String id);
-
-class InstanceRepositoryMock implements M.InstanceRepository {
-  final InstanceRepositoryMockCallback _get;
-
-  InstanceRepositoryMock({InstanceRepositoryMockCallback getter})
-      : _get = getter;
-
-  Future<M.Instance> get(M.IsolateRef isolate, String id, {int count}) {
-    if (_get != null) {
-      return _get(isolate, id);
-    }
-    return new Future.value(null);
-  }
-}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/repositories/library.dart b/runtime/observatory/tests/observatory_ui/mocks/repositories/library.dart
deleted file mode 100644
index 9dc51b1..0000000
--- a/runtime/observatory/tests/observatory_ui/mocks/repositories/library.dart
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-part of mocks;
-
-typedef Future<M.Library> LibraryRepositoryMockCallback(
-    M.IsolateRef isolate, String id);
-
-class LibraryRepositoryMock implements M.LibraryRepository {
-  final LibraryRepositoryMockCallback _get;
-
-  LibraryRepositoryMock({LibraryRepositoryMockCallback getter}) : _get = getter;
-
-  Future<M.Library> get(M.IsolateRef isolate, String id) {
-    if (_get != null) {
-      return _get(isolate, id);
-    }
-    return new Future.value(null);
-  }
-}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/repositories/megamorphiccache.dart b/runtime/observatory/tests/observatory_ui/mocks/repositories/megamorphiccache.dart
deleted file mode 100644
index aabdf90..0000000
--- a/runtime/observatory/tests/observatory_ui/mocks/repositories/megamorphiccache.dart
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-part of mocks;
-
-typedef Future<M.MegamorphicCache> MegamorphicCacheRepositoryMockCallback(
-    M.IsolateRef isolate, String id);
-
-class MegamorphicCacheRepositoryMock implements M.MegamorphicCacheRepository {
-  final MegamorphicCacheRepositoryMockCallback _get;
-
-  MegamorphicCacheRepositoryMock(
-      {MegamorphicCacheRepositoryMockCallback getter})
-      : _get = getter;
-
-  Future<M.MegamorphicCache> get(M.IsolateRef isolate, String id, {int count}) {
-    if (_get != null) {
-      return _get(isolate, id);
-    }
-    return new Future.value(null);
-  }
-}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/repositories/notification.dart b/runtime/observatory/tests/observatory_ui/mocks/repositories/notification.dart
deleted file mode 100644
index 8855d92..0000000
--- a/runtime/observatory/tests/observatory_ui/mocks/repositories/notification.dart
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-part of mocks;
-
-class NotificationChangeEventMock implements M.NotificationChangeEvent {
-  final NotificationRepositoryMock repository;
-  const NotificationChangeEventMock({this.repository});
-}
-
-typedef void NotificationRepositoryMockCallback(M.Notification notification);
-
-class NotificationRepositoryMock implements M.NotificationRepository {
-  final StreamController<M.NotificationChangeEvent> _onChange =
-      new StreamController<M.NotificationChangeEvent>.broadcast();
-  Stream<M.NotificationChangeEvent> get onChange => _onChange.stream;
-
-  bool get hasListeners => _onChange.hasListener;
-
-  final Iterable<M.Notification> _list;
-  final NotificationRepositoryMockCallback _add;
-  final NotificationRepositoryMockCallback _delete;
-
-  bool addInvoked = false;
-  bool listInvoked = false;
-  bool deleteInvoked = false;
-  bool deleteAllInvoked = false;
-
-  void add(M.Notification notification) {
-    addInvoked = true;
-    if (_add != null) _add(notification);
-  }
-
-  Iterable<M.Notification> list() {
-    listInvoked = true;
-    return _list;
-  }
-
-  void delete(M.Notification notification) {
-    deleteInvoked = true;
-    if (_add != null) _delete(notification);
-  }
-
-  void deleteAll() {
-    deleteAllInvoked = true;
-  }
-
-  void triggerChangeEvent() {
-    _onChange.add(new NotificationChangeEventMock(repository: this));
-  }
-
-  NotificationRepositoryMock(
-      {Iterable<M.Notification> list: const [],
-      NotificationRepositoryMockCallback add,
-      NotificationRepositoryMockCallback delete})
-      : _list = list,
-        _add = add,
-        _delete = delete;
-}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/repositories/object.dart b/runtime/observatory/tests/observatory_ui/mocks/repositories/object.dart
deleted file mode 100644
index f965665..0000000
--- a/runtime/observatory/tests/observatory_ui/mocks/repositories/object.dart
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-part of mocks;
-
-typedef Future<M.Object> ObjectRepositoryMockCallback(
-    M.IsolateRef isolate, String id);
-
-class ObjectRepositoryMock implements M.ObjectRepository {
-  final ObjectRepositoryMockCallback _get;
-
-  ObjectRepositoryMock({ObjectRepositoryMockCallback getter}) : _get = getter;
-
-  Future<M.Object> get(M.IsolateRef isolate, String id, {int count}) {
-    if (_get != null) {
-      return _get(isolate, id);
-    }
-    return new Future.value(null);
-  }
-}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/repositories/objectpool.dart b/runtime/observatory/tests/observatory_ui/mocks/repositories/objectpool.dart
deleted file mode 100644
index 2cbf99c..0000000
--- a/runtime/observatory/tests/observatory_ui/mocks/repositories/objectpool.dart
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file
-
-part of mocks;
-
-typedef Future<M.ObjectPool> ObjectPoolRepositoryMockGetter(
-    M.IsolateRef i, String id);
-
-class ObjectPoolRepositoryMock implements M.ObjectPoolRepository {
-  final ObjectPoolRepositoryMockGetter _getter;
-
-  Future<M.ObjectPool> get(M.IsolateRef i, String id) {
-    if (_getter != null) {
-      return _getter(i, id);
-    }
-    return new Future.value(new ObjectPoolMock());
-  }
-
-  ObjectPoolRepositoryMock({ObjectPoolRepositoryMockGetter getter})
-      : _getter = getter;
-}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/repositories/objectstore.dart b/runtime/observatory/tests/observatory_ui/mocks/repositories/objectstore.dart
deleted file mode 100644
index 373e872..0000000
--- a/runtime/observatory/tests/observatory_ui/mocks/repositories/objectstore.dart
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file
-
-part of mocks;
-
-typedef Future<M.ObjectStore> ObjectStoreRepositoryMockGetter(M.IsolateRef i);
-
-class ObjectStoreRepositoryMock implements M.ObjectStoreRepository {
-  final ObjectStoreRepositoryMockGetter _getter;
-
-  Future<M.ObjectStore> get(M.IsolateRef i) {
-    if (_getter != null) {
-      return _getter(i);
-    }
-    return new Future.value(new ObjectStoreMock());
-  }
-
-  ObjectStoreRepositoryMock({ObjectStoreRepositoryMockGetter getter})
-      : _getter = getter;
-}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/repositories/persistent_handles.dart b/runtime/observatory/tests/observatory_ui/mocks/repositories/persistent_handles.dart
deleted file mode 100644
index 518381d..0000000
--- a/runtime/observatory/tests/observatory_ui/mocks/repositories/persistent_handles.dart
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file
-
-part of mocks;
-
-typedef Future<M.PersistentHandles> PersistentHandlesRepositoryMockGetter(
-    M.IsolateRef i);
-
-class PersistentHandlesRepositoryMock implements M.PersistentHandlesRepository {
-  final PersistentHandlesRepositoryMockGetter _getter;
-
-  Future<M.PersistentHandles> get(M.IsolateRef i) {
-    if (_getter != null) {
-      return _getter(i);
-    }
-    return new Future.value(new PortsAndHandlesMock());
-  }
-
-  PersistentHandlesRepositoryMock(
-      {PersistentHandlesRepositoryMockGetter getter})
-      : _getter = getter;
-}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/repositories/ports.dart b/runtime/observatory/tests/observatory_ui/mocks/repositories/ports.dart
deleted file mode 100644
index 8bdbe4d..0000000
--- a/runtime/observatory/tests/observatory_ui/mocks/repositories/ports.dart
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file
-
-part of mocks;
-
-typedef Future<M.Ports> PortsRepositoryMockGetter(M.IsolateRef i);
-
-class PortsRepositoryMock implements M.PortsRepository {
-  final PortsRepositoryMockGetter _getter;
-
-  Future<M.Ports> get(M.IsolateRef i) {
-    if (_getter != null) {
-      return _getter(i);
-    }
-    return new Future.value(new PortsAndHandlesMock());
-  }
-
-  PortsRepositoryMock({PortsRepositoryMockGetter getter}) : _getter = getter;
-}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/repositories/reachable_size.dart b/runtime/observatory/tests/observatory_ui/mocks/repositories/reachable_size.dart
deleted file mode 100644
index 786e719..0000000
--- a/runtime/observatory/tests/observatory_ui/mocks/repositories/reachable_size.dart
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file
-
-part of mocks;
-
-typedef Future<M.Guarded<M.Instance>> ReachableSizeRepositoryMockGetter(
-    M.IsolateRef i, String id);
-
-class ReachableSizeRepositoryMock implements M.ReachableSizeRepository {
-  final ReachableSizeRepositoryMockGetter _getter;
-
-  Future<M.Guarded<M.Instance>> get(M.IsolateRef i, String id) {
-    if (_getter != null) {
-      return _getter(i, id);
-    }
-    return new Future.value(
-        new GuardedMock<M.Instance>.fromSentinel(new SentinelMock()));
-  }
-
-  ReachableSizeRepositoryMock({ReachableSizeRepositoryMockGetter getter})
-      : _getter = getter;
-}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/repositories/retained_size.dart b/runtime/observatory/tests/observatory_ui/mocks/repositories/retained_size.dart
deleted file mode 100644
index d5dba6f..0000000
--- a/runtime/observatory/tests/observatory_ui/mocks/repositories/retained_size.dart
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file
-
-part of mocks;
-
-typedef Future<M.Guarded<M.Instance>> RetainedSizeRepositoryMockGetter(
-    M.IsolateRef i, String id);
-
-class RetainedSizeRepositoryMock implements M.RetainedSizeRepository {
-  final RetainedSizeRepositoryMockGetter _getter;
-
-  Future<M.Guarded<M.Instance>> get(M.IsolateRef i, String id) {
-    if (_getter != null) {
-      return _getter(i, id);
-    }
-    return new Future.value(
-        new GuardedMock<M.Instance>.fromSentinel(new SentinelMock()));
-  }
-
-  RetainedSizeRepositoryMock({RetainedSizeRepositoryMockGetter getter})
-      : _getter = getter;
-}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/repositories/retaining_path.dart b/runtime/observatory/tests/observatory_ui/mocks/repositories/retaining_path.dart
deleted file mode 100644
index 5fef44a..0000000
--- a/runtime/observatory/tests/observatory_ui/mocks/repositories/retaining_path.dart
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file
-
-part of mocks;
-
-typedef Future<M.RetainingPath> RetainingPathRepositoryMockGetter(
-    M.IsolateRef i, String id);
-
-class RetainingPathRepositoryMock implements M.RetainingPathRepository {
-  final RetainingPathRepositoryMockGetter _getter;
-
-  Future<M.RetainingPath> get(M.IsolateRef i, String id) {
-    if (_getter != null) {
-      return _getter(i, id);
-    }
-    return new Future.value(new RetainingPathMock());
-  }
-
-  RetainingPathRepositoryMock({RetainingPathRepositoryMockGetter getter})
-      : _getter = getter;
-}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/repositories/sample_profile.dart b/runtime/observatory/tests/observatory_ui/mocks/repositories/sample_profile.dart
deleted file mode 100644
index 0beeaea..0000000
--- a/runtime/observatory/tests/observatory_ui/mocks/repositories/sample_profile.dart
+++ /dev/null
@@ -1,99 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file
-
-part of mocks;
-
-class SampleProfileLoadingProgressEventMock
-    implements M.SampleProfileLoadingProgressEvent {
-  final M.SampleProfileLoadingProgress progress;
-  SampleProfileLoadingProgressEventMock({this.progress});
-}
-
-class SampleProfileLoadingProgressMock
-    implements M.SampleProfileLoadingProgress {
-  final M.SampleProfileLoadingStatus status;
-  final double progress;
-  final Duration fetchingTime;
-  final Duration loadingTime;
-  final M.SampleProfile profile;
-
-  const SampleProfileLoadingProgressMock(
-      {this.status: M.SampleProfileLoadingStatus.disabled,
-      this.progress: 0.0,
-      this.fetchingTime: const Duration(),
-      this.loadingTime: const Duration(),
-      this.profile});
-}
-
-typedef Stream<
-    M
-        .SampleProfileLoadingProgressEvent> ClassSampleProfileRepositoryMockCallback(
-    M.Isolate isolate,
-    M.ClassRef cls,
-    M.SampleProfileTag tag,
-    bool clear,
-    bool forceFetch);
-typedef Future ClassSampleProfileRepositoryMockToggleCallback(
-    M.Isolate isolate, M.ClassRef cls);
-
-class ClassSampleProfileRepositoryMock
-    implements M.ClassSampleProfileRepository {
-  final ClassSampleProfileRepositoryMockCallback _get;
-  final ClassSampleProfileRepositoryMockToggleCallback _enable;
-  final ClassSampleProfileRepositoryMockToggleCallback _disable;
-
-  Stream<M.SampleProfileLoadingProgressEvent> get(
-      covariant M.Isolate isolate, M.ClassRef cls, M.SampleProfileTag tag,
-      {bool clear: false, bool forceFetch: false}) {
-    if (_get != null) {
-      return _get(isolate, cls, tag, clear, forceFetch);
-    }
-    return null;
-  }
-
-  Future enable(covariant M.Isolate isolate, M.ClassRef cls) {
-    if (_enable != null) {
-      return _enable(isolate, cls);
-    }
-    return new Future.value();
-  }
-
-  Future disable(covariant M.Isolate isolate, M.ClassRef cls) {
-    if (_disable != null) {
-      return _disable(isolate, cls);
-    }
-    return new Future.value();
-  }
-
-  ClassSampleProfileRepositoryMock(
-      {ClassSampleProfileRepositoryMockCallback getter,
-      ClassSampleProfileRepositoryMockToggleCallback enable,
-      ClassSampleProfileRepositoryMockToggleCallback disable})
-      : _get = getter,
-        _enable = enable,
-        _disable = disable;
-}
-
-typedef Stream<
-    M
-        .SampleProfileLoadingProgressEvent> IsolateampleProfileRepositoryMockCallback(
-    M.IsolateRef cls, M.SampleProfileTag tag, bool clear, bool forceFetch);
-
-class IsolateSampleProfileRepositoryMock
-    implements M.IsolateSampleProfileRepository {
-  final IsolateampleProfileRepositoryMockCallback _get;
-
-  Stream<M.SampleProfileLoadingProgressEvent> get(
-      M.IsolateRef isolate, M.SampleProfileTag tag,
-      {bool clear: false, bool forceFetch: false}) {
-    if (_get != null) {
-      return _get(isolate, tag, clear, forceFetch);
-    }
-    return null;
-  }
-
-  IsolateSampleProfileRepositoryMock(
-      {IsolateampleProfileRepositoryMockCallback getter})
-      : _get = getter;
-}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/repositories/script.dart b/runtime/observatory/tests/observatory_ui/mocks/repositories/script.dart
deleted file mode 100644
index efa60ae..0000000
--- a/runtime/observatory/tests/observatory_ui/mocks/repositories/script.dart
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-part of mocks;
-
-typedef Future<M.Script> ScriptRepositoryMockCallback(
-    M.IsolateRef isolate, String id);
-
-class ScriptRepositoryMock implements M.ScriptRepository {
-  final ScriptRepositoryMockCallback _get;
-
-  ScriptRepositoryMock({ScriptRepositoryMockCallback getter}) : _get = getter;
-
-  Future<M.Script> get(M.IsolateRef isolate, String id) {
-    if (_get != null) {
-      return _get(isolate, id);
-    }
-    return new Future.value(null);
-  }
-}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/repositories/target.dart b/runtime/observatory/tests/observatory_ui/mocks/repositories/target.dart
deleted file mode 100644
index c6b5187..0000000
--- a/runtime/observatory/tests/observatory_ui/mocks/repositories/target.dart
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-part of mocks;
-
-class TargetChangeEventMock implements M.TargetChangeEvent {
-  final TargetRepositoryMock repository;
-  const TargetChangeEventMock({this.repository});
-}
-
-typedef void TargetRepositoryMockStringCallback(String notification);
-typedef void TargetRepositoryMockTargetCallback(M.Target notification);
-
-class TargetRepositoryMock implements M.TargetRepository {
-  final StreamController<M.TargetChangeEvent> _onChange =
-      new StreamController<M.TargetChangeEvent>.broadcast();
-  Stream<M.TargetChangeEvent> get onChange => _onChange.stream;
-
-  bool get hasListeners => _onChange.hasListener;
-
-  final M.Target _current;
-  final Iterable<M.Target> _list;
-  final TargetRepositoryMockStringCallback _add;
-  final TargetRepositoryMockTargetCallback _setCurrent;
-  final TargetRepositoryMockTargetCallback _delete;
-
-  bool currentInvoked = false;
-  bool addInvoked = false;
-  bool listInvoked = false;
-  bool setCurrentInvoked = false;
-  bool deleteInvoked = false;
-
-  M.Target get current {
-    currentInvoked = true;
-    return _current;
-  }
-
-  void add(String val) {
-    addInvoked = true;
-    if (_add != null) _add(val);
-  }
-
-  Iterable<M.Target> list() {
-    listInvoked = true;
-    return _list;
-  }
-
-  void setCurrent(M.Target target) {
-    setCurrentInvoked = true;
-    if (_setCurrent != null) _setCurrent(target);
-  }
-
-  void delete(M.Target target) {
-    deleteInvoked = true;
-    if (_delete != null) _delete(target);
-  }
-
-  void triggerChangeEvent() {
-    _onChange.add(new TargetChangeEventMock(repository: this));
-  }
-
-  M.Target find(String networkAddress) {
-    return const TargetMock();
-  }
-
-  @override
-  bool isConnectedVMTarget(M.Target target) {
-    return false;
-  }
-
-  TargetRepositoryMock(
-      {M.Target current,
-      Iterable<M.Target> list: const [],
-      TargetRepositoryMockStringCallback add,
-      TargetRepositoryMockTargetCallback setCurrent,
-      TargetRepositoryMockTargetCallback delete})
-      : _current = current,
-        _list = list,
-        _add = add,
-        _setCurrent = setCurrent,
-        _delete = delete;
-}
diff --git a/runtime/observatory/tests/observatory_ui/nav/class-menu/element_test.dart b/runtime/observatory/tests/observatory_ui/nav/class-menu/element_test.dart
deleted file mode 100644
index ba755bc..0000000
--- a/runtime/observatory/tests/observatory_ui/nav/class-menu/element_test.dart
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:html';
-import 'package:test/test.dart';
-import 'package:observatory/src/elements/nav/class_menu.dart';
-import '../../mocks.dart';
-
-main() {
-  NavClassMenuElement.tag.ensureRegistration();
-
-  final i_ref = const IsolateRefMock(id: 'i-id', name: 'i-name');
-  final c_ref = const ClassRefMock(id: 'c-id', name: 'c-name');
-  test('instantiation', () {
-    final e = new NavClassMenuElement(i_ref, c_ref);
-    expect(e, isNotNull, reason: 'element correctly created');
-    expect(e.isolate, equals(i_ref));
-    expect(e.cls, equals(c_ref));
-  });
-  test('elements created after attachment', () async {
-    final e = new NavClassMenuElement(i_ref, c_ref);
-    e.content = <Element>[document.createElement('content')];
-    document.body.append(e);
-    await e.onRendered.first;
-    expect(e.children.length, isNonZero, reason: 'has elements');
-    e.remove();
-    await e.onRendered.first;
-    expect(e.children.length, isZero, reason: 'is empty');
-  });
-}
diff --git a/runtime/observatory/tests/observatory_ui/nav/class-menu/element_test.html b/runtime/observatory/tests/observatory_ui/nav/class-menu/element_test.html
deleted file mode 100644
index f548be4..0000000
--- a/runtime/observatory/tests/observatory_ui/nav/class-menu/element_test.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-  <meta http-equiv="X-UA-Compatible" content="IE=edge">
-  <meta name="dart.unittest" content="full-stack-traces">
-  <style>
-     .unittest-table { font-family:monospace; border:1px; }
-     .unittest-pass { background: #6b3;}
-     .unittest-fail { background: #d55;}
-     .unittest-error { background: #a11;}
-  </style>
-</head>
-<body>
-  <script type="text/javascript"
-      src="/root_dart/tools/testing/dart/test_controller.js"></script>
-  %TEST_SCRIPTS%
-</body>
-</html>
diff --git a/runtime/observatory/tests/observatory_ui/nav/isolate-menu/element_test.dart b/runtime/observatory/tests/observatory_ui/nav/isolate-menu/element_test.dart
deleted file mode 100644
index 80d3e70..0000000
--- a/runtime/observatory/tests/observatory_ui/nav/isolate-menu/element_test.dart
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:html';
-import 'package:test/test.dart';
-import 'package:observatory/src/elements/nav/isolate_menu.dart';
-import '../../mocks.dart';
-
-main() {
-  NavIsolateMenuElement.tag.ensureRegistration();
-
-  final tag = '.nav-menu_label > a';
-
-  EventRepositoryMock events;
-  final ref = const IsolateRefMock(id: 'i-id', name: 'old-name');
-  final obj = const IsolateMock(id: 'i-id', name: 'new-name');
-  setUp(() {
-    events = new EventRepositoryMock();
-  });
-  group('instantiation', () {
-    test('IsolateRef', () {
-      final e = new NavIsolateMenuElement(ref, events);
-      expect(e, isNotNull, reason: 'element correctly created');
-      expect(e.isolate, equals(ref));
-    });
-    test('Isolate', () {
-      final e = new NavIsolateMenuElement(obj, events);
-      expect(e, isNotNull, reason: 'element correctly created');
-      expect(e.isolate, equals(obj));
-    });
-  });
-  test('elements created after attachment', () async {
-    final e = new NavIsolateMenuElement(ref, events);
-    document.body.append(e);
-    await e.onRendered.first;
-    expect(e.children.length, isNonZero, reason: 'has elements');
-    e.remove();
-    await e.onRendered.first;
-    expect(e.children.length, isZero, reason: 'is empty');
-  });
-  group('updates', () {
-    test('are correctly listen', () async {
-      final e = new NavIsolateMenuElement(ref, events);
-      expect(events.onIsolateUpdateHasListener, isFalse);
-      document.body.append(e);
-      await e.onRendered.first;
-      expect(events.onIsolateUpdateHasListener, isTrue);
-      e.remove();
-      await e.onRendered.first;
-      expect(events.onIsolateUpdateHasListener, isFalse);
-    });
-    test('have effects', () async {
-      final e = new NavIsolateMenuElement(ref, events);
-      document.body.append(e);
-      await e.onRendered.first;
-      expect(e.querySelector(tag).text.contains(ref.name), isTrue);
-      events.add(new IsolateUpdateEventMock(isolate: obj));
-      await e.onRendered.first;
-      expect(e.querySelector(tag).text.contains(ref.name), isFalse);
-      expect(e.querySelector(tag).text.contains(obj.name), isTrue);
-      e.remove();
-    });
-  });
-}
diff --git a/runtime/observatory/tests/observatory_ui/nav/isolate-menu/element_test.html b/runtime/observatory/tests/observatory_ui/nav/isolate-menu/element_test.html
deleted file mode 100644
index f548be4..0000000
--- a/runtime/observatory/tests/observatory_ui/nav/isolate-menu/element_test.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-  <meta http-equiv="X-UA-Compatible" content="IE=edge">
-  <meta name="dart.unittest" content="full-stack-traces">
-  <style>
-     .unittest-table { font-family:monospace; border:1px; }
-     .unittest-pass { background: #6b3;}
-     .unittest-fail { background: #d55;}
-     .unittest-error { background: #a11;}
-  </style>
-</head>
-<body>
-  <script type="text/javascript"
-      src="/root_dart/tools/testing/dart/test_controller.js"></script>
-  %TEST_SCRIPTS%
-</body>
-</html>
diff --git a/runtime/observatory/tests/observatory_ui/nav/library-menu/element_test.dart b/runtime/observatory/tests/observatory_ui/nav/library-menu/element_test.dart
deleted file mode 100644
index 59c59b6..0000000
--- a/runtime/observatory/tests/observatory_ui/nav/library-menu/element_test.dart
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:html';
-import 'package:test/test.dart';
-import 'package:observatory/src/elements/nav/library_menu.dart';
-import '../../mocks.dart';
-
-main() {
-  NavLibraryMenuElement.tag.ensureRegistration();
-
-  final i_ref = const IsolateRefMock(id: 'i-id', name: 'i-name');
-  final l_ref = const LibraryRefMock(id: 'l-id', name: 'l-name');
-  test('instantiation', () {
-    final e = new NavLibraryMenuElement(i_ref, l_ref);
-    expect(e, isNotNull, reason: 'element correctly created');
-    expect(e.isolate, equals(i_ref));
-    expect(e.library, equals(l_ref));
-  });
-  test('elements created after attachment', () async {
-    final e = new NavLibraryMenuElement(i_ref, l_ref);
-    document.body.append(e);
-    await e.onRendered.first;
-    expect(e.children.length, isNonZero, reason: 'has elements');
-    e.remove();
-    await e.onRendered.first;
-    expect(e.children.length, isZero, reason: 'is empty');
-  });
-}
diff --git a/runtime/observatory/tests/observatory_ui/nav/library-menu/element_test.html b/runtime/observatory/tests/observatory_ui/nav/library-menu/element_test.html
deleted file mode 100644
index f548be4..0000000
--- a/runtime/observatory/tests/observatory_ui/nav/library-menu/element_test.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-  <meta http-equiv="X-UA-Compatible" content="IE=edge">
-  <meta name="dart.unittest" content="full-stack-traces">
-  <style>
-     .unittest-table { font-family:monospace; border:1px; }
-     .unittest-pass { background: #6b3;}
-     .unittest-fail { background: #d55;}
-     .unittest-error { background: #a11;}
-  </style>
-</head>
-<body>
-  <script type="text/javascript"
-      src="/root_dart/tools/testing/dart/test_controller.js"></script>
-  %TEST_SCRIPTS%
-</body>
-</html>
diff --git a/runtime/observatory/tests/observatory_ui/nav/menu-item/element_test.dart b/runtime/observatory/tests/observatory_ui/nav/menu-item/element_test.dart
deleted file mode 100644
index 8f77748..0000000
--- a/runtime/observatory/tests/observatory_ui/nav/menu-item/element_test.dart
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:html';
-import 'package:test/test.dart';
-import 'package:observatory/src/elements/nav/menu_item.dart';
-
-main() {
-  NavMenuItemElement.tag.ensureRegistration();
-
-  group('instantiation', () {
-    final label = 'custom-label';
-    final link = 'link-to-target';
-    test('label', () {
-      final e = new NavMenuItemElement(label);
-      expect(e, isNotNull, reason: 'element correctly created');
-      expect(e.label, equals(label), reason: 'element correctly created');
-    });
-    test('label', () {
-      final e = new NavMenuItemElement(label, link: link);
-      expect(e, isNotNull, reason: 'element correctly created');
-      expect(e.link, equals(link), reason: 'element correctly created');
-    });
-  });
-  group('elements', () {
-    test('created', () async {
-      final label = 'custom-label';
-      final e = new NavMenuItemElement(label);
-      e.content = <Element>[document.createElement('content')];
-      document.body.append(e);
-      await e.onRendered.first;
-      expect(e.children.length, isNonZero, reason: 'has elements');
-      expect(e.querySelector('content'), isNotNull,
-          reason: 'has content elements');
-      e.remove();
-      await e.onRendered.first;
-      expect(e.children.length, isZero, reason: 'is empty');
-    });
-    test('react to label change', () async {
-      final label1 = 'custom-label-1';
-      final label2 = 'custom-label-2';
-      final e = new NavMenuItemElement(label1);
-      document.body.append(e);
-      await e.onRendered.first;
-      expect(e.innerHtml.contains(label1), isTrue);
-      expect(e.innerHtml.contains(label2), isFalse);
-      e.label = label2;
-      await e.onRendered.first;
-      expect(e.innerHtml.contains(label1), isFalse);
-      expect(e.innerHtml.contains(label2), isTrue);
-      e.remove();
-      await e.onRendered.first;
-    });
-    test('react to link change', () async {
-      final label = 'custom-label';
-      final link1 = 'custom-label-1';
-      final link2 = 'custom-label-2';
-      final e = new NavMenuItemElement(label, link: link1);
-      document.body.append(e);
-      await e.onRendered.first;
-      expect(e.innerHtml.contains(link1), isTrue);
-      expect(e.innerHtml.contains(link2), isFalse);
-      e.link = link2;
-      await e.onRendered.first;
-      expect(e.innerHtml.contains(link1), isFalse);
-      expect(e.innerHtml.contains(link2), isTrue);
-      e.remove();
-      await e.onRendered.first;
-    });
-  });
-}
diff --git a/runtime/observatory/tests/observatory_ui/nav/menu-item/element_test.html b/runtime/observatory/tests/observatory_ui/nav/menu-item/element_test.html
deleted file mode 100644
index f548be4..0000000
--- a/runtime/observatory/tests/observatory_ui/nav/menu-item/element_test.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-  <meta http-equiv="X-UA-Compatible" content="IE=edge">
-  <meta name="dart.unittest" content="full-stack-traces">
-  <style>
-     .unittest-table { font-family:monospace; border:1px; }
-     .unittest-pass { background: #6b3;}
-     .unittest-fail { background: #d55;}
-     .unittest-error { background: #a11;}
-  </style>
-</head>
-<body>
-  <script type="text/javascript"
-      src="/root_dart/tools/testing/dart/test_controller.js"></script>
-  %TEST_SCRIPTS%
-</body>
-</html>
diff --git a/runtime/observatory/tests/observatory_ui/nav/notify/element_test.dart b/runtime/observatory/tests/observatory_ui/nav/notify/element_test.dart
deleted file mode 100644
index 3fafd60..0000000
--- a/runtime/observatory/tests/observatory_ui/nav/notify/element_test.dart
+++ /dev/null
@@ -1,118 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:html' hide Notification, NotificationEvent;
-import 'package:test/test.dart';
-import 'package:observatory/models.dart' as M;
-import 'package:observatory/src/elements/nav/notify.dart';
-import 'package:observatory/src/elements/nav/notify_event.dart';
-import 'package:observatory/src/elements/nav/notify_exception.dart';
-import '../../mocks.dart';
-
-main() {
-  NavNotifyElement.tag.ensureRegistration();
-
-  final evTag = NavNotifyEventElement.tag.name;
-  final exTag = NavNotifyExceptionElement.tag.name;
-
-  const vm = const VMRefMock();
-  const isolate = const IsolateRefMock(id: 'i-id', name: 'i-name');
-
-  group('instantiation', () {
-    NotificationRepositoryMock repository;
-    setUp(() {
-      repository = new NotificationRepositoryMock();
-    });
-    test('default', () {
-      final e = new NavNotifyElement(repository);
-      expect(e, isNotNull, reason: 'element correctly created');
-      expect(e.notifyOnPause, isTrue, reason: 'notifyOnPause is default');
-    });
-    test('notify on pause', () {
-      final e = new NavNotifyElement(repository, notifyOnPause: true);
-      expect(e, isNotNull, reason: 'element correctly created');
-      expect(e.notifyOnPause, isTrue, reason: 'notifyOnPause is the same');
-    });
-    test('do not notify on pause', () {
-      final e = new NavNotifyElement(repository, notifyOnPause: false);
-      expect(e, isNotNull, reason: 'element correctly created');
-      expect(e.notifyOnPause, isFalse, reason: 'notifyOnPause is the same');
-    });
-  });
-  test('is correctly listening', () async {
-    final repository = new NotificationRepositoryMock();
-    final e = new NavNotifyElement(repository);
-    document.body.append(e);
-    await e.onRendered.first;
-    expect(repository.hasListeners, isTrue, reason: 'is listening');
-    e.remove();
-    await e.onRendered.first;
-    expect(repository.hasListeners, isFalse, reason: 'is no more listening');
-  });
-  group('elements', () {
-    test('created after attachment', () async {
-      final repository = new NotificationRepositoryMock(list: [
-        new ExceptionNotificationMock(exception: new Exception("ex")),
-        const EventNotificationMock(event: const VMUpdateEventMock(vm: vm)),
-        const EventNotificationMock(event: const VMUpdateEventMock(vm: vm))
-      ]);
-      final e = new NavNotifyElement(repository);
-      document.body.append(e);
-      await e.onRendered.first;
-      expect(repository.listInvoked, isTrue, reason: 'should invoke list()');
-      expect(e.children.length, isNonZero, reason: 'has elements');
-      expect(e.querySelectorAll(evTag).length, equals(2));
-      expect(e.querySelectorAll(exTag).length, equals(1));
-      e.remove();
-      await e.onRendered.first;
-      expect(e.children.length, isZero, reason: 'is empty');
-    });
-    test('react to notifyOnPause change', () async {
-      final NotificationRepositoryMock repository =
-          new NotificationRepositoryMock(list: [
-        new ExceptionNotificationMock(exception: new Exception("ex")),
-        const EventNotificationMock(event: const VMUpdateEventMock()),
-        const EventNotificationMock(
-            event: const PauseStartEventMock(isolate: isolate))
-      ]);
-      final e = new NavNotifyElement(repository, notifyOnPause: true);
-      document.body.append(e);
-      await e.onRendered.first;
-      expect(e.querySelectorAll(evTag).length, equals(2));
-      expect(e.querySelectorAll(exTag).length, equals(1));
-      e.notifyOnPause = false;
-      await e.onRendered.first;
-      expect(e.querySelectorAll(evTag).length, equals(1));
-      expect(e.querySelectorAll(exTag).length, equals(1));
-      e.notifyOnPause = true;
-      await e.onRendered.first;
-      expect(e.querySelectorAll(evTag).length, equals(2));
-      expect(e.querySelectorAll(exTag).length, equals(1));
-      e.remove();
-      await e.onRendered.first;
-      expect(e.children.length, isZero, reason: 'is empty');
-    });
-    test('react to update event', () async {
-      final List<M.Notification> list = [
-        new ExceptionNotificationMock(exception: new Exception("ex")),
-        const EventNotificationMock(event: const VMUpdateEventMock()),
-      ];
-      final repository = new NotificationRepositoryMock(list: list);
-      final e = new NavNotifyElement(repository, notifyOnPause: true);
-      document.body.append(e);
-      await e.onRendered.first;
-      expect(e.querySelectorAll(evTag).length, equals(1));
-      expect(e.querySelectorAll(exTag).length, equals(1));
-      list.add(const EventNotificationMock(
-          event: const PauseStartEventMock(isolate: isolate)));
-      repository.triggerChangeEvent();
-      await e.onRendered.first;
-      expect(e.querySelectorAll(evTag).length, equals(2));
-      expect(e.querySelectorAll(exTag).length, equals(1));
-      e.remove();
-      await e.onRendered.first;
-      expect(e.children.length, isZero, reason: 'is empty');
-    });
-  });
-}
diff --git a/runtime/observatory/tests/observatory_ui/nav/notify/element_test.html b/runtime/observatory/tests/observatory_ui/nav/notify/element_test.html
deleted file mode 100644
index f548be4..0000000
--- a/runtime/observatory/tests/observatory_ui/nav/notify/element_test.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-  <meta http-equiv="X-UA-Compatible" content="IE=edge">
-  <meta name="dart.unittest" content="full-stack-traces">
-  <style>
-     .unittest-table { font-family:monospace; border:1px; }
-     .unittest-pass { background: #6b3;}
-     .unittest-fail { background: #d55;}
-     .unittest-error { background: #a11;}
-  </style>
-</head>
-<body>
-  <script type="text/javascript"
-      src="/root_dart/tools/testing/dart/test_controller.js"></script>
-  %TEST_SCRIPTS%
-</body>
-</html>
diff --git a/runtime/observatory/tests/observatory_ui/nav/notify_event/element_test.dart b/runtime/observatory/tests/observatory_ui/nav/notify_event/element_test.dart
deleted file mode 100644
index 557a278..0000000
--- a/runtime/observatory/tests/observatory_ui/nav/notify_event/element_test.dart
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:html';
-import 'dart:async';
-import 'package:test/test.dart';
-import 'package:observatory/src/elements/nav/notify_event.dart';
-import '../../mocks.dart';
-
-main() {
-  NavNotifyEventElement.tag.ensureRegistration();
-
-  final event = new PauseStartEventMock(
-      isolate: new IsolateMock(id: 'isolate-id', name: 'isolate-name'));
-  group('instantiation', () {
-    test('default', () {
-      final e = new NavNotifyEventElement(event);
-      expect(e, isNotNull, reason: 'element correctly created');
-      expect(e.event, equals(event));
-    });
-  });
-  group('elements', () {
-    test('created after attachment', () async {
-      final e = new NavNotifyEventElement(event);
-      document.body.append(e);
-      await e.onRendered.first;
-      expect(e.children.length, isNonZero, reason: 'has elements');
-      e.remove();
-      await e.onRendered.first;
-      expect(e.children.length, isZero, reason: 'is empty');
-    });
-  });
-  group('events are fired', () {
-    NavNotifyEventElement e;
-    StreamSubscription sub;
-    setUp(() async {
-      e = new NavNotifyEventElement(event);
-      document.body.append(e);
-      await e.onRendered.first;
-    });
-    tearDown(() {
-      sub.cancel();
-      e.remove();
-    });
-    test('navigation after connect', () async {
-      sub = window.onPopState
-          .listen(expectAsync1((_) {}, count: 1, reason: 'event is fired'));
-      e.querySelector('a').click();
-    });
-    test('onDelete events (DOM)', () async {
-      sub = e.onDelete.listen(expectAsync1((EventDeleteEvent ev) {
-        expect(ev, isNotNull, reason: 'event is passed');
-        expect(ev.event, equals(event), reason: 'exception is the same');
-      }, count: 1, reason: 'event is fired'));
-      e.querySelector('button').click();
-    });
-    test('onDelete events (code)', () async {
-      sub = e.onDelete.listen(expectAsync1((EventDeleteEvent ev) {
-        expect(ev, isNotNull, reason: 'event is passed');
-        expect(ev.event, equals(event), reason: 'exception is the same');
-      }, count: 1, reason: 'event is fired'));
-      e.delete();
-    });
-  });
-}
diff --git a/runtime/observatory/tests/observatory_ui/nav/notify_event/element_test.html b/runtime/observatory/tests/observatory_ui/nav/notify_event/element_test.html
deleted file mode 100644
index f548be4..0000000
--- a/runtime/observatory/tests/observatory_ui/nav/notify_event/element_test.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-  <meta http-equiv="X-UA-Compatible" content="IE=edge">
-  <meta name="dart.unittest" content="full-stack-traces">
-  <style>
-     .unittest-table { font-family:monospace; border:1px; }
-     .unittest-pass { background: #6b3;}
-     .unittest-fail { background: #d55;}
-     .unittest-error { background: #a11;}
-  </style>
-</head>
-<body>
-  <script type="text/javascript"
-      src="/root_dart/tools/testing/dart/test_controller.js"></script>
-  %TEST_SCRIPTS%
-</body>
-</html>
diff --git a/runtime/observatory/tests/observatory_ui/nav/notify_exception/connection_exception_test.dart b/runtime/observatory/tests/observatory_ui/nav/notify_exception/connection_exception_test.dart
deleted file mode 100644
index 473ab77..0000000
--- a/runtime/observatory/tests/observatory_ui/nav/notify_exception/connection_exception_test.dart
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:html';
-import 'dart:async';
-import 'package:test/test.dart';
-import 'package:observatory/src/elements/nav/notify_exception.dart';
-import '../../mocks.dart';
-
-main() {
-  NavNotifyExceptionElement.tag.ensureRegistration();
-
-  final exception = new ConnectionExceptionMock(message: 'message');
-  test('instantiation', () {
-    final e = new NavNotifyExceptionElement(exception);
-    expect(e, isNotNull, reason: 'element correctly created');
-  });
-  test('elements created after attachment', () async {
-    final e = new NavNotifyExceptionElement(exception);
-    document.body.append(e);
-    await e.onRendered.first;
-    expect(e.children.length, isNonZero, reason: 'has elements');
-    e.remove();
-    await e.onRendered.first;
-    expect(e.children.length, isZero, reason: 'is empty');
-  });
-  group('events are fired', () {
-    NavNotifyExceptionElement e;
-    StreamSubscription sub;
-    setUp(() async {
-      e = new NavNotifyExceptionElement(exception);
-      document.body.append(e);
-      await e.onRendered.first;
-    });
-    tearDown(() {
-      sub.cancel();
-      e.remove();
-    });
-    test('navigation after connect', () async {
-      sub = window.onPopState
-          .listen(expectAsync1((_) {}, count: 1, reason: 'event is fired'));
-      e.querySelector('a').click();
-    });
-    test('onDelete events (DOM)', () async {
-      sub = e.onDelete.listen(expectAsync1((ExceptionDeleteEvent event) {
-        expect(event, isNotNull, reason: 'event is passed');
-        expect(event.exception, equals(exception),
-            reason: 'exception is the same');
-        expect(event.stacktrace, isNull);
-      }, count: 1, reason: 'event is fired'));
-      e.querySelector('button').click();
-    });
-    test('onDelete events (code)', () async {
-      sub = e.onDelete.listen(expectAsync1((ExceptionDeleteEvent event) {
-        expect(event, isNotNull, reason: 'event is passed');
-        expect(event.exception, equals(exception),
-            reason: 'exception is the same');
-        expect(event.stacktrace, isNull);
-      }, count: 1, reason: 'event is fired'));
-      e.delete();
-    });
-  });
-}
diff --git a/runtime/observatory/tests/observatory_ui/nav/notify_exception/connection_exception_test.html b/runtime/observatory/tests/observatory_ui/nav/notify_exception/connection_exception_test.html
deleted file mode 100644
index f548be4..0000000
--- a/runtime/observatory/tests/observatory_ui/nav/notify_exception/connection_exception_test.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-  <meta http-equiv="X-UA-Compatible" content="IE=edge">
-  <meta name="dart.unittest" content="full-stack-traces">
-  <style>
-     .unittest-table { font-family:monospace; border:1px; }
-     .unittest-pass { background: #6b3;}
-     .unittest-fail { background: #d55;}
-     .unittest-error { background: #a11;}
-  </style>
-</head>
-<body>
-  <script type="text/javascript"
-      src="/root_dart/tools/testing/dart/test_controller.js"></script>
-  %TEST_SCRIPTS%
-</body>
-</html>
diff --git a/runtime/observatory/tests/observatory_ui/nav/notify_exception/exception_test.dart b/runtime/observatory/tests/observatory_ui/nav/notify_exception/exception_test.dart
deleted file mode 100644
index d521aa2..0000000
--- a/runtime/observatory/tests/observatory_ui/nav/notify_exception/exception_test.dart
+++ /dev/null
@@ -1,91 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:html';
-import 'dart:async';
-import 'package:test/test.dart';
-import 'package:observatory/src/elements/nav/notify_exception.dart';
-
-main() {
-  NavNotifyExceptionElement.tag.ensureRegistration();
-
-  final st = new StackTrace.fromString('stacktrace string');
-  group('normal exception', () {
-    final ex = new Exception('exception message');
-    group('instantiation', () {
-      test('no stacktrace', () {
-        final e = new NavNotifyExceptionElement(ex);
-        expect(e, isNotNull, reason: 'element correctly created');
-        expect(e.exception, equals(ex));
-        expect(e.stacktrace, isNull);
-      });
-      test('with stacktrace', () {
-        final e = new NavNotifyExceptionElement(ex, stacktrace: st);
-        expect(e, isNotNull, reason: 'element correctly created');
-        expect(e.exception, equals(ex));
-        expect(e.stacktrace, equals(st));
-      });
-    });
-    group('elements', () {
-      test('created after attachment (no stacktrace)', () async {
-        final e = new NavNotifyExceptionElement(ex);
-        document.body.append(e);
-        await e.onRendered.first;
-        expect(e.children.length, isNonZero, reason: 'has elements');
-        expect(e.innerHtml.contains(ex.toString()), isTrue);
-        expect(e.innerHtml.contains(st.toString()), isFalse);
-        e.remove();
-        await e.onRendered.first;
-        expect(e.children.length, isZero, reason: 'is empty');
-      });
-      test('created after attachment (with stacktrace)', () async {
-        final e = new NavNotifyExceptionElement(ex, stacktrace: st);
-        document.body.append(e);
-        await e.onRendered.first;
-        expect(e.children.length, isNonZero, reason: 'has elements');
-        expect(e.innerHtml.contains(ex.toString()), isTrue);
-        expect(e.innerHtml.contains(st.toString()), isTrue);
-        e.remove();
-        await e.onRendered.first;
-        expect(e.children.length, isZero, reason: 'is empty');
-      });
-    });
-    group('events are fired', () {
-      NavNotifyExceptionElement e;
-      StreamSubscription sub;
-      setUp(() async {
-        e = new NavNotifyExceptionElement(ex, stacktrace: st);
-        document.body.append(e);
-        await e.onRendered.first;
-      });
-      tearDown(() {
-        sub.cancel();
-        e.remove();
-      });
-      test('navigation after connect', () async {
-        sub = window.onPopState
-            .listen(expectAsync1((_) {}, count: 1, reason: 'event is fired'));
-        e.querySelector('a').click();
-      });
-      test('onDelete events (DOM)', () async {
-        sub = e.onDelete.listen(expectAsync1((ExceptionDeleteEvent event) {
-          expect(event, isNotNull, reason: 'event is passed');
-          expect(event.exception, equals(ex), reason: 'exception is the same');
-          expect(event.stacktrace, equals(st),
-              reason: 'stacktrace is the same');
-        }, count: 1, reason: 'event is fired'));
-        e.querySelector('button').click();
-      });
-      test('onDelete events (code)', () async {
-        sub = e.onDelete.listen(expectAsync1((ExceptionDeleteEvent event) {
-          expect(event, isNotNull, reason: 'event is passed');
-          expect(event.exception, equals(ex), reason: 'exception is the same');
-          expect(event.stacktrace, equals(st),
-              reason: 'stacktrace is the same');
-        }, count: 1, reason: 'event is fired'));
-        e.delete();
-      });
-    });
-  });
-}
diff --git a/runtime/observatory/tests/observatory_ui/nav/notify_exception/exception_test.html b/runtime/observatory/tests/observatory_ui/nav/notify_exception/exception_test.html
deleted file mode 100644
index f548be4..0000000
--- a/runtime/observatory/tests/observatory_ui/nav/notify_exception/exception_test.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-  <meta http-equiv="X-UA-Compatible" content="IE=edge">
-  <meta name="dart.unittest" content="full-stack-traces">
-  <style>
-     .unittest-table { font-family:monospace; border:1px; }
-     .unittest-pass { background: #6b3;}
-     .unittest-fail { background: #d55;}
-     .unittest-error { background: #a11;}
-  </style>
-</head>
-<body>
-  <script type="text/javascript"
-      src="/root_dart/tools/testing/dart/test_controller.js"></script>
-  %TEST_SCRIPTS%
-</body>
-</html>
diff --git a/runtime/observatory/tests/observatory_ui/nav/refresh/element_test.dart b/runtime/observatory/tests/observatory_ui/nav/refresh/element_test.dart
deleted file mode 100644
index 6880244..0000000
--- a/runtime/observatory/tests/observatory_ui/nav/refresh/element_test.dart
+++ /dev/null
@@ -1,124 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:html';
-import 'dart:async';
-import 'package:test/test.dart';
-import 'package:observatory/src/elements/nav/refresh.dart';
-
-main() {
-  NavRefreshElement.tag.ensureRegistration();
-
-  group('instantiation', () {
-    test('no parameters', () {
-      final e = new NavRefreshElement();
-      expect(e, isNotNull, reason: 'element correctly created');
-      expect(e.label, isNotNull, reason: 'label is set to default');
-      expect(e.disabled, isFalse, reason: 'element correctly created');
-    });
-    test('label', () {
-      final label = 'custom-label';
-      final e = new NavRefreshElement(label: label);
-      expect(e, isNotNull, reason: 'element correctly created');
-      expect(e.label, isNotNull, reason: 'label is set');
-      expect(e.label, equals(label), reason: 'label is set to value');
-    });
-    test('not disabled', () {
-      final e = new NavRefreshElement(disabled: false);
-      expect(e, isNotNull, reason: 'element correctly created');
-      expect(e.disabled, isFalse, reason: 'element correctly created');
-    });
-    test('disabled', () {
-      final e = new NavRefreshElement(disabled: true);
-      expect(e, isNotNull, reason: 'element correctly created');
-      expect(e.disabled, isTrue, reason: 'element correctly created');
-    });
-  });
-  group('elements', () {
-    test('created after attachment', () async {
-      final e = new NavRefreshElement();
-      document.body.append(e);
-      await e.onRendered.first;
-      expect(e.children.length, isNonZero, reason: 'has elements');
-      e.remove();
-      await e.onRendered.first;
-      expect(e.children.length, isZero, reason: 'is empty');
-    });
-    test('contain custom label', () async {
-      final label = 'custom-label';
-      final e = new NavRefreshElement(label: label);
-      document.body.append(e);
-      await e.onRendered.first;
-      expect(e.innerHtml.contains(label), isTrue);
-      e.remove();
-      await e.onRendered.first;
-    });
-    test('react to label change', () async {
-      final label1 = 'custom-label-1';
-      final label2 = 'custom-label-2';
-      final e = new NavRefreshElement(label: label1);
-      document.body.append(e);
-      await e.onRendered.first;
-      expect(e.innerHtml.contains(label1), isTrue);
-      expect(e.innerHtml.contains(label2), isFalse);
-      e.label = label2;
-      await e.onRendered.first;
-      expect(e.innerHtml.contains(label2), isTrue);
-      expect(e.innerHtml.contains(label1), isFalse);
-      e.remove();
-      await e.onRendered.first;
-    });
-    test('react to disabled change', () async {
-      final e = new NavRefreshElement(disabled: false);
-      document.body.append(e);
-      await e.onRendered.first;
-      expect(e.disabled, isFalse);
-      e.disabled = true;
-      await e.onRendered.first;
-      expect(e.disabled, isTrue);
-      e.remove();
-      await e.onRendered.first;
-    });
-  });
-  group('event', () {
-    NavRefreshElement e;
-    StreamSubscription sub;
-    setUp(() async {
-      e = new NavRefreshElement();
-      document.body.append(e);
-      await e.onRendered.first;
-    });
-    tearDown(() async {
-      sub.cancel();
-      e.remove();
-      await e.onRendered.first;
-    });
-    test('fires', () async {
-      sub = e.onRefresh.listen(expectAsync1((event) {
-        expect(event, isNotNull, reason: 'event passed');
-        expect(event is RefreshEvent, isTrue, reason: 'is the right event');
-        expect(event.element, equals(e), reason: 'is related to the element');
-      }, count: 1));
-      e.refresh();
-    });
-    test('fires on click', () async {
-      sub = e.onRefresh.listen(expectAsync1((event) {
-        expect(event, isNotNull, reason: 'event passed');
-        expect(event is RefreshEvent, isTrue, reason: 'is the right event');
-        expect(event.element, equals(e), reason: 'is related to the element');
-      }, count: 1));
-      e.querySelector('button').click();
-    });
-    test('does not fire if disabled', () async {
-      e.disabled = true;
-      sub = e.onRefresh.listen(expectAsync1((_) {}, count: 0));
-      e.refresh();
-    });
-    test('does not fires on click if disabled', () async {
-      e.disabled = true;
-      sub = e.onRefresh.listen(expectAsync1((_) {}, count: 0));
-      e.querySelector('button').click();
-    });
-  });
-}
diff --git a/runtime/observatory/tests/observatory_ui/nav/refresh/element_test.html b/runtime/observatory/tests/observatory_ui/nav/refresh/element_test.html
deleted file mode 100644
index f548be4..0000000
--- a/runtime/observatory/tests/observatory_ui/nav/refresh/element_test.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-  <meta http-equiv="X-UA-Compatible" content="IE=edge">
-  <meta name="dart.unittest" content="full-stack-traces">
-  <style>
-     .unittest-table { font-family:monospace; border:1px; }
-     .unittest-pass { background: #6b3;}
-     .unittest-fail { background: #d55;}
-     .unittest-error { background: #a11;}
-  </style>
-</head>
-<body>
-  <script type="text/javascript"
-      src="/root_dart/tools/testing/dart/test_controller.js"></script>
-  %TEST_SCRIPTS%
-</body>
-</html>
diff --git a/runtime/observatory/tests/observatory_ui/nav/top_menu/element_test.dart b/runtime/observatory/tests/observatory_ui/nav/top_menu/element_test.dart
deleted file mode 100644
index 7ddd2ca..0000000
--- a/runtime/observatory/tests/observatory_ui/nav/top_menu/element_test.dart
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:html';
-import 'package:test/test.dart';
-import 'package:observatory/src/elements/nav/top_menu.dart';
-
-main() {
-  NavTopMenuElement.tag.ensureRegistration();
-
-  test('instantiation', () {
-    final e = new NavTopMenuElement();
-    expect(e, isNotNull, reason: 'element correctly created');
-  });
-  group('elements', () {
-    test('created', () async {
-      final e = new NavTopMenuElement();
-      e.content = <Element>[document.createElement('content')];
-      document.body.append(e);
-      await e.onRendered.first;
-      expect(e.children.length, isNonZero, reason: 'has elements');
-      expect(e.querySelector('content'), isNotNull,
-          reason: 'has content elements');
-      e.remove();
-      await e.onRendered.first;
-      expect(e.children.length, isZero, reason: 'is empty');
-    });
-  });
-}
diff --git a/runtime/observatory/tests/observatory_ui/nav/top_menu/element_test.html b/runtime/observatory/tests/observatory_ui/nav/top_menu/element_test.html
deleted file mode 100644
index f548be4..0000000
--- a/runtime/observatory/tests/observatory_ui/nav/top_menu/element_test.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-  <meta http-equiv="X-UA-Compatible" content="IE=edge">
-  <meta name="dart.unittest" content="full-stack-traces">
-  <style>
-     .unittest-table { font-family:monospace; border:1px; }
-     .unittest-pass { background: #6b3;}
-     .unittest-fail { background: #d55;}
-     .unittest-error { background: #a11;}
-  </style>
-</head>
-<body>
-  <script type="text/javascript"
-      src="/root_dart/tools/testing/dart/test_controller.js"></script>
-  %TEST_SCRIPTS%
-</body>
-</html>
diff --git a/runtime/observatory/tests/observatory_ui/nav/vm_menu/element_test.dart b/runtime/observatory/tests/observatory_ui/nav/vm_menu/element_test.dart
deleted file mode 100644
index be95c7a..0000000
--- a/runtime/observatory/tests/observatory_ui/nav/vm_menu/element_test.dart
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:html';
-import 'package:test/test.dart';
-import 'package:observatory/src/elements/nav/menu_item.dart';
-import 'package:observatory/src/elements/nav/vm_menu.dart';
-import '../../mocks.dart';
-
-main() {
-  NavVMMenuElement.tag.ensureRegistration();
-
-  final mTag = '.nav-menu_label > a';
-  final miTag = NavMenuItemElement.tag.name;
-
-  EventRepositoryMock events;
-  final vm1 = const VMMock(
-      name: 'vm-name-1',
-      displayName: 'display-name-1',
-      isolates: const [const IsolateRefMock(id: 'i-id-1', name: 'i-name-1')]);
-  final vm2 = const VMMock(
-      name: 'vm-name-2',
-      displayName: 'display-name-2',
-      isolates: const [
-        const IsolateRefMock(id: 'i-id-1', name: 'i-name-1'),
-        const IsolateRefMock(id: 'i-id-2', name: 'i-name-2')
-      ]);
-  setUp(() {
-    events = new EventRepositoryMock();
-  });
-  test('instantiation', () {
-    final e = new NavVMMenuElement(vm1, events);
-    expect(e, isNotNull, reason: 'element correctly created');
-    expect(e.vm, equals(vm1));
-  });
-  test('elements created after attachment', () async {
-    final e = new NavVMMenuElement(vm1, events);
-    document.body.append(e);
-    await e.onRendered.first;
-    expect(e.children.length, isNonZero, reason: 'has elements');
-    e.remove();
-    await e.onRendered.first;
-    expect(e.children.length, isZero, reason: 'is empty');
-  });
-  group('updates', () {
-    test('are correctly listen', () async {
-      final e = new NavVMMenuElement(vm1, events);
-      expect(events.onVMUpdateHasListener, isFalse);
-      document.body.append(e);
-      await e.onRendered.first;
-      expect(events.onVMUpdateHasListener, isTrue);
-      e.remove();
-      await e.onRendered.first;
-      expect(events.onVMUpdateHasListener, isFalse);
-    });
-    test('have effects', () async {
-      final e = new NavVMMenuElement(vm1, events);
-      document.body.append(e);
-      await e.onRendered.first;
-      expect(e.querySelectorAll(mTag).single.text, equals(vm1.displayName));
-      expect(e.querySelectorAll(miTag).length, equals(vm1.isolates.length));
-      events.add(new VMUpdateEventMock(vm: vm2));
-      await e.onRendered.first;
-      expect(e.querySelectorAll(mTag).single.text, equals(vm2.displayName));
-      expect(e.querySelectorAll(miTag).length, equals(vm2.isolates.length));
-      e.remove();
-    });
-  });
-}
diff --git a/runtime/observatory/tests/observatory_ui/nav/vm_menu/element_test.html b/runtime/observatory/tests/observatory_ui/nav/vm_menu/element_test.html
deleted file mode 100644
index f548be4..0000000
--- a/runtime/observatory/tests/observatory_ui/nav/vm_menu/element_test.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-  <meta http-equiv="X-UA-Compatible" content="IE=edge">
-  <meta name="dart.unittest" content="full-stack-traces">
-  <style>
-     .unittest-table { font-family:monospace; border:1px; }
-     .unittest-pass { background: #6b3;}
-     .unittest-fail { background: #d55;}
-     .unittest-error { background: #a11;}
-  </style>
-</head>
-<body>
-  <script type="text/javascript"
-      src="/root_dart/tools/testing/dart/test_controller.js"></script>
-  %TEST_SCRIPTS%
-</body>
-</html>
diff --git a/runtime/observatory/tests/observatory_ui/object_common/element_test.dart b/runtime/observatory/tests/observatory_ui/object_common/element_test.dart
deleted file mode 100644
index c589cbf..0000000
--- a/runtime/observatory/tests/observatory_ui/object_common/element_test.dart
+++ /dev/null
@@ -1,103 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:html';
-import 'package:test/test.dart';
-import 'package:observatory/src/elements/class_ref.dart';
-import 'package:observatory/src/elements/inbound_references.dart';
-import 'package:observatory/src/elements/object_common.dart';
-import 'package:observatory/src/elements/retaining_path.dart';
-import '../mocks.dart';
-
-main() {
-  ObjectCommonElement.tag.ensureRegistration();
-
-  final cTag = ClassRefElement.tag.name;
-  final iTag = InboundReferencesElement.tag.name;
-  final rTag = RetainingPathElement.tag.name;
-
-  const isolate = const IsolateRefMock();
-  const object = const InstanceMock();
-  final reachableSizes = new ReachableSizeRepositoryMock();
-  final retainedSizes = new RetainedSizeRepositoryMock();
-  final inbounds = new InboundReferencesRepositoryMock();
-  final paths = new RetainingPathRepositoryMock();
-  final objects = new ObjectRepositoryMock();
-  test('instantiation', () {
-    final e = new ObjectCommonElement(isolate, object, retainedSizes,
-        reachableSizes, inbounds, paths, objects);
-    expect(e, isNotNull, reason: 'element correctly created');
-    expect(e.isolate, equals(isolate));
-    expect(e.object, equals(object));
-  });
-  group('elements', () {
-    test('created after attachment', () async {
-      final e = new ObjectCommonElement(isolate, object, retainedSizes,
-          reachableSizes, inbounds, paths, objects);
-      document.body.append(e);
-      await e.onRendered.first;
-      expect(e.children.length, isNonZero, reason: 'has elements');
-      expect(e.querySelectorAll(cTag).length, equals(1));
-      expect(e.querySelectorAll(iTag).length, equals(1));
-      expect(e.querySelectorAll(rTag).length, equals(1));
-      e.remove();
-      await e.onRendered.first;
-      expect(e.children.length, isZero, reason: 'is empty');
-    });
-    test('created after attachment', () async {
-      const value = const GuardedMock<InstanceMock>.fromValue(
-          const InstanceMock(valueAsString: '10'));
-      bool invoked = false;
-      final reachableSizes = new ReachableSizeRepositoryMock(
-          getter: expectAsync2((i, id) async {
-        expect(i, equals(isolate));
-        expect(id, equals(object.id));
-        invoked = true;
-        return value;
-      }, count: 1));
-      final e = new ObjectCommonElement(isolate, object, retainedSizes,
-          reachableSizes, inbounds, paths, objects);
-      document.body.append(e);
-      await e.onRendered.first;
-      expect(invoked, isFalse);
-      expect(e.children.length, isNonZero, reason: 'has elements');
-      expect(e.querySelectorAll(cTag).length, equals(1));
-      expect(e.querySelectorAll(iTag).length, equals(1));
-      expect(e.querySelectorAll(rTag).length, equals(1));
-      e.querySelector('.reachable_size').click();
-      await e.onRendered.first;
-      expect(invoked, isTrue);
-      e.remove();
-      await e.onRendered.first;
-      expect(e.children.length, isZero, reason: 'is empty');
-    });
-    test('created after attachment', () async {
-      const value = const GuardedMock<InstanceMock>.fromValue(
-          const InstanceMock(valueAsString: '10'));
-      bool invoked = false;
-      final retainedSizes = new RetainedSizeRepositoryMock(
-          getter: expectAsync2((i, id) async {
-        expect(i, equals(isolate));
-        expect(id, equals(object.id));
-        invoked = true;
-        return value;
-      }, count: 1));
-      final e = new ObjectCommonElement(isolate, object, retainedSizes,
-          reachableSizes, inbounds, paths, objects);
-      document.body.append(e);
-      await e.onRendered.first;
-      expect(invoked, isFalse);
-      expect(e.children.length, isNonZero, reason: 'has elements');
-      expect(e.querySelectorAll(cTag).length, equals(1));
-      expect(e.querySelectorAll(iTag).length, equals(1));
-      expect(e.querySelectorAll(rTag).length, equals(1));
-      e.querySelector('.retained_size').click();
-      await e.onRendered.first;
-      expect(invoked, isTrue);
-      e.remove();
-      await e.onRendered.first;
-      expect(e.children.length, isZero, reason: 'is empty');
-    });
-  });
-}
diff --git a/runtime/observatory/tests/observatory_ui/object_common/element_test.html b/runtime/observatory/tests/observatory_ui/object_common/element_test.html
deleted file mode 100644
index 39c5683..0000000
--- a/runtime/observatory/tests/observatory_ui/object_common/element_test.html
+++ /dev/null
@@ -1,19 +0,0 @@
-
-<!DOCTYPE html>
-<html>
-<head>
-  <meta http-equiv="X-UA-Compatible" content="IE=edge">
-  <meta name="dart.unittest" content="full-stack-traces">
-  <style>
-     .unittest-table { font-family:monospace; border:1px; }
-     .unittest-pass { background: #6b3;}
-     .unittest-fail { background: #d55;}
-     .unittest-error { background: #a11;}
-  </style>
-</head>
-<body>
-  <script type="text/javascript"
-      src="/root_dart/tools/testing/dart/test_controller.js"></script>
-  %TEST_SCRIPTS%
-</body>
-</html>
diff --git a/runtime/observatory/tests/observatory_ui/objectpool_ref/element_test.dart b/runtime/observatory/tests/observatory_ui/objectpool_ref/element_test.dart
deleted file mode 100644
index 5c5ec9d..0000000
--- a/runtime/observatory/tests/observatory_ui/objectpool_ref/element_test.dart
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:html';
-import 'package:test/test.dart';
-import 'package:observatory/src/elements/objectpool_ref.dart';
-import '../mocks.dart';
-
-main() {
-  ObjectPoolRefElement.tag.ensureRegistration();
-
-  const isolate = const IsolateRefMock();
-  const pool = const ObjectPoolRefMock();
-  test('instantiation', () {
-    final e = new ObjectPoolRefElement(isolate, pool);
-    expect(e, isNotNull, reason: 'element correctly created');
-    expect(e.isolate, equals(isolate));
-    expect(e.pool, equals(pool));
-  });
-  test('elements created after attachment', () async {
-    final e = new ObjectPoolRefElement(isolate, pool);
-    document.body.append(e);
-    await e.onRendered.first;
-    expect(e.children.length, isNonZero, reason: 'has elements');
-    e.remove();
-    await e.onRendered.first;
-    expect(e.children.length, isZero, reason: 'is empty');
-  });
-}
diff --git a/runtime/observatory/tests/observatory_ui/objectpool_ref/element_test.html b/runtime/observatory/tests/observatory_ui/objectpool_ref/element_test.html
deleted file mode 100644
index f548be4..0000000
--- a/runtime/observatory/tests/observatory_ui/objectpool_ref/element_test.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-  <meta http-equiv="X-UA-Compatible" content="IE=edge">
-  <meta name="dart.unittest" content="full-stack-traces">
-  <style>
-     .unittest-table { font-family:monospace; border:1px; }
-     .unittest-pass { background: #6b3;}
-     .unittest-fail { background: #d55;}
-     .unittest-error { background: #a11;}
-  </style>
-</head>
-<body>
-  <script type="text/javascript"
-      src="/root_dart/tools/testing/dart/test_controller.js"></script>
-  %TEST_SCRIPTS%
-</body>
-</html>
diff --git a/runtime/observatory/tests/observatory_ui/objectpool_view/element_test.dart b/runtime/observatory/tests/observatory_ui/objectpool_view/element_test.dart
deleted file mode 100644
index a8c1d4a..0000000
--- a/runtime/observatory/tests/observatory_ui/objectpool_view/element_test.dart
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:html';
-import 'package:test/test.dart';
-import 'package:observatory/src/elements/nav/refresh.dart';
-import 'package:observatory/src/elements/object_common.dart';
-import 'package:observatory/src/elements/objectpool_view.dart';
-import '../mocks.dart';
-
-main() {
-  ObjectPoolViewElement.tag.ensureRegistration();
-
-  final cTag = ObjectCommonElement.tag.name;
-  final rTag = NavRefreshElement.tag.name;
-
-  const vm = const VMMock();
-  const isolate = const IsolateRefMock();
-  final events = new EventRepositoryMock();
-  final notifs = new NotificationRepositoryMock();
-  final pool = const ObjectPoolMock();
-  final pools = new ObjectPoolRepositoryMock();
-  final reachableSizes = new ReachableSizeRepositoryMock();
-  final retainedSizes = new RetainedSizeRepositoryMock();
-  final inbounds = new InboundReferencesRepositoryMock();
-  final paths = new RetainingPathRepositoryMock();
-  final objects = new ObjectRepositoryMock();
-  test('instantiation', () {
-    final e = new ObjectPoolViewElement(vm, isolate, pool, events, notifs,
-        pools, retainedSizes, reachableSizes, inbounds, paths, objects);
-    expect(e, isNotNull, reason: 'element correctly created');
-    expect(e.isolate, equals(isolate));
-    expect(e.pool, equals(pool));
-  });
-  test('elements created after attachment', () async {
-    final pools = new ObjectPoolRepositoryMock(
-        getter: expectAsync2((i, id) async {
-      expect(i, equals(isolate));
-      expect(id, equals(pool.id));
-      return pool;
-    }, count: 1));
-    final e = new ObjectPoolViewElement(vm, isolate, pool, events, notifs,
-        pools, retainedSizes, reachableSizes, inbounds, paths, objects);
-    document.body.append(e);
-    await e.onRendered.first;
-    expect(e.children.length, isNonZero, reason: 'has elements');
-    expect(e.querySelectorAll(cTag).length, equals(1));
-    (e.querySelector(rTag) as NavRefreshElement).refresh();
-    await e.onRendered.first;
-    e.remove();
-    await e.onRendered.first;
-    expect(e.children.length, isZero, reason: 'is empty');
-  });
-}
diff --git a/runtime/observatory/tests/observatory_ui/objectpool_view/element_test.html b/runtime/observatory/tests/observatory_ui/objectpool_view/element_test.html
deleted file mode 100644
index f548be4..0000000
--- a/runtime/observatory/tests/observatory_ui/objectpool_view/element_test.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-  <meta http-equiv="X-UA-Compatible" content="IE=edge">
-  <meta name="dart.unittest" content="full-stack-traces">
-  <style>
-     .unittest-table { font-family:monospace; border:1px; }
-     .unittest-pass { background: #6b3;}
-     .unittest-fail { background: #d55;}
-     .unittest-error { background: #a11;}
-  </style>
-</head>
-<body>
-  <script type="text/javascript"
-      src="/root_dart/tools/testing/dart/test_controller.js"></script>
-  %TEST_SCRIPTS%
-</body>
-</html>
diff --git a/runtime/observatory/tests/observatory_ui/objectstore_view/element_test.dart b/runtime/observatory/tests/observatory_ui/objectstore_view/element_test.dart
deleted file mode 100644
index 1c8ca9b..0000000
--- a/runtime/observatory/tests/observatory_ui/objectstore_view/element_test.dart
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:html';
-import 'package:test/test.dart';
-import 'package:observatory/src/elements/objectstore_view.dart';
-import '../mocks.dart';
-
-main() {
-  ObjectStoreViewElement.tag.ensureRegistration();
-
-  const vm = const VMMock();
-  const isolate = const IsolateRefMock();
-  final events = new EventRepositoryMock();
-  final notifs = new NotificationRepositoryMock();
-  final stores = new ObjectStoreRepositoryMock();
-  final objects = new ObjectRepositoryMock();
-  test('instantiation', () {
-    final e = new ObjectStoreViewElement(
-        vm, isolate, events, notifs, stores, objects);
-    expect(e, isNotNull, reason: 'element correctly created');
-    expect(e.isolate, equals(isolate));
-  });
-  test('elements created after attachment', () async {
-    const fields = const [
-      const NamedFieldMock(name: 'field-1'),
-      const NamedFieldMock(name: 'field-2'),
-      const NamedFieldMock(name: 'field-3')
-    ];
-    const store = const ObjectStoreMock(fields: fields);
-    final stores = new ObjectStoreRepositoryMock(
-        getter: expectAsync1((i) async {
-      expect(i, equals(isolate));
-      return store;
-    }, count: 1));
-    final objects = new ObjectRepositoryMock();
-    final e = new ObjectStoreViewElement(
-        vm, isolate, events, notifs, stores, objects);
-    document.body.append(e);
-    await e.onRendered.first;
-    expect(e.children.length, isNonZero, reason: 'has elements');
-    await e.onRendered.first;
-    expect(e.querySelectorAll('.memberItem').length, equals(fields.length));
-    e.remove();
-    await e.onRendered.first;
-    expect(e.children.length, isZero, reason: 'is empty');
-  });
-}
diff --git a/runtime/observatory/tests/observatory_ui/objectstore_view/element_test.html b/runtime/observatory/tests/observatory_ui/objectstore_view/element_test.html
deleted file mode 100644
index f548be4..0000000
--- a/runtime/observatory/tests/observatory_ui/objectstore_view/element_test.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-  <meta http-equiv="X-UA-Compatible" content="IE=edge">
-  <meta name="dart.unittest" content="full-stack-traces">
-  <style>
-     .unittest-table { font-family:monospace; border:1px; }
-     .unittest-pass { background: #6b3;}
-     .unittest-fail { background: #d55;}
-     .unittest-error { background: #a11;}
-  </style>
-</head>
-<body>
-  <script type="text/javascript"
-      src="/root_dart/tools/testing/dart/test_controller.js"></script>
-  %TEST_SCRIPTS%
-</body>
-</html>
diff --git a/runtime/observatory/tests/observatory_ui/pc_descriptors_ref/element_test.dart b/runtime/observatory/tests/observatory_ui/pc_descriptors_ref/element_test.dart
deleted file mode 100644
index 4b5c081..0000000
--- a/runtime/observatory/tests/observatory_ui/pc_descriptors_ref/element_test.dart
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:html';
-import 'package:test/test.dart';
-import 'package:observatory/src/elements/sentinel_value.dart';
-import '../mocks.dart';
-
-main() {
-  SentinelValueElement.tag.ensureRegistration();
-
-  const sentinel = const SentinelMock();
-  test('instantiation', () {
-    final e = new SentinelValueElement(sentinel);
-    expect(e, isNotNull, reason: 'element correctly created');
-    expect(e.sentinel, equals(sentinel));
-  });
-  test('elements created after attachment', () async {
-    final e = new SentinelValueElement(sentinel);
-    document.body.append(e);
-    await e.onRendered.first;
-    expect(e.text, isNotEmpty, reason: 'has text');
-    expect(e.title, isNotEmpty, reason: 'has title');
-    e.remove();
-    await e.onRendered.first;
-  });
-}
diff --git a/runtime/observatory/tests/observatory_ui/pc_descriptors_ref/element_test.html b/runtime/observatory/tests/observatory_ui/pc_descriptors_ref/element_test.html
deleted file mode 100644
index f548be4..0000000
--- a/runtime/observatory/tests/observatory_ui/pc_descriptors_ref/element_test.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-  <meta http-equiv="X-UA-Compatible" content="IE=edge">
-  <meta name="dart.unittest" content="full-stack-traces">
-  <style>
-     .unittest-table { font-family:monospace; border:1px; }
-     .unittest-pass { background: #6b3;}
-     .unittest-fail { background: #d55;}
-     .unittest-error { background: #a11;}
-  </style>
-</head>
-<body>
-  <script type="text/javascript"
-      src="/root_dart/tools/testing/dart/test_controller.js"></script>
-  %TEST_SCRIPTS%
-</body>
-</html>
diff --git a/runtime/observatory/tests/observatory_ui/persistent_handles_page/element_test.dart b/runtime/observatory/tests/observatory_ui/persistent_handles_page/element_test.dart
deleted file mode 100644
index 75cafc5..0000000
--- a/runtime/observatory/tests/observatory_ui/persistent_handles_page/element_test.dart
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:html';
-import 'package:test/test.dart';
-import 'package:observatory/src/elements/persistent_handles.dart';
-import '../mocks.dart';
-
-main() {
-  PersistentHandlesPageElement.tag.ensureRegistration();
-
-  const vm = const VMMock();
-  const isolate = const IsolateRefMock();
-  final events = new EventRepositoryMock();
-  final notifs = new NotificationRepositoryMock();
-  final repository = new PersistentHandlesRepositoryMock();
-  final objects = new ObjectRepositoryMock();
-  test('instantiation', () {
-    final e = new PersistentHandlesPageElement(
-        vm, isolate, events, notifs, repository, objects);
-    expect(e, isNotNull, reason: 'element correctly created');
-    expect(e.isolate, equals(isolate));
-  });
-  test('elements created after attachment', () async {
-    final repository = new PersistentHandlesRepositoryMock(
-        getter: expectAsync1((i) async {
-      expect(i, equals(isolate));
-      return const PersistentHandlesMock();
-    }, count: 1));
-    final objects = new ObjectRepositoryMock();
-    final e = new PersistentHandlesPageElement(
-        vm, isolate, events, notifs, repository, objects);
-    document.body.append(e);
-    await e.onRendered.first;
-    expect(e.children.length, isNonZero, reason: 'has elements');
-    e.remove();
-    await e.onRendered.first;
-    expect(e.children.length, isZero, reason: 'is empty');
-  });
-}
diff --git a/runtime/observatory/tests/observatory_ui/persistent_handles_page/element_test.html b/runtime/observatory/tests/observatory_ui/persistent_handles_page/element_test.html
deleted file mode 100644
index f548be4..0000000
--- a/runtime/observatory/tests/observatory_ui/persistent_handles_page/element_test.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-  <meta http-equiv="X-UA-Compatible" content="IE=edge">
-  <meta name="dart.unittest" content="full-stack-traces">
-  <style>
-     .unittest-table { font-family:monospace; border:1px; }
-     .unittest-pass { background: #6b3;}
-     .unittest-fail { background: #d55;}
-     .unittest-error { background: #a11;}
-  </style>
-</head>
-<body>
-  <script type="text/javascript"
-      src="/root_dart/tools/testing/dart/test_controller.js"></script>
-  %TEST_SCRIPTS%
-</body>
-</html>
diff --git a/runtime/observatory/tests/observatory_ui/ports/element_test.dart b/runtime/observatory/tests/observatory_ui/ports/element_test.dart
deleted file mode 100644
index 876f0db..0000000
--- a/runtime/observatory/tests/observatory_ui/ports/element_test.dart
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:html';
-import 'package:test/test.dart';
-import 'package:observatory/src/elements/ports.dart';
-import '../mocks.dart';
-
-main() {
-  PortsElement.tag.ensureRegistration();
-
-  const vm = const VMMock();
-  const isolate = const IsolateRefMock();
-  final events = new EventRepositoryMock();
-  final notifs = new NotificationRepositoryMock();
-  final ports = new PortsRepositoryMock();
-  final objects = new ObjectRepositoryMock();
-  test('instantiation', () {
-    final e = new PortsElement(vm, isolate, events, notifs, ports, objects);
-    expect(e, isNotNull, reason: 'element correctly created');
-    expect(e.isolate, equals(isolate));
-    expect(e.ports, equals(ports));
-  });
-  test('elements created after attachment', () async {
-    const elements = const [
-      const PortMock(name: 'port-1'),
-      const PortMock(name: 'port-2'),
-      const PortMock(name: 'port-3')
-    ];
-    const isolatePorts = const PortsAndHandlesMock(elements: elements);
-    final ports = new PortsRepositoryMock(
-        getter: expectAsync1((i) async {
-      expect(i, equals(isolate));
-      return isolatePorts;
-    }, count: 1));
-    final objects = new ObjectRepositoryMock();
-    final e = new PortsElement(vm, isolate, events, notifs, ports, objects);
-    document.body.append(e);
-    await e.onRendered.first;
-    expect(e.children.length, isNonZero, reason: 'has elements');
-    await e.onRendered.first;
-    expect(e.querySelectorAll('.port-number').length, equals(elements.length));
-    e.remove();
-    await e.onRendered.first;
-    expect(e.children.length, isZero, reason: 'is empty');
-  });
-}
diff --git a/runtime/observatory/tests/observatory_ui/ports/element_test.html b/runtime/observatory/tests/observatory_ui/ports/element_test.html
deleted file mode 100644
index f548be4..0000000
--- a/runtime/observatory/tests/observatory_ui/ports/element_test.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-  <meta http-equiv="X-UA-Compatible" content="IE=edge">
-  <meta name="dart.unittest" content="full-stack-traces">
-  <style>
-     .unittest-table { font-family:monospace; border:1px; }
-     .unittest-pass { background: #6b3;}
-     .unittest-fail { background: #d55;}
-     .unittest-error { background: #a11;}
-  </style>
-</head>
-<body>
-  <script type="text/javascript"
-      src="/root_dart/tools/testing/dart/test_controller.js"></script>
-  %TEST_SCRIPTS%
-</body>
-</html>
diff --git a/runtime/observatory/tests/observatory_ui/retaining_path/element_test.dart b/runtime/observatory/tests/observatory_ui/retaining_path/element_test.dart
deleted file mode 100644
index 2f10ece..0000000
--- a/runtime/observatory/tests/observatory_ui/retaining_path/element_test.dart
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:html';
-import 'package:test/test.dart';
-import 'package:observatory/src/elements/curly_block.dart';
-import 'package:observatory/src/elements/instance_ref.dart';
-import 'package:observatory/src/elements/retaining_path.dart';
-import '../mocks.dart';
-
-main() {
-  RetainingPathElement.tag.ensureRegistration();
-
-  final cTag = CurlyBlockElement.tag.name;
-  final iTag = InstanceRefElement.tag.name;
-
-  const isolate = const IsolateRefMock();
-  const object = const InstanceRefMock();
-  final paths = new RetainingPathRepositoryMock();
-  final objects = new ObjectRepositoryMock();
-  test('instantiation', () {
-    final e = new RetainingPathElement(isolate, object, paths, objects);
-    expect(e, isNotNull, reason: 'element correctly created');
-    expect(e.isolate, equals(isolate));
-    expect(e.object, equals(object));
-  });
-  test('elements created after attachment', () async {
-    const source = const InstanceRefMock(id: 'source-id', name: 'source_name');
-    const path = const RetainingPathMock(
-        elements: const [const RetainingPathItemMock(source: source)]);
-    bool invoked = false;
-    final paths = new RetainingPathRepositoryMock(
-        getter: expectAsync2((i, id) async {
-      expect(i, equals(isolate));
-      expect(id, equals(object.id));
-      invoked = true;
-      return path;
-    }, count: 1));
-    final objects = new ObjectRepositoryMock();
-    final e = new RetainingPathElement(isolate, object, paths, objects);
-    document.body.append(e);
-    await e.onRendered.first;
-    expect(invoked, isFalse);
-    expect(e.children.length, isNonZero, reason: 'has elements');
-    expect(e.querySelectorAll(iTag).length, isZero);
-    (e.querySelector(cTag) as CurlyBlockElement).toggle();
-    await e.onRendered.first;
-    expect(invoked, isTrue);
-    expect(e.querySelectorAll(iTag).length, equals(1));
-    e.remove();
-    await e.onRendered.first;
-    expect(e.children.length, isZero, reason: 'is empty');
-  });
-}
diff --git a/runtime/observatory/tests/observatory_ui/retaining_path/element_test.html b/runtime/observatory/tests/observatory_ui/retaining_path/element_test.html
deleted file mode 100644
index f548be4..0000000
--- a/runtime/observatory/tests/observatory_ui/retaining_path/element_test.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-  <meta http-equiv="X-UA-Compatible" content="IE=edge">
-  <meta name="dart.unittest" content="full-stack-traces">
-  <style>
-     .unittest-table { font-family:monospace; border:1px; }
-     .unittest-pass { background: #6b3;}
-     .unittest-fail { background: #d55;}
-     .unittest-error { background: #a11;}
-  </style>
-</head>
-<body>
-  <script type="text/javascript"
-      src="/root_dart/tools/testing/dart/test_controller.js"></script>
-  %TEST_SCRIPTS%
-</body>
-</html>
diff --git a/runtime/observatory/tests/observatory_ui/sample_buffer_control/element_test.dart b/runtime/observatory/tests/observatory_ui/sample_buffer_control/element_test.dart
deleted file mode 100644
index 9820989..0000000
--- a/runtime/observatory/tests/observatory_ui/sample_buffer_control/element_test.dart
+++ /dev/null
@@ -1,166 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:html';
-import 'dart:async';
-import 'package:test/test.dart';
-import 'package:observatory/models.dart' as M;
-import 'package:observatory/src/elements/sample_buffer_control.dart';
-import '../mocks.dart';
-
-main() {
-  SampleBufferControlElement.tag.ensureRegistration();
-
-  const vm = const VMMock();
-
-  group('instantiation', () {
-    SampleProfileLoadingProgressMock progress;
-    StreamController<SampleProfileLoadingProgressEventMock> events;
-    setUp(() {
-      progress = new SampleProfileLoadingProgressMock();
-      events = new StreamController<SampleProfileLoadingProgressEventMock>();
-    });
-    test('no additional parameters', () {
-      final e = new SampleBufferControlElement(vm, progress, events.stream);
-      expect(e, isNotNull, reason: 'element correctly created');
-      expect(e.progress, equals(progress));
-      expect(e.selectedTag, equals(M.SampleProfileTag.none));
-      expect(e.showTag, isTrue);
-    });
-    test('selected tag', () {
-      const tag = M.SampleProfileTag.userOnly;
-      final e = new SampleBufferControlElement(vm, progress, events.stream,
-          selectedTag: tag);
-      expect(e, isNotNull, reason: 'element correctly created');
-      expect(e.progress, equals(progress));
-      expect(e.selectedTag, equals(tag));
-      expect(e.showTag, isTrue);
-    });
-    test('show tag (true)', () {
-      final e = new SampleBufferControlElement(vm, progress, events.stream,
-          showTag: true);
-      expect(e, isNotNull, reason: 'element correctly created');
-      expect(e.progress, equals(progress));
-      expect(e.selectedTag, equals(M.SampleProfileTag.none));
-      expect(e.showTag, isTrue);
-    });
-    test('show tag (false)', () {
-      final e = new SampleBufferControlElement(vm, progress, events.stream,
-          showTag: false);
-      expect(e, isNotNull, reason: 'element correctly created');
-      expect(e.progress, equals(progress));
-      expect(e.selectedTag, equals(M.SampleProfileTag.none));
-      expect(e.showTag, isFalse);
-    });
-  });
-  group('elements', () {
-    SampleProfileLoadingProgressMock progress;
-    StreamController<SampleProfileLoadingProgressEventMock> events;
-    setUp(() {
-      progress = new SampleProfileLoadingProgressMock();
-      events = new StreamController<SampleProfileLoadingProgressEventMock>();
-    });
-    test('created after attachment', () async {
-      final e = new SampleBufferControlElement(vm, progress, events.stream);
-      document.body.append(e);
-      await e.onRendered.first;
-      expect(e.children.length, isNonZero, reason: 'has elements');
-      e.remove();
-      await e.onRendered.first;
-      expect(e.children.length, isZero, reason: 'is empty');
-    });
-    test('listen for status changes', () async {
-      final e = new SampleBufferControlElement(vm, progress, events.stream);
-      expect(events.hasListener, isFalse);
-      document.body.append(e);
-      await e.onRendered.first;
-      expect(events.hasListener, isTrue);
-      events.add(new SampleProfileLoadingProgressEventMock(progress: progress));
-      events.close();
-      await e.onRendered.first;
-      e.remove();
-      await e.onRendered.first;
-    });
-    test('follow updates changes', () async {
-      final e = new SampleBufferControlElement(vm, progress, events.stream);
-      document.body.append(e);
-      await e.onRendered.first;
-      expect(e.querySelector('select'), isNull);
-      events.add(new SampleProfileLoadingProgressEventMock(
-          progress: new SampleProfileLoadingProgressMock(
-              status: M.SampleProfileLoadingStatus.fetching)));
-      await e.onRendered.first;
-      expect(e.querySelector('select'), isNull);
-      events.add(new SampleProfileLoadingProgressEventMock(
-          progress: new SampleProfileLoadingProgressMock(
-              status: M.SampleProfileLoadingStatus.loading)));
-      await e.onRendered.first;
-      expect(e.querySelector('select'), isNull);
-      events.add(new SampleProfileLoadingProgressEventMock(
-          progress: new SampleProfileLoadingProgressMock(
-              status: M.SampleProfileLoadingStatus.loaded,
-              profile: new SampleProfileMock())));
-      events.close();
-      await e.onRendered.first;
-      expect(e.querySelector('select'), isNotNull);
-      e.remove();
-      await e.onRendered.first;
-    });
-    test('follow updates changes (no tag)', () async {
-      final e = new SampleBufferControlElement(vm, progress, events.stream,
-          showTag: false);
-      document.body.append(e);
-      await e.onRendered.first;
-      expect(e.querySelector('select'), isNull);
-      events.add(new SampleProfileLoadingProgressEventMock(
-          progress: new SampleProfileLoadingProgressMock(
-              status: M.SampleProfileLoadingStatus.fetching)));
-      await e.onRendered.first;
-      expect(e.querySelector('select'), isNull);
-      events.add(new SampleProfileLoadingProgressEventMock(
-          progress: new SampleProfileLoadingProgressMock(
-              status: M.SampleProfileLoadingStatus.loading)));
-      await e.onRendered.first;
-      expect(e.querySelector('select'), isNull);
-      events.add(new SampleProfileLoadingProgressEventMock(
-          progress: new SampleProfileLoadingProgressMock(
-              status: M.SampleProfileLoadingStatus.loaded,
-              profile: new SampleProfileMock())));
-      await e.onRendered.first;
-      expect(e.querySelector('select'), isNull);
-      e.remove();
-      await e.onRendered.first;
-    });
-  });
-  group('events', () {
-    SampleProfileLoadingProgressMock progress;
-    StreamController<SampleProfileLoadingProgressEventMock> events;
-    setUp(() {
-      progress = new SampleProfileLoadingProgressMock();
-      events = new StreamController<SampleProfileLoadingProgressEventMock>();
-    });
-    test('onModeChange', () async {
-      final e = new SampleBufferControlElement(vm, progress, events.stream);
-      document.body.append(e);
-      await e.onRendered.first;
-      events.add(new SampleProfileLoadingProgressEventMock(
-          progress: new SampleProfileLoadingProgressMock(
-              status: M.SampleProfileLoadingStatus.loaded,
-              profile: new SampleProfileMock())));
-      await e.onRendered.first;
-      expect(e.selectedTag, equals(M.SampleProfileTag.none));
-      e.onTagChange.listen(expectAsync1((_) {
-        expect(e.selectedTag, equals(M.SampleProfileTag.userOnly));
-      }, count: 1));
-      final select = (e.querySelector('.tag-select') as SelectElement);
-      select.selectedIndex = select.options.indexOf((select.options.toSet()
-            ..removeAll(select.selectedOptions))
-          .toList()
-          .first);
-      select.dispatchEvent(new Event("change"));
-      e.remove();
-      await e.onRendered.first;
-    });
-  });
-}
diff --git a/runtime/observatory/tests/observatory_ui/sample_buffer_control/element_test.html b/runtime/observatory/tests/observatory_ui/sample_buffer_control/element_test.html
deleted file mode 100644
index f548be4..0000000
--- a/runtime/observatory/tests/observatory_ui/sample_buffer_control/element_test.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-  <meta http-equiv="X-UA-Compatible" content="IE=edge">
-  <meta name="dart.unittest" content="full-stack-traces">
-  <style>
-     .unittest-table { font-family:monospace; border:1px; }
-     .unittest-pass { background: #6b3;}
-     .unittest-fail { background: #d55;}
-     .unittest-error { background: #a11;}
-  </style>
-</head>
-<body>
-  <script type="text/javascript"
-      src="/root_dart/tools/testing/dart/test_controller.js"></script>
-  %TEST_SCRIPTS%
-</body>
-</html>
diff --git a/runtime/observatory/tests/observatory_ui/script_ref/element_test.dart b/runtime/observatory/tests/observatory_ui/script_ref/element_test.dart
deleted file mode 100644
index ae6d7f5..0000000
--- a/runtime/observatory/tests/observatory_ui/script_ref/element_test.dart
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:html';
-import 'package:test/test.dart';
-import 'package:observatory/src/elements/script_ref.dart';
-import '../mocks.dart';
-
-main() {
-  ScriptRefElement.tag.ensureRegistration();
-
-  const isolate = const IsolateRefMock(id: 'isolate-id');
-  const file = 'filename.dart';
-  const ref = const ScriptRefMock(id: 'script-id', uri: 'package/$file');
-  group('instantiation', () {
-    test('no position', () {
-      final e = new ScriptRefElement(isolate, ref);
-      expect(e, isNotNull, reason: 'element correctly created');
-      expect(e.isolate, equals(isolate));
-      expect(e.script, equals(ref));
-    });
-  });
-  test('elements created after attachment', () async {
-    final e = new ScriptRefElement(isolate, ref);
-    document.body.append(e);
-    await e.onRendered.first;
-    expect(e.children.length, isNonZero, reason: 'has elements');
-    expect(e.innerHtml.contains(isolate.id), isTrue,
-        reason: 'no message in the component');
-    expect(e.innerHtml.contains(file), isTrue,
-        reason: 'no message in the component');
-    e.remove();
-    await e.onRendered.first;
-    expect(e.children.length, isZero, reason: 'is empty');
-  });
-}
diff --git a/runtime/observatory/tests/observatory_ui/script_ref/element_test.html b/runtime/observatory/tests/observatory_ui/script_ref/element_test.html
deleted file mode 100644
index f548be4..0000000
--- a/runtime/observatory/tests/observatory_ui/script_ref/element_test.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-  <meta http-equiv="X-UA-Compatible" content="IE=edge">
-  <meta name="dart.unittest" content="full-stack-traces">
-  <style>
-     .unittest-table { font-family:monospace; border:1px; }
-     .unittest-pass { background: #6b3;}
-     .unittest-fail { background: #d55;}
-     .unittest-error { background: #a11;}
-  </style>
-</head>
-<body>
-  <script type="text/javascript"
-      src="/root_dart/tools/testing/dart/test_controller.js"></script>
-  %TEST_SCRIPTS%
-</body>
-</html>
diff --git a/runtime/observatory/tests/observatory_ui/sentinel_value/element_test.dart b/runtime/observatory/tests/observatory_ui/sentinel_value/element_test.dart
deleted file mode 100644
index 69d3b11..0000000
--- a/runtime/observatory/tests/observatory_ui/sentinel_value/element_test.dart
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:html';
-import 'package:test/test.dart';
-import 'package:observatory/src/elements/pc_descriptors_ref.dart';
-import '../mocks.dart';
-
-main() {
-  PcDescriptorsRefElement.tag.ensureRegistration();
-
-  const isolate = const IsolateRefMock();
-  const descriptors = const PcDescriptorsRefMock();
-  test('instantiation', () {
-    final e = new PcDescriptorsRefElement(isolate, descriptors);
-    expect(e, isNotNull, reason: 'element correctly created');
-    expect(e.isolate, equals(isolate));
-    expect(e.descriptors, equals(descriptors));
-  });
-  test('elements created after attachment', () async {
-    final e = new PcDescriptorsRefElement(isolate, descriptors);
-    document.body.append(e);
-    await e.onRendered.first;
-    expect(e.children.length, isNonZero, reason: 'has elements');
-    e.remove();
-    await e.onRendered.first;
-    expect(e.children.length, isZero, reason: 'is empty');
-  });
-}
diff --git a/runtime/observatory/tests/observatory_ui/sentinel_value/element_test.html b/runtime/observatory/tests/observatory_ui/sentinel_value/element_test.html
deleted file mode 100644
index f548be4..0000000
--- a/runtime/observatory/tests/observatory_ui/sentinel_value/element_test.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-  <meta http-equiv="X-UA-Compatible" content="IE=edge">
-  <meta name="dart.unittest" content="full-stack-traces">
-  <style>
-     .unittest-table { font-family:monospace; border:1px; }
-     .unittest-pass { background: #6b3;}
-     .unittest-fail { background: #d55;}
-     .unittest-error { background: #a11;}
-  </style>
-</head>
-<body>
-  <script type="text/javascript"
-      src="/root_dart/tools/testing/dart/test_controller.js"></script>
-  %TEST_SCRIPTS%
-</body>
-</html>
diff --git a/runtime/observatory/tests/observatory_ui/source_link/element_test.dart b/runtime/observatory/tests/observatory_ui/source_link/element_test.dart
deleted file mode 100644
index a6c10bb..0000000
--- a/runtime/observatory/tests/observatory_ui/source_link/element_test.dart
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:html';
-import 'package:test/test.dart';
-import 'package:observatory/src/elements/source_link.dart';
-import '../mocks.dart';
-
-main() {
-  SourceLinkElement.tag.ensureRegistration();
-
-  const isolate = const IsolateRefMock(id: 'isolate-id');
-  const script_id = 'script-id';
-  const file = 'filename.dart';
-  final script = new ScriptMock(
-      id: script_id,
-      uri: 'package/$file',
-      tokenToLine: (int token) => 1,
-      tokenToCol: (int token) => 2);
-  final location =
-      new SourceLocationMock(script: script, tokenPos: 0, endTokenPos: 1);
-  final repository = new ScriptRepositoryMock();
-  test('instantiation', () {
-    final e = new SourceLinkElement(isolate, location, repository);
-    expect(e, isNotNull, reason: 'element correctly created');
-    expect(e.isolate, equals(isolate));
-    expect(e.location, equals(location));
-  });
-  test('elements created after attachment', () async {
-    bool rendered = false;
-    final repository = new ScriptRepositoryMock(
-        getter: expectAsync2((isolate, id) async {
-      expect(rendered, isFalse);
-      expect(id, equals(script_id));
-      return script;
-    }, count: 1));
-    final e = new SourceLinkElement(isolate, location, repository);
-    document.body.append(e);
-    await e.onRendered.first;
-    rendered = true;
-    expect(e.children.length, isNonZero, reason: 'has elements');
-    expect(e.innerHtml.contains(isolate.id), isTrue,
-        reason: 'no message in the component');
-    expect(e.innerHtml.contains(file), isTrue,
-        reason: 'no message in the component');
-    e.remove();
-    await e.onRendered.first;
-    expect(e.children.length, isZero, reason: 'is empty');
-  });
-}
diff --git a/runtime/observatory/tests/observatory_ui/source_link/element_test.html b/runtime/observatory/tests/observatory_ui/source_link/element_test.html
deleted file mode 100644
index f548be4..0000000
--- a/runtime/observatory/tests/observatory_ui/source_link/element_test.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-  <meta http-equiv="X-UA-Compatible" content="IE=edge">
-  <meta name="dart.unittest" content="full-stack-traces">
-  <style>
-     .unittest-table { font-family:monospace; border:1px; }
-     .unittest-pass { background: #6b3;}
-     .unittest-fail { background: #d55;}
-     .unittest-error { background: #a11;}
-  </style>
-</head>
-<body>
-  <script type="text/javascript"
-      src="/root_dart/tools/testing/dart/test_controller.js"></script>
-  %TEST_SCRIPTS%
-</body>
-</html>
diff --git a/runtime/observatory/tests/observatory_ui/stack_trace_tree_config/element_test.dart b/runtime/observatory/tests/observatory_ui/stack_trace_tree_config/element_test.dart
deleted file mode 100644
index 3649041..0000000
--- a/runtime/observatory/tests/observatory_ui/stack_trace_tree_config/element_test.dart
+++ /dev/null
@@ -1,185 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:html';
-import 'package:test/test.dart';
-import 'package:observatory/models.dart' as M;
-import 'package:observatory/src/elements/stack_trace_tree_config.dart';
-
-main() {
-  StackTraceTreeConfigElement.tag.ensureRegistration();
-
-  group('instantiation', () {
-    test('default', () {
-      final e = new StackTraceTreeConfigElement();
-      expect(e, isNotNull, reason: 'element correctly created');
-      expect(e.showMode, isTrue);
-      expect(e.showDirection, isTrue);
-      expect(e.showFilter, isTrue);
-      expect(e.filter, equals(''));
-      expect(e.mode, equals(ProfileTreeMode.function));
-      expect(e.direction, equals(M.ProfileTreeDirection.exclusive));
-    });
-    test('showMode', () {
-      final e = new StackTraceTreeConfigElement(showMode: false);
-      expect(e, isNotNull, reason: 'element correctly created');
-      expect(e.showMode, isFalse);
-      expect(e.showDirection, isTrue);
-      expect(e.showFilter, isTrue);
-      expect(e.filter, equals(''));
-      expect(e.mode, equals(ProfileTreeMode.function));
-      expect(e.direction, equals(M.ProfileTreeDirection.exclusive));
-    });
-    test('showDirection', () {
-      final e = new StackTraceTreeConfigElement(showDirection: false);
-      expect(e, isNotNull, reason: 'element correctly created');
-      expect(e.showMode, isTrue);
-      expect(e.showDirection, isFalse);
-      expect(e.showFilter, isTrue);
-      expect(e.filter, equals(''));
-      expect(e.mode, equals(ProfileTreeMode.function));
-      expect(e.direction, equals(M.ProfileTreeDirection.exclusive));
-    });
-    test('showFilter', () {
-      final e = new StackTraceTreeConfigElement(showFilter: false);
-      expect(e, isNotNull, reason: 'element correctly created');
-      expect(e.showMode, isTrue);
-      expect(e.showDirection, isTrue);
-      expect(e.showFilter, isFalse);
-      expect(e.filter, equals(''));
-      expect(e.mode, equals(ProfileTreeMode.function));
-      expect(e.direction, equals(M.ProfileTreeDirection.exclusive));
-    });
-    test('filter', () {
-      final filter = 'filter-string';
-      final e = new StackTraceTreeConfigElement(filter: filter);
-      expect(e, isNotNull, reason: 'element correctly created');
-      expect(e.showMode, isTrue);
-      expect(e.showDirection, isTrue);
-      expect(e.showFilter, isTrue);
-      expect(e.filter, equals(filter));
-      expect(e.mode, equals(ProfileTreeMode.function));
-      expect(e.direction, equals(M.ProfileTreeDirection.exclusive));
-    });
-    test('mode', () {
-      final e = new StackTraceTreeConfigElement(mode: ProfileTreeMode.code);
-      expect(e, isNotNull, reason: 'element correctly created');
-      expect(e.showMode, isTrue);
-      expect(e.showDirection, isTrue);
-      expect(e.showFilter, isTrue);
-      expect(e.filter, equals(''));
-      expect(e.mode, equals(ProfileTreeMode.code));
-      expect(e.direction, equals(M.ProfileTreeDirection.exclusive));
-    });
-    test('default', () {
-      final e = new StackTraceTreeConfigElement(
-          direction: M.ProfileTreeDirection.inclusive);
-      expect(e, isNotNull, reason: 'element correctly created');
-      expect(e.showMode, isTrue);
-      expect(e.showDirection, isTrue);
-      expect(e.showFilter, isTrue);
-      expect(e.filter, equals(''));
-      expect(e.mode, equals(ProfileTreeMode.function));
-      expect(e.direction, equals(M.ProfileTreeDirection.inclusive));
-    });
-  });
-  group('elements', () {
-    test('created after attachment', () async {
-      final e = new StackTraceTreeConfigElement();
-      document.body.append(e);
-      await e.onRendered.first;
-      expect(e.children.length, isNonZero, reason: 'has elements');
-      e.remove();
-      await e.onRendered.first;
-      expect(e.children.length, isZero, reason: 'is empty');
-    });
-    test('react to mode change', () async {
-      final e = new StackTraceTreeConfigElement();
-      document.body.append(e);
-      await e.onRendered.first;
-      expect(e.mode, equals(ProfileTreeMode.function));
-      e.mode = ProfileTreeMode.code;
-      await e.onRendered.first;
-      expect(e.mode, equals(ProfileTreeMode.code));
-      e.remove();
-      await e.onRendered.first;
-      expect(e.children.length, isZero, reason: 'is empty');
-    });
-    test('react to direction change', () async {
-      final e = new StackTraceTreeConfigElement();
-      document.body.append(e);
-      await e.onRendered.first;
-      expect(e.direction, equals(M.ProfileTreeDirection.exclusive));
-      e.direction = M.ProfileTreeDirection.inclusive;
-      await e.onRendered.first;
-      expect(e.direction, equals(M.ProfileTreeDirection.inclusive));
-      e.remove();
-      await e.onRendered.first;
-      expect(e.children.length, isZero, reason: 'is empty');
-    });
-    test('react to filter change', () async {
-      final filter = 'filter-string';
-      final e = new StackTraceTreeConfigElement();
-      document.body.append(e);
-      await e.onRendered.first;
-      expect(e.filter, equals(''));
-      e.filter = filter;
-      await e.onRendered.first;
-      expect(e.filter, equals(filter));
-      e.remove();
-      await e.onRendered.first;
-      expect(e.children.length, isZero, reason: 'is empty');
-    });
-  });
-  group('events', () {
-    test('onModeChange', () async {
-      final e = new StackTraceTreeConfigElement();
-      document.body.append(e);
-      await e.onRendered.first;
-      expect(e.mode, equals(ProfileTreeMode.function));
-      e.onModeChange.listen(expectAsync1((_) {
-        expect(e.mode, equals(ProfileTreeMode.code));
-      }, count: 1));
-      final select = (e.querySelector('.mode-select') as SelectElement);
-      select.selectedIndex = select.options.indexOf((select.options.toSet()
-            ..removeAll(select.selectedOptions))
-          .toList()
-          .first);
-      select.dispatchEvent(new Event("change"));
-      e.remove();
-      await e.onRendered.first;
-    });
-    test('onDirectionChange', () async {
-      final e = new StackTraceTreeConfigElement();
-      document.body.append(e);
-      await e.onRendered.first;
-      expect(e.direction, equals(M.ProfileTreeDirection.exclusive));
-      e.onDirectionChange.listen(expectAsync1((_) {
-        expect(e.direction, equals(M.ProfileTreeDirection.inclusive));
-      }, count: 1));
-      final select = (e.querySelector('.direction-select') as SelectElement);
-      select.selectedIndex = select.options.indexOf((select.options.toSet()
-            ..removeAll(select.selectedOptions))
-          .toList()
-          .first);
-      select.dispatchEvent(new Event("change"));
-      e.remove();
-      await e.onRendered.first;
-    });
-    test('onFilterChange', () async {
-      final e = new StackTraceTreeConfigElement();
-      document.body.append(e);
-      await e.onRendered.first;
-      expect(e.direction, equals(M.ProfileTreeDirection.exclusive));
-      e.onFilterChange.listen(expectAsync1((_) {
-        expect(e.filter, equals('value'));
-      }, count: 1));
-      var input = (e.querySelector('input') as TextInputElement);
-      input.value = 'value';
-      input.dispatchEvent(new Event("change"));
-      e.remove();
-      await e.onRendered.first;
-    });
-  });
-}
diff --git a/runtime/observatory/tests/observatory_ui/stack_trace_tree_config/element_test.html b/runtime/observatory/tests/observatory_ui/stack_trace_tree_config/element_test.html
deleted file mode 100644
index f548be4..0000000
--- a/runtime/observatory/tests/observatory_ui/stack_trace_tree_config/element_test.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-  <meta http-equiv="X-UA-Compatible" content="IE=edge">
-  <meta name="dart.unittest" content="full-stack-traces">
-  <style>
-     .unittest-table { font-family:monospace; border:1px; }
-     .unittest-pass { background: #6b3;}
-     .unittest-fail { background: #d55;}
-     .unittest-error { background: #a11;}
-  </style>
-</head>
-<body>
-  <script type="text/javascript"
-      src="/root_dart/tools/testing/dart/test_controller.js"></script>
-  %TEST_SCRIPTS%
-</body>
-</html>
diff --git a/runtime/observatory/tests/observatory_ui/unknown_ref/element_test.dart b/runtime/observatory/tests/observatory_ui/unknown_ref/element_test.dart
deleted file mode 100644
index 66f907d..0000000
--- a/runtime/observatory/tests/observatory_ui/unknown_ref/element_test.dart
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:html';
-import 'package:test/test.dart';
-import 'package:observatory/src/elements/unknown_ref.dart';
-import '../mocks.dart';
-
-main() {
-  UnknownObjectRefElement.tag.ensureRegistration();
-
-  const isolate = const IsolateRefMock();
-  const obj = const UnknownObjectRefMock();
-  test('instantiation', () {
-    final e = new UnknownObjectRefElement(isolate, obj);
-    expect(e, isNotNull, reason: 'element correctly created');
-    expect(e.isolate, equals(isolate));
-    expect(e.obj, equals(obj));
-  });
-  test('elements created after attachment', () async {
-    final e = new UnknownObjectRefElement(isolate, obj);
-    document.body.append(e);
-    await e.onRendered.first;
-    expect(e.children.length, isNonZero, reason: 'has elements');
-    e.remove();
-    await e.onRendered.first;
-    expect(e.children.length, isZero, reason: 'is empty');
-  });
-}
diff --git a/runtime/observatory/tests/observatory_ui/unknown_ref/element_test.html b/runtime/observatory/tests/observatory_ui/unknown_ref/element_test.html
deleted file mode 100644
index f548be4..0000000
--- a/runtime/observatory/tests/observatory_ui/unknown_ref/element_test.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-  <meta http-equiv="X-UA-Compatible" content="IE=edge">
-  <meta name="dart.unittest" content="full-stack-traces">
-  <style>
-     .unittest-table { font-family:monospace; border:1px; }
-     .unittest-pass { background: #6b3;}
-     .unittest-fail { background: #d55;}
-     .unittest-error { background: #a11;}
-  </style>
-</head>
-<body>
-  <script type="text/javascript"
-      src="/root_dart/tools/testing/dart/test_controller.js"></script>
-  %TEST_SCRIPTS%
-</body>
-</html>
diff --git a/runtime/observatory/tests/observatory_ui/view_footer/element_test.dart b/runtime/observatory/tests/observatory_ui/view_footer/element_test.dart
deleted file mode 100644
index cc0e635..0000000
--- a/runtime/observatory/tests/observatory_ui/view_footer/element_test.dart
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:html';
-import 'package:test/test.dart';
-import 'package:observatory/src/elements/view_footer.dart';
-
-main() {
-  ViewFooterElement.tag.ensureRegistration();
-
-  test('instantiation', () {
-    final e = new ViewFooterElement();
-    expect(e, isNotNull, reason: 'element correctly created');
-  });
-  test('elements created', () async {
-    final e = new ViewFooterElement();
-    document.body.append(e);
-    await e.onRendered.first;
-    expect(e.children.length, isNonZero, reason: 'has elements');
-    e.remove();
-    await e.onRendered.first;
-    expect(e.children.length, isZero, reason: 'is empty');
-  });
-}
diff --git a/runtime/observatory/tests/observatory_ui/view_footer/element_test.html b/runtime/observatory/tests/observatory_ui/view_footer/element_test.html
deleted file mode 100644
index f548be4..0000000
--- a/runtime/observatory/tests/observatory_ui/view_footer/element_test.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-  <meta http-equiv="X-UA-Compatible" content="IE=edge">
-  <meta name="dart.unittest" content="full-stack-traces">
-  <style>
-     .unittest-table { font-family:monospace; border:1px; }
-     .unittest-pass { background: #6b3;}
-     .unittest-fail { background: #d55;}
-     .unittest-error { background: #a11;}
-  </style>
-</head>
-<body>
-  <script type="text/javascript"
-      src="/root_dart/tools/testing/dart/test_controller.js"></script>
-  %TEST_SCRIPTS%
-</body>
-</html>
diff --git a/runtime/observatory/tests/observatory_ui/virtual_tree/element_test.dart b/runtime/observatory/tests/observatory_ui/virtual_tree/element_test.dart
deleted file mode 100644
index 2520f74..0000000
--- a/runtime/observatory/tests/observatory_ui/virtual_tree/element_test.dart
+++ /dev/null
@@ -1,112 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:html';
-import 'package:test/test.dart';
-import 'package:observatory/src/elements/containers/virtual_collection.dart';
-import 'package:observatory/src/elements/containers/virtual_tree.dart';
-
-main() {
-  VirtualTreeElement.tag.ensureRegistration();
-
-  final cTag = VirtualCollectionElement.tag.name;
-
-  var container;
-  setUp(() {
-    container = document.body.getElementsByClassName('test_container').first;
-  });
-  group('instantiation', () {
-    test('default', () {
-      final e = new VirtualTreeElement((_) {}, (_1, _2, _3) {}, (_) {});
-      expect(e, isNotNull, reason: 'element correctly created');
-      expect(e.items, isNotNull, reason: 'items not null');
-      expect(e.items, isEmpty, reason: 'no items');
-    });
-    test('items: []', () {
-      final items = ["1", 2, {}];
-      final e =
-          new VirtualTreeElement((_) {}, (_1, _2, _3) {}, (_) {}, items: items);
-      expect(e, isNotNull, reason: 'element correctly created');
-      expect(e.items, isNot(same(items)), reason: 'avoid side effect');
-      expect(e.items, equals(items), reason: 'same items');
-    });
-  });
-  test('elements created after attachment', () async {
-    final create = (toggle) => new DivElement()..classes = ['test_item'];
-    final update = (HtmlElement el, item, depth) {
-      el.text = item.toString();
-    };
-    final children = (item) => [];
-    final items = ["1", 2, {}];
-    final e = new VirtualTreeElement(create, update, children);
-    container.append(e);
-    await e.onRendered.first;
-    expect(e.children.length, isNonZero, reason: 'has elements');
-    expect(e.querySelectorAll(cTag).length, same(1));
-    e.remove();
-    await e.onRendered.first;
-    expect(e.children.length, isZero, reason: 'is empty');
-  });
-  test('expand single child', () async {
-    const max_depth = 100000;
-    final create = (toggle) => new DivElement()..classes = ['test_item'];
-    final update = (HtmlElement el, item, depth) {
-      el.text = item.toString();
-    };
-    final children = (item) => item >= max_depth ? [] : [item + 1];
-    final items = [0];
-    final e = new VirtualTreeElement(create, update, children, items: items);
-    container.append(e);
-    await e.onRendered.first;
-    expect(e.children.length, isNonZero, reason: 'has elements');
-    final VirtualCollectionElement collection = e.querySelectorAll(cTag).first;
-    expect(collection.items.length, equals(1), reason: 'begin');
-    e.expand(0, autoExpandSingleChildNodes: true);
-    await e.onRendered.first;
-    expect(collection.items.length, equals(max_depth + 1), reason: 'expanded');
-    e.collapse(0, autoCollapseSingleChildNodes: true);
-    await e.onRendered.first;
-    expect(collection.items.length, equals(1), reason: 'collapsed');
-    e.remove();
-    await e.onRendered.first;
-    expect(e.children.length, isZero, reason: 'is empty');
-  });
-
-  test('expand whole tree', () async {
-    const max_depth = 100000;
-    final create = (toggle) => new DivElement()..classes = ['test_item'];
-    final update = (HtmlElement el, item, depth) {
-      el.text = item.toString();
-    };
-    // We want to generated a tree that doesn't collapse to a chain of items
-    // while avoiding to generate an exponential number of items
-    final children = (item) {
-      if (item < 2 * max_depth) {
-        if (item % 200 == 0) {
-          return [item + 1, item + 2];
-        } else if (item % 2 == 0) {
-          return [item + 2];
-        }
-      }
-      return [];
-    };
-    final items = [0];
-    final e = new VirtualTreeElement(create, update, children, items: items);
-    container.append(e);
-    await e.onRendered.first;
-    expect(e.children.length, isNonZero, reason: 'has elements');
-    final VirtualCollectionElement collection = e.querySelectorAll(cTag).first;
-    expect(collection.items.length, equals(1), reason: 'begin');
-    e.expand(0, autoExpandWholeTree: true);
-    await e.onRendered.first;
-    expect(collection.items.length, equals(max_depth + max_depth / 100 + 1),
-        reason: 'expanded');
-    e.collapse(0, autoCollapseWholeTree: true);
-    await e.onRendered.first;
-    expect(collection.items.length, equals(1), reason: 'collapsed');
-    e.remove();
-    await e.onRendered.first;
-    expect(e.children.length, isZero, reason: 'is empty');
-  });
-}
diff --git a/runtime/observatory/tests/observatory_ui/virtual_tree/element_test.html b/runtime/observatory/tests/observatory_ui/virtual_tree/element_test.html
deleted file mode 100644
index 92c3180..0000000
--- a/runtime/observatory/tests/observatory_ui/virtual_tree/element_test.html
+++ /dev/null
@@ -1,30 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-  <meta http-equiv="X-UA-Compatible" content="IE=edge">
-  <meta name="dart.unittest" content="full-stack-traces">
-  <link rel="stylesheet" href="packages/observatory/src/elements/css/shared.css">
-  <style>
-     .unittest-table { font-family:monospace; border:1px; }
-     .unittest-pass { background: #6b3;}
-     .unittest-fail { background: #d55;}
-     .unittest-error { background: #a11;}
-
-     .test_container {
-       height: 100px;
-       width: 100%;
-     }
-
-     .test_item {
-       height: 20px;
-     }
-  </style>
-</head>
-<body>
-  <div class="test_container">
-  </div>
-  <script type="text/javascript"
-      src="/root_dart/tools/testing/dart/test_controller.js"></script>
-  %TEST_SCRIPTS%
-</body>
-</html>
diff --git a/runtime/observatory/tests/observatory_ui/vm_connect/element_test.dart b/runtime/observatory/tests/observatory_ui/vm_connect/element_test.dart
deleted file mode 100644
index 1f5d1b6..0000000
--- a/runtime/observatory/tests/observatory_ui/vm_connect/element_test.dart
+++ /dev/null
@@ -1,115 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:html';
-import 'package:test/test.dart';
-import 'package:observatory/models.dart' as M;
-import 'package:observatory/src/elements/nav/notify.dart';
-import 'package:observatory/src/elements/vm_connect_target.dart';
-import 'package:observatory/src/elements/vm_connect.dart';
-import '../mocks.dart';
-
-main() {
-  VMConnectElement.tag.ensureRegistration();
-
-  final nTag = NavNotifyElement.tag.name;
-  final tTag = VMConnectTargetElement.tag.name;
-
-  group('instantiation', () {
-    test('default', () {
-      final e = new VMConnectElement(
-          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, new NotificationRepositoryMock());
-    document.body.append(e);
-    await e.onRendered.first;
-    expect(targets.hasListeners, isTrue, reason: 'is listening');
-    e.remove();
-    await e.onRendered.first;
-    expect(targets.hasListeners, isFalse, reason: 'is no more listening');
-  });
-  group('elements', () {
-    test('created after attachment', () async {
-      final targets = new TargetRepositoryMock(list: const [
-        const TargetMock(name: 't-1'),
-        const TargetMock(name: 't-2'),
-      ]);
-      final e = new VMConnectElement(targets, new NotificationRepositoryMock());
-      document.body.append(e);
-      await e.onRendered.first;
-      expect(targets.listInvoked, isTrue, reason: 'should invoke list()');
-      expect(e.children.length, isNonZero, reason: 'has elements');
-      expect(e.querySelectorAll(nTag).length, equals(1));
-      expect(e.querySelectorAll(tTag).length, equals(2));
-      e.remove();
-      await e.onRendered.first;
-      expect(e.children.length, isZero, reason: 'is empty');
-    });
-    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, new NotificationRepositoryMock());
-      document.body.append(e);
-      await e.onRendered.first;
-      expect(e.querySelectorAll(tTag).length, equals(1));
-      list.add(const TargetMock(name: 't-2'));
-      targets.triggerChangeEvent();
-      await e.onRendered.first;
-      expect(e.querySelectorAll(tTag).length, equals(2));
-      e.remove();
-      await e.onRendered.first;
-      expect(e.children.length, isZero, reason: 'is empty');
-    });
-  });
-  group('invokes', () {
-    test('add on click', () async {
-      final address = 'ws://host:1234/ws';
-      final list = <TargetMock>[const TargetMock(name: 't-1')];
-      final targets = new TargetRepositoryMock(
-          list: list,
-          add: expectAsync1((String val) {
-            expect(val, equals(address));
-          }, count: 1, reason: 'should be invoked'));
-      final e = new VMConnectElement(targets, new NotificationRepositoryMock(),
-          address: address);
-      document.body.append(e);
-      await e.onRendered.first;
-      (e.querySelector('button.vm_connect') as ButtonElement).click();
-      e.remove();
-      await e.onRendered.first;
-    });
-    test('connect', () async {
-      final list = <TargetMock>[const TargetMock(name: 't-1')];
-      final targets = new TargetRepositoryMock(
-          list: list,
-          setCurrent: expectAsync1((M.Target t) {
-            expect(t, equals(list[0]));
-          }, count: 1, reason: 'should be invoked'));
-      final e = new VMConnectElement(targets, new NotificationRepositoryMock());
-      document.body.append(e);
-      await e.onRendered.first;
-      (e.querySelector(tTag) as VMConnectTargetElement).connect();
-      e.remove();
-      await e.onRendered.first;
-    });
-    test('delete', () async {
-      final list = <TargetMock>[const TargetMock(name: 't-1')];
-      final targets = new TargetRepositoryMock(
-          list: list,
-          delete: expectAsync1((M.Target t) {
-            expect(t, equals(list[0]));
-          }, count: 1, reason: 'should be invoked'));
-      final e = new VMConnectElement(targets, new NotificationRepositoryMock());
-      document.body.append(e);
-      await e.onRendered.first;
-      (e.querySelector(tTag) as VMConnectTargetElement).delete();
-      e.remove();
-      await e.onRendered.first;
-    });
-  });
-}
diff --git a/runtime/observatory/tests/observatory_ui/vm_connect/element_test.html b/runtime/observatory/tests/observatory_ui/vm_connect/element_test.html
deleted file mode 100644
index f548be4..0000000
--- a/runtime/observatory/tests/observatory_ui/vm_connect/element_test.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-  <meta http-equiv="X-UA-Compatible" content="IE=edge">
-  <meta name="dart.unittest" content="full-stack-traces">
-  <style>
-     .unittest-table { font-family:monospace; border:1px; }
-     .unittest-pass { background: #6b3;}
-     .unittest-fail { background: #d55;}
-     .unittest-error { background: #a11;}
-  </style>
-</head>
-<body>
-  <script type="text/javascript"
-      src="/root_dart/tools/testing/dart/test_controller.js"></script>
-  %TEST_SCRIPTS%
-</body>
-</html>
diff --git a/runtime/observatory/tests/observatory_ui/vm_connect_target/element_test.dart b/runtime/observatory/tests/observatory_ui/vm_connect_target/element_test.dart
deleted file mode 100644
index 79003c8..0000000
--- a/runtime/observatory/tests/observatory_ui/vm_connect_target/element_test.dart
+++ /dev/null
@@ -1,86 +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.
-
-import 'dart:html';
-import 'package:test/test.dart';
-import 'package:observatory/src/elements/vm_connect_target.dart';
-import '../mocks.dart';
-
-main() {
-  VMConnectTargetElement.tag.ensureRegistration();
-
-  TargetMock t;
-  setUp(() {
-    t = new TargetMock(name: "a network address");
-  });
-  group('instantiation', () {
-    test('no other parameters', () {
-      final e = new VMConnectTargetElement(t);
-      expect(e, isNotNull, reason: 'element correctly created');
-      expect(e.target, t, reason: 'target not setted');
-      expect(e.current, isFalse, reason: 'default to not current');
-    });
-    test('isCurrent: false', () {
-      final e = new VMConnectTargetElement(t, current: false);
-      expect(e, isNotNull, reason: 'element correctly created');
-      expect(e.target, t, reason: 'target not setted');
-      expect(e.current, isFalse, reason: 'default to not current');
-    });
-    test('isCurrent: true', () {
-      final e = new VMConnectTargetElement(t, current: true);
-      expect(e, isNotNull, reason: 'element correctly created');
-      expect(e.target, t, reason: 'target not setted');
-      expect(e.current, isTrue, reason: 'default to not current');
-    });
-  });
-  test('elements created after attachment', () async {
-    final e = new VMConnectTargetElement(t);
-    document.body.append(e);
-    await e.onRendered.first;
-    expect(e.children.length, isNonZero, reason: 'has elements');
-    e.remove();
-    await e.onRendered.first;
-    expect(e.children.length, isZero, reason: 'is empty');
-  });
-  group('events are fired', () {
-    VMConnectTargetElement e;
-    setUp(() async {
-      e = new VMConnectTargetElement(t);
-      document.body.append(e);
-      await e.onRendered.first;
-    });
-    tearDown(() async {
-      e.remove();
-      await e.onRendered.first;
-    });
-    test('onConnect events (DOM)', () async {
-      e.onConnect.listen(expectAsync1((TargetEvent event) {
-        expect(event, isNotNull, reason: 'event is passed');
-        expect(event.target, t, reason: 'target is the same');
-      }, count: 1, reason: 'event is fired'));
-      e.querySelector('a').click();
-    });
-    test('onConnect events (code)', () async {
-      e.onConnect.listen(expectAsync1((TargetEvent event) {
-        expect(event, isNotNull, reason: 'event is passed');
-        expect(event.target, t, reason: 'target is the same');
-      }, count: 1, reason: 'event is fired'));
-      e.connect();
-    });
-    test('onRemove events (DOM)', () async {
-      e.onDelete.listen(expectAsync1((TargetEvent event) {
-        expect(event, isNotNull, reason: 'event is passed');
-        expect(event.target, t, reason: 'target is the same');
-      }, count: 1, reason: 'event is fired'));
-      e.querySelector('button').click();
-    });
-    test('onRemove events (code)', () async {
-      e.onDelete.listen(expectAsync1((TargetEvent event) {
-        expect(event, isNotNull, reason: 'event is passed');
-        expect(event.target, t, reason: 'target is the same');
-      }, count: 1, reason: 'event is fired'));
-      e.delete();
-    });
-  });
-}
diff --git a/runtime/observatory/tests/observatory_ui/vm_connect_target/element_test.html b/runtime/observatory/tests/observatory_ui/vm_connect_target/element_test.html
deleted file mode 100644
index f548be4..0000000
--- a/runtime/observatory/tests/observatory_ui/vm_connect_target/element_test.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-  <meta http-equiv="X-UA-Compatible" content="IE=edge">
-  <meta name="dart.unittest" content="full-stack-traces">
-  <style>
-     .unittest-table { font-family:monospace; border:1px; }
-     .unittest-pass { background: #6b3;}
-     .unittest-fail { background: #d55;}
-     .unittest-error { background: #a11;}
-  </style>
-</head>
-<body>
-  <script type="text/javascript"
-      src="/root_dart/tools/testing/dart/test_controller.js"></script>
-  %TEST_SCRIPTS%
-</body>
-</html>
diff --git a/runtime/observatory/tests/service/eval_skip_breakpoint.dart b/runtime/observatory/tests/service/eval_skip_breakpoint.dart
index 447852f..c2d7029 100644
--- a/runtime/observatory/tests/service/eval_skip_breakpoint.dart
+++ b/runtime/observatory/tests/service/eval_skip_breakpoint.dart
@@ -3,11 +3,12 @@
 // BSD-style license that can be found in the LICENSE file.
 // VMOptions=--verbose_debug
 
+import 'dart:developer';
+
 import 'package:observatory/service_io.dart';
-import 'package:unittest/unittest.dart';
+
 import 'service_test_common.dart';
 import 'test_helper.dart';
-import 'dart:developer';
 
 const int LINE_A = 21;
 const int LINE_B = 16;
diff --git a/runtime/observatory/tests/service/regress_34841_lib.dart b/runtime/observatory/tests/service/regress_34841_lib.dart
index 304f6f5..60eb3e4 100644
--- a/runtime/observatory/tests/service/regress_34841_lib.dart
+++ b/runtime/observatory/tests/service/regress_34841_lib.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 class Foo {
+  String baz() => StackTrace.current.toString();
   final String foo = () {
     return StackTrace.current.toString();
   }();
diff --git a/runtime/observatory/tests/service/regress_34841_test.dart b/runtime/observatory/tests/service/regress_34841_test.dart
index 69acbad..c53a9e9 100644
--- a/runtime/observatory/tests/service/regress_34841_test.dart
+++ b/runtime/observatory/tests/service/regress_34841_test.dart
@@ -19,6 +19,7 @@
 void testFunction() {
   Bar bar = new Bar();
   print(bar.foo);
+  print(bar.baz());
   debugger();
 }
 
diff --git a/runtime/observatory/tests/service/unused_changes_in_last_reload/v2/main.dart b/runtime/observatory/tests/service/unused_changes_in_last_reload/v2/main.dart
index 48682e2..910904f 100644
--- a/runtime/observatory/tests/service/unused_changes_in_last_reload/v2/main.dart
+++ b/runtime/observatory/tests/service/unused_changes_in_last_reload/v2/main.dart
@@ -2,8 +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 'dart:isolate';
-
 unchangedFunction() => "unchanged";
 var unchangedField = "unchanged".toString();
 
diff --git a/runtime/observatory/web/main.dart b/runtime/observatory/web/main.dart
index 07fcb1a..b09362d 100644
--- a/runtime/observatory/web/main.dart
+++ b/runtime/observatory/web/main.dart
@@ -13,9 +13,8 @@
     Logger.root.onRecord.listen((LogRecord rec) {
       print('${rec.level.name}: ${rec.time}: ${rec.message}');
     });
-    await initElements();
     Logger.root.info('Starting Observatory');
     document.body.children
-        .insert(0, document.createElement('observatory-application'));
+        .insert(0, new ObservatoryApplicationElement.created().element);
   });
 }
diff --git a/runtime/tests/vm/dart/spawn_shutdown_test.dart b/runtime/tests/vm/dart/spawn_shutdown_test.dart
index 235a0d8..6e42f3e 100644
--- a/runtime/tests/vm/dart/spawn_shutdown_test.dart
+++ b/runtime/tests/vm/dart/spawn_shutdown_test.dart
@@ -1,6 +1,7 @@
 // Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
+// VMOptions=--enable-asserts
 
 import 'dart:async';
 import 'dart:io';
@@ -16,7 +17,7 @@
 
 trySpawn(Function f, Object o) async {
   try {
-    await Isolate.spawn(f, o);
+    await Isolate.spawn<SendPort>(f, o);
   } catch (e) {
     // Isolate spawning may fail if the program is ending.
     assert(e is IsolateSpawnException);
diff --git a/runtime/tools/dartfuzz/dartfuzz.dart b/runtime/tools/dartfuzz/dartfuzz.dart
index e3b06fa..01dc871 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.12';
+const String version = '1.13';
 
 // Restriction on statements and expressions.
 const int stmtLength = 2;
@@ -131,7 +131,7 @@
     indent += 2;
     emitLn('new X${classFields.length - 1}().run();');
     indent -= 2;
-    emitLn('} catch (e) {');
+    emitLn('} catch (exception, stackTrace) {');
     indent += 2;
     emitLn("print('throws');");
     indent -= 2;
@@ -411,7 +411,7 @@
     indent += 2;
     emitStatements(depth + 1);
     indent -= 2;
-    emitLn('} catch (e) {');
+    emitLn('} catch (exception, stackTrace) {');
     indent += 2;
     emitStatements(depth + 1);
     indent -= 2;
diff --git a/runtime/vm/BUILD.gn b/runtime/vm/BUILD.gn
index 599c9a9..5ccc521 100644
--- a/runtime/vm/BUILD.gn
+++ b/runtime/vm/BUILD.gn
@@ -101,13 +101,12 @@
     }
   }
   include_dirs = [ ".." ]
-  allsources =
-      async_runtime_sources + collection_runtime_sources +
-      convert_runtime_sources + core_runtime_sources +
-      developer_runtime_sources + internal_runtime_sources +
-      isolate_runtime_sources + math_runtime_sources + mirrors_runtime_sources +
-      profiler_runtime_sources + typed_data_runtime_sources +
-      vmservice_runtime_sources + ffi_runtime_sources
+  allsources = async_runtime_cc_files + collection_runtime_cc_files +
+               core_runtime_cc_files + developer_runtime_cc_files +
+               internal_runtime_cc_files + isolate_runtime_cc_files +
+               math_runtime_cc_files + mirrors_runtime_cc_files +
+               typed_data_runtime_cc_files + vmservice_runtime_cc_files +
+               ffi_runtime_cc_files
   sources = [ "bootstrap.cc" ] + rebase_path(allsources, ".", "../lib")
   snapshot_sources = []
   nosnapshot_sources = []
diff --git a/runtime/vm/clustered_snapshot.cc b/runtime/vm/clustered_snapshot.cc
index d30764c..dba74ea 100644
--- a/runtime/vm/clustered_snapshot.cc
+++ b/runtime/vm/clustered_snapshot.cc
@@ -7,6 +7,7 @@
 #include "platform/assert.h"
 #include "vm/bootstrap.h"
 #include "vm/compiler/backend/code_statistics.h"
+#include "vm/compiler/frontend/bytecode_reader.h"
 #include "vm/compiler/relocation.h"
 #include "vm/dart.h"
 #include "vm/heap/heap.h"
@@ -1291,6 +1292,14 @@
       info.set_libraries_cache(array);
       array = HashTables::New<UnorderedHashMap<SmiTraits>>(16, Heap::kOld);
       info.set_classes_cache(array);
+
+      static_assert(KernelBytecode::kMinSupportedBytecodeFormatVersion < 7,
+                    "Cleanup support for old bytecode format versions");
+      array = info.bytecode_component();
+      if (!array.IsNull()) {
+        kernel::BytecodeReader::UseBytecodeVersion(
+            kernel::BytecodeComponentData(array).GetVersion());
+      }
     }
   }
 };
diff --git a/runtime/vm/compiler/aot/aot_call_specializer.cc b/runtime/vm/compiler/aot/aot_call_specializer.cc
index 07d879f..895d8a7 100644
--- a/runtime/vm/compiler/aot/aot_call_specializer.cc
+++ b/runtime/vm/compiler/aot/aot_call_specializer.cc
@@ -1145,8 +1145,10 @@
     InsertBefore(call, invoke_call->PushArgumentAt(i), NULL,
                  FlowGraph::kEffect);
   }
-  // Remove original PushArguments from the graph.
+  // Replace original PushArguments in the graph (mainly env uses).
+  ASSERT(call->ArgumentCount() == invoke_call->ArgumentCount());
   for (intptr_t i = 0; i < call->ArgumentCount(); i++) {
+    call->PushArgumentAt(i)->ReplaceUsesWith(invoke_call->PushArgumentAt(i));
     call->PushArgumentAt(i)->RemoveFromGraph();
   }
 
diff --git a/runtime/vm/compiler/aot/precompiler.cc b/runtime/vm/compiler/aot/precompiler.cc
index 2355495..29b1fad 100644
--- a/runtime/vm/compiler/aot/precompiler.cc
+++ b/runtime/vm/compiler/aot/precompiler.cc
@@ -72,7 +72,6 @@
 DECLARE_FLAG(bool, trace_compiler);
 DECLARE_FLAG(bool, trace_optimizing_compiler);
 DECLARE_FLAG(bool, trace_bailout);
-DECLARE_FLAG(bool, verify_compiler);
 DECLARE_FLAG(bool, huge_method_cutoff_in_code_size);
 DECLARE_FLAG(bool, trace_failed_optimization_attempts);
 DECLARE_FLAG(bool, trace_inlining_intervals);
diff --git a/runtime/vm/compiler/asm_intrinsifier_ia32.cc b/runtime/vm/compiler/asm_intrinsifier_ia32.cc
index d26494d..c035d55 100644
--- a/runtime/vm/compiler/asm_intrinsifier_ia32.cc
+++ b/runtime/vm/compiler/asm_intrinsifier_ia32.cc
@@ -2206,8 +2206,7 @@
   __ xorl(ECX, ECX);
 
   // Tail-call the function.
-  __ movl(EDI, FieldAddress(EAX, target::Function::entry_point_offset()));
-  __ jmp(EDI);
+  __ jmp(FieldAddress(EAX, target::Function::entry_point_offset()));
 }
 
 // On stack: user tag (+1), return-address (+0).
diff --git a/runtime/vm/compiler/assembler/assembler_arm.cc b/runtime/vm/compiler/assembler/assembler_arm.cc
index a232e37..9a40633 100644
--- a/runtime/vm/compiler/assembler/assembler_arm.cc
+++ b/runtime/vm/compiler/assembler/assembler_arm.cc
@@ -1616,14 +1616,6 @@
   LoadObjectHelper(rd, object, cond, /* is_unique = */ true, PP);
 }
 
-void Assembler::LoadFunctionFromCalleePool(Register dst,
-                                           const Function& function,
-                                           Register new_pp) {
-  const int32_t offset = ObjectPool::element_offset(
-      object_pool_builder().FindObject(ToObject(function)));
-  LoadWordFromPoolOffset(dst, offset - kHeapObjectTag, new_pp, AL);
-}
-
 void Assembler::LoadNativeEntry(Register rd,
                                 const ExternalLabel* label,
                                 ObjectPoolBuilderEntry::Patchability patchable,
diff --git a/runtime/vm/compiler/assembler/assembler_arm.h b/runtime/vm/compiler/assembler/assembler_arm.h
index 3f37cbd6..7d2e40c 100644
--- a/runtime/vm/compiler/assembler/assembler_arm.h
+++ b/runtime/vm/compiler/assembler/assembler_arm.h
@@ -758,9 +758,6 @@
 
   void LoadObject(Register rd, const Object& object, Condition cond = AL);
   void LoadUniqueObject(Register rd, const Object& object, Condition cond = AL);
-  void LoadFunctionFromCalleePool(Register dst,
-                                  const Function& function,
-                                  Register new_pp);
   void LoadNativeEntry(Register dst,
                        const ExternalLabel* label,
                        ObjectPoolBuilderEntry::Patchability patchable,
diff --git a/runtime/vm/compiler/assembler/assembler_arm64.cc b/runtime/vm/compiler/assembler/assembler_arm64.cc
index c88687fc..63775f1 100644
--- a/runtime/vm/compiler/assembler/assembler_arm64.cc
+++ b/runtime/vm/compiler/assembler/assembler_arm64.cc
@@ -495,17 +495,6 @@
   }
 }
 
-void Assembler::LoadFunctionFromCalleePool(Register dst,
-                                           const Function& function,
-                                           Register new_pp) {
-  ASSERT(!constant_pool_allowed());
-  ASSERT(new_pp != PP);
-  const int32_t offset = ObjectPool::element_offset(
-      object_pool_builder().FindObject(ToObject(function)));
-  ASSERT(Address::CanHoldOffset(offset));
-  ldr(dst, Address(new_pp, offset));
-}
-
 void Assembler::LoadObject(Register dst, const Object& object) {
   LoadObjectHelper(dst, object, false);
 }
@@ -1453,19 +1442,21 @@
   bool saved_use_far_branches = use_far_branches();
   set_use_far_branches(false);
 
+  const intptr_t start = CodeSize();
+
   Label immediate, miss;
   Bind(&miss);
   ldr(IP0, Address(THR, Thread::monomorphic_miss_entry_offset()));
   br(IP0);
 
   Comment("MonomorphicCheckedEntry");
-  ASSERT(CodeSize() == Instructions::kPolymorphicEntryOffset);
+  ASSERT(CodeSize() - start == Instructions::kPolymorphicEntryOffset);
   LoadClassIdMayBeSmi(IP0, R0);
   cmp(R5, Operand(IP0, LSL, 1));
   b(&miss, NE);
 
   // Fall through to unchecked entry.
-  ASSERT(CodeSize() == Instructions::kMonomorphicEntryOffset);
+  ASSERT(CodeSize() - start == Instructions::kMonomorphicEntryOffset);
 
   set_use_far_branches(saved_use_far_branches);
 }
diff --git a/runtime/vm/compiler/assembler/assembler_arm64.h b/runtime/vm/compiler/assembler/assembler_arm64.h
index 1ff5ac9..1a0cfb7 100644
--- a/runtime/vm/compiler/assembler/assembler_arm64.h
+++ b/runtime/vm/compiler/assembler/assembler_arm64.h
@@ -1485,9 +1485,6 @@
   void LoadNativeEntry(Register dst,
                        const ExternalLabel* label,
                        ObjectPoolBuilderEntry::Patchability patchable);
-  void LoadFunctionFromCalleePool(Register dst,
-                                  const Function& function,
-                                  Register new_pp);
   void LoadIsolate(Register dst);
   void LoadObject(Register dst, const Object& obj);
   void LoadUniqueObject(Register dst, const Object& obj);
@@ -1537,7 +1534,7 @@
   void RestoreCodePointer();
 
   void EnterDartFrame(intptr_t frame_size, Register new_pp = kNoRegister);
-  void EnterOsrFrame(intptr_t extra_size, Register new_pp);
+  void EnterOsrFrame(intptr_t extra_size, Register new_pp = kNoRegister);
   void LeaveDartFrame(RestorePP restore_pp = kRestoreCallerPP);
 
   void EnterCallRuntimeFrame(intptr_t frame_size);
diff --git a/runtime/vm/compiler/assembler/assembler_dbc.h b/runtime/vm/compiler/assembler/assembler_dbc.h
index 253fdc1..b88795f 100644
--- a/runtime/vm/compiler/assembler/assembler_dbc.h
+++ b/runtime/vm/compiler/assembler/assembler_dbc.h
@@ -39,6 +39,8 @@
   // Misc. functionality
   intptr_t prologue_offset() const { return 0; }
 
+  void MonomorphicCheckedEntry() {}
+
   // Debugging and bringup support.
   void Stop(const char* message) override;
 
diff --git a/runtime/vm/compiler/assembler/assembler_ia32.cc b/runtime/vm/compiler/assembler/assembler_ia32.cc
index 8794ba8..32656b9 100644
--- a/runtime/vm/compiler/assembler/assembler_ia32.cc
+++ b/runtime/vm/compiler/assembler/assembler_ia32.cc
@@ -1667,6 +1667,12 @@
   EmitRegisterOperand(4, reg);
 }
 
+void Assembler::jmp(const Address& address) {
+  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
+  EmitUint8(0xFF);
+  EmitOperand(4, address);
+}
+
 void Assembler::jmp(Label* label, bool near) {
   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
   if (label->IsBound()) {
diff --git a/runtime/vm/compiler/assembler/assembler_ia32.h b/runtime/vm/compiler/assembler/assembler_ia32.h
index 39086a3..df07d96 100644
--- a/runtime/vm/compiler/assembler/assembler_ia32.h
+++ b/runtime/vm/compiler/assembler/assembler_ia32.h
@@ -549,6 +549,7 @@
   void j(Condition condition, const ExternalLabel* label);
 
   void jmp(Register reg);
+  void jmp(const Address& address);
   void jmp(Label* label, bool near = kFarJump);
   void jmp(const ExternalLabel* label);
 
@@ -645,6 +646,8 @@
   void LeaveFrame();
   void ReserveAlignedFrameSpace(intptr_t frame_space);
 
+  void MonomorphicCheckedEntry() {}
+
   // Require a temporary register 'tmp'.
   // Clobber all non-CPU registers (e.g. XMM registers and the "FPU stack").
   void TransitionGeneratedToNative(Register destination_address,
diff --git a/runtime/vm/compiler/assembler/assembler_ia32_test.cc b/runtime/vm/compiler/assembler/assembler_ia32_test.cc
index 1ba6a08..ca0ab3a 100644
--- a/runtime/vm/compiler/assembler/assembler_ia32_test.cc
+++ b/runtime/vm/compiler/assembler/assembler_ia32_test.cc
@@ -326,6 +326,51 @@
       "ret\n");
 }
 
+struct JumpAddress {
+  uword filler1;
+  uword filler2;
+  uword filler3;
+  uword filler4;
+  uword filler5;
+  uword target;
+  uword filler6;
+  uword filler7;
+  uword filler8;
+};
+static JumpAddress jump_address;
+static uword jump_address_offset;
+
+ASSEMBLER_TEST_GENERATE(JumpAddress, assembler) {
+  __ movl(EAX, Address(ESP, 4));
+  __ jmp(Address(EAX, OFFSET_OF(JumpAddress, target)));
+  __ int3();
+  __ int3();
+  __ int3();
+  __ int3();
+  __ int3();
+  jump_address_offset = __ CodeSize();
+  __ movl(EAX, Immediate(42));
+  __ ret();
+}
+
+ASSEMBLER_TEST_RUN(JumpAddress, test) {
+  memset(&jump_address, 0, sizeof(jump_address));
+  jump_address.target = test->entry() + jump_address_offset;
+
+  typedef int (*TestCode)(void*);
+  EXPECT_EQ(42, reinterpret_cast<TestCode>(test->entry())(&jump_address));
+  EXPECT_DISASSEMBLY(
+      "mov eax,[esp+0x4]\n"
+      "jmp [eax+0x14]\n"
+      "int3\n"
+      "int3\n"
+      "int3\n"
+      "int3\n"
+      "int3\n"
+      "mov eax,0x2a\n"
+      "ret\n");
+}
+
 ASSEMBLER_TEST_GENERATE(Increment, assembler) {
   __ movl(EAX, Immediate(0));
   __ pushl(EAX);
diff --git a/runtime/vm/compiler/assembler/assembler_x64.cc b/runtime/vm/compiler/assembler/assembler_x64.cc
index 300cf65..073a179 100644
--- a/runtime/vm/compiler/assembler/assembler_x64.cc
+++ b/runtime/vm/compiler/assembler/assembler_x64.cc
@@ -996,7 +996,7 @@
   const intptr_t idx = object_pool_builder().AddObject(
       ToObject(target), ObjectPoolBuilderEntry::kPatchable);
   const int32_t offset = target::ObjectPool::element_offset(idx);
-  movq(CODE_REG, Address::AddressBaseImm32(pp, offset - kHeapObjectTag));
+  movq(CODE_REG, Address(pp, offset - kHeapObjectTag));
   movq(TMP, FieldAddress(CODE_REG, target::Code::entry_point_offset()));
   jmp(TMP);
 }
@@ -1007,8 +1007,7 @@
       ToObject(target), ObjectPoolBuilderEntry::kNotPatchable);
   const int32_t offset = target::ObjectPool::element_offset(idx);
   movq(CODE_REG, FieldAddress(pp, offset));
-  movq(TMP, FieldAddress(CODE_REG, target::Code::entry_point_offset()));
-  jmp(TMP);
+  jmp(FieldAddress(CODE_REG, target::Code::entry_point_offset()));
 }
 
 void Assembler::CompareRegisters(Register a, Register b) {
@@ -1196,17 +1195,6 @@
   }
 }
 
-void Assembler::LoadFunctionFromCalleePool(Register dst,
-                                           const Function& function,
-                                           Register new_pp) {
-  ASSERT(!constant_pool_allowed());
-  ASSERT(new_pp != PP);
-  const intptr_t idx = object_pool_builder().FindObject(
-      ToObject(function), ObjectPoolBuilderEntry::kNotPatchable);
-  const int32_t offset = target::ObjectPool::element_offset(idx);
-  movq(dst, Address::AddressBaseImm32(new_pp, offset - kHeapObjectTag));
-}
-
 void Assembler::LoadObject(Register dst, const Object& object) {
   LoadObjectHelper(dst, object, false);
 }
diff --git a/runtime/vm/compiler/assembler/assembler_x64.h b/runtime/vm/compiler/assembler/assembler_x64.h
index 0ef1efe..1fe5400 100644
--- a/runtime/vm/compiler/assembler/assembler_x64.h
+++ b/runtime/vm/compiler/assembler/assembler_x64.h
@@ -696,9 +696,6 @@
   void LoadNativeEntry(Register dst,
                        const ExternalLabel* label,
                        ObjectPoolBuilderEntry::Patchability patchable);
-  void LoadFunctionFromCalleePool(Register dst,
-                                  const Function& function,
-                                  Register new_pp);
   void JmpPatchable(const Code& code, Register pp);
   void Jmp(const Code& code, Register pp = PP);
   void J(Condition condition, const Code& code, Register pp);
@@ -856,7 +853,7 @@
   //   ...
   //   pushq r15
   //   .....
-  void EnterDartFrame(intptr_t frame_size, Register new_pp);
+  void EnterDartFrame(intptr_t frame_size, Register new_pp = kNoRegister);
   void LeaveDartFrame(RestorePP restore_pp = kRestoreCallerPP);
 
   // Set up a Dart frame for a function compiled for on-stack replacement.
diff --git a/runtime/vm/compiler/assembler/assembler_x64_test.cc b/runtime/vm/compiler/assembler/assembler_x64_test.cc
index e8d6883..92aa14d 100644
--- a/runtime/vm/compiler/assembler/assembler_x64_test.cc
+++ b/runtime/vm/compiler/assembler/assembler_x64_test.cc
@@ -670,6 +670,49 @@
       "ret\n");
 }
 
+struct JumpAddress {
+  uword filler1;
+  uword filler2;
+  uword filler3;
+  uword filler4;
+  uword filler5;
+  uword target;
+  uword filler6;
+  uword filler7;
+  uword filler8;
+};
+static JumpAddress jump_address;
+static uword jump_address_offset;
+
+ASSEMBLER_TEST_GENERATE(JumpAddress, assembler) {
+  __ jmp(Address(CallingConventions::kArg1Reg, OFFSET_OF(JumpAddress, target)));
+  __ int3();
+  __ int3();
+  __ int3();
+  __ int3();
+  __ int3();
+  jump_address_offset = __ CodeSize();
+  __ movl(RAX, Immediate(42));
+  __ ret();
+}
+
+ASSEMBLER_TEST_RUN(JumpAddress, test) {
+  memset(&jump_address, 0, sizeof(jump_address));
+  jump_address.target = test->entry() + jump_address_offset;
+
+  typedef int (*TestCode)(void*);
+  EXPECT_EQ(42, reinterpret_cast<TestCode>(test->entry())(&jump_address));
+  EXPECT_DISASSEMBLY_NOT_WINDOWS(
+      "jmp [rdi+0x28]\n"
+      "int3\n"
+      "int3\n"
+      "int3\n"
+      "int3\n"
+      "int3\n"
+      "movl rax,0x2a\n"
+      "ret\n");
+}
+
 ASSEMBLER_TEST_GENERATE(Increment, assembler) {
   __ movq(RAX, Immediate(0));
   __ pushq(RAX);
diff --git a/runtime/vm/compiler/assembler/disassembler.cc b/runtime/vm/compiler/assembler/disassembler.cc
index 8cf7adc..a2fe6a1 100644
--- a/runtime/vm/compiler/assembler/disassembler.cc
+++ b/runtime/vm/compiler/assembler/disassembler.cc
@@ -318,11 +318,24 @@
       ExceptionHandlers::Handle(zone, code.exception_handlers());
   THR_Print("%s}\n", handlers.ToCString());
 
-  if (instructions.unchecked_entrypoint_pc_offset() != 0) {
-    THR_Print("Unchecked entrypoint at offset 0x%" Px "\n",
-              Instructions::UncheckedEntryPoint(instructions.raw()));
-  } else {
-    THR_Print("No unchecked entrypoint.\n");
+  {
+    THR_Print("Entry points for function '%s' {\n", function_fullname);
+    THR_Print("  [code+0x%02" Px "] %" Px " kNormal\n",
+              Code::entry_point_offset(CodeEntryKind::kNormal) - kHeapObjectTag,
+              Instructions::EntryPoint(instructions.raw()));
+    THR_Print(
+        "  [code+0x%02" Px "] %" Px " kUnchecked\n",
+        Code::entry_point_offset(CodeEntryKind::kUnchecked) - kHeapObjectTag,
+        Instructions::UncheckedEntryPoint(instructions.raw()));
+    THR_Print(
+        "  [code+0x%02" Px "] %" Px " kMonomorphic\n",
+        Code::entry_point_offset(CodeEntryKind::kMonomorphic) - kHeapObjectTag,
+        Instructions::MonomorphicEntryPoint(instructions.raw()));
+    THR_Print("  [code+0x%02" Px "] %" Px " kMonomorphicUnchecked\n",
+              Code::entry_point_offset(CodeEntryKind::kMonomorphicUnchecked) -
+                  kHeapObjectTag,
+              Instructions::MonomorphicUncheckedEntryPoint(instructions.raw()));
+    THR_Print("}\n");
   }
 
   {
diff --git a/runtime/vm/compiler/assembler/disassembler_kbc.cc b/runtime/vm/compiler/assembler/disassembler_kbc.cc
index c0b9538..411e1cf 100644
--- a/runtime/vm/compiler/assembler/disassembler_kbc.cc
+++ b/runtime/vm/compiler/assembler/disassembler_kbc.cc
@@ -15,19 +15,23 @@
 namespace dart {
 
 static const char* kOpcodeNames[] = {
-#define BYTECODE_NAME(name, encoding, op1, op2, op3) #name,
+#define BYTECODE_NAME(name, encoding, kind, op1, op2, op3) #name,
     KERNEL_BYTECODES_LIST(BYTECODE_NAME)
 #undef BYTECODE_NAME
 };
 
 static const size_t kOpcodeCount =
     sizeof(kOpcodeNames) / sizeof(kOpcodeNames[0]);
+static_assert(kOpcodeCount <= 256, "Opcode should fit into a byte");
 
 typedef void (*BytecodeFormatter)(char* buffer,
                                   intptr_t size,
-                                  uword pc,
-                                  uint32_t bc);
-typedef void (*Fmt)(char** buf, intptr_t* size, uword pc, int32_t value);
+                                  KernelBytecode::Opcode opcode,
+                                  const KBCInstr* instr);
+typedef void (*Fmt)(char** buf,
+                    intptr_t* size,
+                    const KBCInstr* instr,
+                    int32_t value);
 
 template <typename ValueType>
 void FormatOperand(char** buf,
@@ -43,35 +47,53 @@
   }
 }
 
-static void Fmt___(char** buf, intptr_t* size, uword pc, int32_t value) {}
+static void Fmt___(char** buf,
+                   intptr_t* size,
+                   const KBCInstr* instr,
+                   int32_t value) {}
 
-static void Fmttgt(char** buf, intptr_t* size, uword pc, int32_t value) {
-  FormatOperand(buf, size, "-> %" Px, pc + (value << 2));
+static void Fmttgt(char** buf,
+                   intptr_t* size,
+                   const KBCInstr* instr,
+                   int32_t value) {
+  FormatOperand(buf, size, "-> %" Px, instr + value);
 }
 
-static void Fmtlit(char** buf, intptr_t* size, uword pc, int32_t value) {
+static void Fmtlit(char** buf,
+                   intptr_t* size,
+                   const KBCInstr* instr,
+                   int32_t value) {
   FormatOperand(buf, size, "k%d", value);
 }
 
-static void Fmtreg(char** buf, intptr_t* size, uword pc, int32_t value) {
+static void Fmtreg(char** buf,
+                   intptr_t* size,
+                   const KBCInstr* instr,
+                   int32_t value) {
   FormatOperand(buf, size, "r%d", value);
 }
 
-static void Fmtxeg(char** buf, intptr_t* size, uword pc, int32_t value) {
+static void Fmtxeg(char** buf,
+                   intptr_t* size,
+                   const KBCInstr* instr,
+                   int32_t value) {
   if (value < 0) {
     FormatOperand(buf, size, "FP[%d]", value);
   } else {
-    Fmtreg(buf, size, pc, value);
+    Fmtreg(buf, size, instr, value);
   }
 }
 
-static void Fmtnum(char** buf, intptr_t* size, uword pc, int32_t value) {
+static void Fmtnum(char** buf,
+                   intptr_t* size,
+                   const KBCInstr* instr,
+                   int32_t value) {
   FormatOperand(buf, size, "#%d", value);
 }
 
 static void Apply(char** buf,
                   intptr_t* size,
-                  uword pc,
+                  const KBCInstr* instr,
                   Fmt fmt,
                   int32_t value,
                   const char* suffix) {
@@ -79,7 +101,7 @@
     return;
   }
 
-  fmt(buf, size, pc, value);
+  fmt(buf, size, instr, value);
   if (*size > 0) {
     FormatOperand(buf, size, "%s", suffix);
   }
@@ -87,154 +109,209 @@
 
 static void Format0(char* buf,
                     intptr_t size,
-                    uword pc,
-                    uint32_t op,
+                    KernelBytecode::Opcode opcode,
+                    const KBCInstr* instr,
                     Fmt op1,
                     Fmt op2,
                     Fmt op3) {}
 
-static void FormatT(char* buf,
-                    intptr_t size,
-                    uword pc,
-                    uint32_t op,
-                    Fmt op1,
-                    Fmt op2,
-                    Fmt op3) {
-  const int32_t x = static_cast<int32_t>(op) >> 8;
-  Apply(&buf, &size, pc, op1, x, "");
-}
-
 static void FormatA(char* buf,
                     intptr_t size,
-                    uword pc,
-                    uint32_t op,
+                    KernelBytecode::Opcode opcode,
+                    const KBCInstr* instr,
                     Fmt op1,
                     Fmt op2,
                     Fmt op3) {
-  const int32_t a = (op & 0xFF00) >> 8;
-  Apply(&buf, &size, pc, op1, a, "");
-}
-
-static void FormatA_D(char* buf,
-                      intptr_t size,
-                      uword pc,
-                      uint32_t op,
-                      Fmt op1,
-                      Fmt op2,
-                      Fmt op3) {
-  const int32_t a = (op & 0xFF00) >> 8;
-  const int32_t bc = op >> 16;
-  Apply(&buf, &size, pc, op1, a, ", ");
-  Apply(&buf, &size, pc, op2, bc, "");
-}
-
-static void FormatA_X(char* buf,
-                      intptr_t size,
-                      uword pc,
-                      uint32_t op,
-                      Fmt op1,
-                      Fmt op2,
-                      Fmt op3) {
-  const int32_t a = (op & 0xFF00) >> 8;
-  const int32_t bc = static_cast<int32_t>(op) >> 16;
-  Apply(&buf, &size, pc, op1, a, ", ");
-  Apply(&buf, &size, pc, op2, bc, "");
-}
-
-static void FormatX(char* buf,
-                    intptr_t size,
-                    uword pc,
-                    uint32_t op,
-                    Fmt op1,
-                    Fmt op2,
-                    Fmt op3) {
-  const int32_t bc = static_cast<int32_t>(op) >> 16;
-  Apply(&buf, &size, pc, op1, bc, "");
+  const int32_t a = KernelBytecode::DecodeA(instr);
+  Apply(&buf, &size, instr, op1, a, "");
 }
 
 static void FormatD(char* buf,
                     intptr_t size,
-                    uword pc,
-                    uint32_t op,
+                    KernelBytecode::Opcode opcode,
+                    const KBCInstr* instr,
                     Fmt op1,
                     Fmt op2,
                     Fmt op3) {
-  const int32_t bc = op >> 16;
-  Apply(&buf, &size, pc, op1, bc, "");
+  const int32_t bc = KernelBytecode::DecodeD(instr);
+  Apply(&buf, &size, instr, op1, bc, "");
+}
+
+static void FormatX(char* buf,
+                    intptr_t size,
+                    KernelBytecode::Opcode opcode,
+                    const KBCInstr* instr,
+                    Fmt op1,
+                    Fmt op2,
+                    Fmt op3) {
+  const int32_t bc = KernelBytecode::DecodeX(instr);
+  Apply(&buf, &size, instr, op1, bc, "");
+}
+
+static void FormatT(char* buf,
+                    intptr_t size,
+                    KernelBytecode::Opcode opcode,
+                    const KBCInstr* instr,
+                    Fmt op1,
+                    Fmt op2,
+                    Fmt op3) {
+  const int32_t x = KernelBytecode::DecodeT(instr);
+  Apply(&buf, &size, instr, op1, x, "");
+}
+
+static void FormatA_D(char* buf,
+                      intptr_t size,
+                      KernelBytecode::Opcode opcode,
+                      const KBCInstr* instr,
+                      Fmt op1,
+                      Fmt op2,
+                      Fmt op3) {
+  const int32_t a = KernelBytecode::DecodeA(instr);
+  const int32_t bc = KernelBytecode::DecodeD(instr);
+  Apply(&buf, &size, instr, op1, a, ", ");
+  Apply(&buf, &size, instr, op2, bc, "");
+}
+
+static void FormatA_X(char* buf,
+                      intptr_t size,
+                      KernelBytecode::Opcode opcode,
+                      const KBCInstr* instr,
+                      Fmt op1,
+                      Fmt op2,
+                      Fmt op3) {
+  const int32_t a = KernelBytecode::DecodeA(instr);
+  const int32_t bc = KernelBytecode::DecodeX(instr);
+  Apply(&buf, &size, instr, op1, a, ", ");
+  Apply(&buf, &size, instr, op2, bc, "");
+}
+
+static void FormatA_E(char* buf,
+                      intptr_t size,
+                      KernelBytecode::Opcode opcode,
+                      const KBCInstr* instr,
+                      Fmt op1,
+                      Fmt op2,
+                      Fmt op3) {
+  const int32_t a = KernelBytecode::DecodeA(instr);
+  const int32_t e = KernelBytecode::DecodeE(instr);
+  Apply(&buf, &size, instr, op1, a, ", ");
+  Apply(&buf, &size, instr, op2, e, "");
+}
+
+static void FormatA_Y(char* buf,
+                      intptr_t size,
+                      KernelBytecode::Opcode opcode,
+                      const KBCInstr* instr,
+                      Fmt op1,
+                      Fmt op2,
+                      Fmt op3) {
+  const int32_t a = KernelBytecode::DecodeA(instr);
+  const int32_t y = KernelBytecode::DecodeY(instr);
+  Apply(&buf, &size, instr, op1, a, ", ");
+  Apply(&buf, &size, instr, op2, y, "");
+}
+
+static void FormatD_F(char* buf,
+                      intptr_t size,
+                      KernelBytecode::Opcode opcode,
+                      const KBCInstr* instr,
+                      Fmt op1,
+                      Fmt op2,
+                      Fmt op3) {
+  const int32_t d = KernelBytecode::DecodeD(instr);
+  const int32_t f = KernelBytecode::DecodeF(instr);
+  Apply(&buf, &size, instr, op1, d, ", ");
+  Apply(&buf, &size, instr, op2, f, "");
 }
 
 static void FormatA_B_C(char* buf,
                         intptr_t size,
-                        uword pc,
-                        uint32_t op,
+                        KernelBytecode::Opcode opcode,
+                        const KBCInstr* instr,
                         Fmt op1,
                         Fmt op2,
                         Fmt op3) {
-  const int32_t a = (op >> 8) & 0xFF;
-  const int32_t b = (op >> 16) & 0xFF;
-  const int32_t c = (op >> 24) & 0xFF;
-  Apply(&buf, &size, pc, op1, a, ", ");
-  Apply(&buf, &size, pc, op2, b, ", ");
-  Apply(&buf, &size, pc, op3, c, "");
+  const int32_t a = KernelBytecode::DecodeA(instr);
+  const int32_t b = KernelBytecode::DecodeB(instr);
+  const int32_t c = KernelBytecode::DecodeC(instr);
+  Apply(&buf, &size, instr, op1, a, ", ");
+  Apply(&buf, &size, instr, op2, b, ", ");
+  Apply(&buf, &size, instr, op3, c, "");
 }
 
-// TODO(alexmarkov) This format is currently unused. Restore it if needed, or
-// remove it once bytecode instruction set is finalized.
-//
-// static void FormatA_B_Y(char* buf,
-//                        intptr_t size,
-//                        uword pc,
-//                        uint32_t op,
-//                        Fmt op1,
-//                        Fmt op2,
-//                        Fmt op3) {
-//  const int32_t a = (op >> 8) & 0xFF;
-//  const int32_t b = (op >> 16) & 0xFF;
-//  const int32_t y = static_cast<int8_t>((op >> 24) & 0xFF);
-//  Apply(&buf, &size, pc, op1, a, ", ");
-//  Apply(&buf, &size, pc, op2, b, ", ");
-//  Apply(&buf, &size, pc, op3, y, "");
-// }
-
-#define BYTECODE_FORMATTER(name, encoding, op1, op2, op3)                      \
-  static void Format##name(char* buf, intptr_t size, uword pc, uint32_t op) {  \
-    Format##encoding(buf, size, pc, op, Fmt##op1, Fmt##op2, Fmt##op3);         \
+#define BYTECODE_FORMATTER(name, encoding, kind, op1, op2, op3)                \
+  static void Format##name(char* buf, intptr_t size,                           \
+                           KernelBytecode::Opcode opcode,                      \
+                           const KBCInstr* instr) {                            \
+    Format##encoding(buf, size, opcode, instr, Fmt##op1, Fmt##op2, Fmt##op3);  \
   }
 KERNEL_BYTECODES_LIST(BYTECODE_FORMATTER)
 #undef BYTECODE_FORMATTER
 
 static const BytecodeFormatter kFormatters[] = {
-#define BYTECODE_FORMATTER(name, encoding, op1, op2, op3) &Format##name,
+#define BYTECODE_FORMATTER(name, encoding, kind, op1, op2, op3) &Format##name,
     KERNEL_BYTECODES_LIST(BYTECODE_FORMATTER)
 #undef BYTECODE_FORMATTER
 };
 
-static bool HasLoadFromPool(KBCInstr instr) {
+static intptr_t GetConstantPoolIndex(const KBCInstr* instr) {
   switch (KernelBytecode::DecodeOpcode(instr)) {
+    case KernelBytecode::kLoadConstant_Old:
+    case KernelBytecode::kInstantiateTypeArgumentsTOS_Old:
+    case KernelBytecode::kAssertAssignable_Old:
+    case KernelBytecode::kPushConstant_Old:
+    case KernelBytecode::kStoreStaticTOS_Old:
+    case KernelBytecode::kPushStatic_Old:
+    case KernelBytecode::kAllocate_Old:
+    case KernelBytecode::kAllocateClosure_Old:
+    case KernelBytecode::kInstantiateType_Old:
+    case KernelBytecode::kDirectCall_Old:
+    case KernelBytecode::kInterfaceCall_Old:
+    case KernelBytecode::kUncheckedInterfaceCall_Old:
+    case KernelBytecode::kDynamicCall_Old:
+      return KernelBytecode::DecodeD(instr);
+
     case KernelBytecode::kLoadConstant:
-    case KernelBytecode::kPushConstant:
-    case KernelBytecode::kIndirectStaticCall:
-    case KernelBytecode::kInterfaceCall:
-    case KernelBytecode::kUncheckedInterfaceCall:
-    case KernelBytecode::kDynamicCall:
-    case KernelBytecode::kStoreStaticTOS:
-    case KernelBytecode::kPushStatic:
-    case KernelBytecode::kAllocate:
-    case KernelBytecode::kInstantiateType:
+    case KernelBytecode::kLoadConstant_Wide:
     case KernelBytecode::kInstantiateTypeArgumentsTOS:
+    case KernelBytecode::kInstantiateTypeArgumentsTOS_Wide:
     case KernelBytecode::kAssertAssignable:
-      return true;
+    case KernelBytecode::kAssertAssignable_Wide:
+      return KernelBytecode::DecodeE(instr);
+
+    case KernelBytecode::kPushConstant:
+    case KernelBytecode::kPushConstant_Wide:
+    case KernelBytecode::kStoreStaticTOS:
+    case KernelBytecode::kStoreStaticTOS_Wide:
+    case KernelBytecode::kPushStatic:
+    case KernelBytecode::kPushStatic_Wide:
+    case KernelBytecode::kAllocate:
+    case KernelBytecode::kAllocate_Wide:
+    case KernelBytecode::kAllocateClosure:
+    case KernelBytecode::kAllocateClosure_Wide:
+    case KernelBytecode::kInstantiateType:
+    case KernelBytecode::kInstantiateType_Wide:
+    case KernelBytecode::kDirectCall:
+    case KernelBytecode::kDirectCall_Wide:
+    case KernelBytecode::kInterfaceCall:
+    case KernelBytecode::kInterfaceCall_Wide:
+    case KernelBytecode::kUncheckedInterfaceCall:
+    case KernelBytecode::kUncheckedInterfaceCall_Wide:
+    case KernelBytecode::kDynamicCall:
+    case KernelBytecode::kDynamicCall_Wide:
+      return KernelBytecode::DecodeD(instr);
+
     default:
-      return false;
+      return -1;
   }
 }
 
 static bool GetLoadedObjectAt(uword pc,
                               const ObjectPool& object_pool,
                               Object* obj) {
-  KBCInstr instr = KernelBytecode::At(pc);
-  if (HasLoadFromPool(instr)) {
-    uint16_t index = KernelBytecode::DecodeD(instr);
+  const KBCInstr* instr = reinterpret_cast<const KBCInstr*>(pc);
+  const intptr_t index = GetConstantPoolIndex(instr);
+  if (index >= 0) {
     if (object_pool.TypeAt(index) == ObjectPool::EntryType::kTaggedObject) {
       *obj = object_pool.ObjectAt(index);
       return true;
@@ -251,19 +328,26 @@
                                                    const Bytecode& bytecode,
                                                    Object** object,
                                                    uword pc) {
-  const uint32_t instr = *reinterpret_cast<uint32_t*>(pc);
-  const uint8_t opcode = instr & 0xFF;
+  const KBCInstr* instr = reinterpret_cast<const KBCInstr*>(pc);
+  const KernelBytecode::Opcode opcode = KernelBytecode::DecodeOpcode(instr);
   ASSERT(opcode < kOpcodeCount);
+  const intptr_t instr_size = KernelBytecode::kInstructionSize[opcode];
+
   size_t name_size =
       Utils::SNPrint(human_buffer, human_size, "%-10s\t", kOpcodeNames[opcode]);
-
   human_buffer += name_size;
   human_size -= name_size;
-  kFormatters[opcode](human_buffer, human_size, pc, instr);
+  kFormatters[opcode](human_buffer, human_size, opcode, instr);
 
-  Utils::SNPrint(hex_buffer, hex_size, "%08x", instr);
+  const intptr_t kCharactersPerByte = 3;
+  if (hex_size > instr_size * kCharactersPerByte) {
+    for (intptr_t i = 0; i < instr_size; ++i) {
+      Utils::SNPrint(hex_buffer + (i * kCharactersPerByte),
+                     hex_size - (i * kCharactersPerByte), " %02x", instr[i]);
+    }
+  }
   if (out_instr_size) {
-    *out_instr_size = sizeof(uint32_t);
+    *out_instr_size = instr_size;
   }
 
   *object = NULL;
diff --git a/runtime/vm/compiler/backend/block_builder.h b/runtime/vm/compiler/backend/block_builder.h
index 22557d7..94b566a 100644
--- a/runtime/vm/compiler/backend/block_builder.h
+++ b/runtime/vm/compiler/backend/block_builder.h
@@ -54,8 +54,9 @@
   }
 
   Definition* AddParameter(intptr_t index, bool with_frame) {
-    return AddToInitialDefinitions(new ParameterInstr(
-        index, flow_graph_->graph_entry(), with_frame ? FPREG : SPREG));
+    auto normal_entry = flow_graph_->graph_entry()->normal_entry();
+    return AddToInitialDefinitions(
+        new ParameterInstr(index, normal_entry, with_frame ? FPREG : SPREG));
   }
 
   TokenPosition TokenPos() { return flow_graph_->function().token_pos(); }
diff --git a/runtime/vm/compiler/backend/block_scheduler.cc b/runtime/vm/compiler/backend/block_scheduler.cc
index af57dfd..51eceea 100644
--- a/runtime/vm/compiler/backend/block_scheduler.cc
+++ b/runtime/vm/compiler/backend/block_scheduler.cc
@@ -219,13 +219,23 @@
     Union(&chains, source_chain, target_chain);
   }
 
+  // Ensure the checked entry remains first to avoid needing another offset on
+  // Instructions, compare Code::EntryPoint.
+  GraphEntryInstr* graph_entry = flow_graph()->graph_entry();
+  flow_graph()->CodegenBlockOrder(true)->Add(graph_entry);
+  FunctionEntryInstr* checked_entry = graph_entry->normal_entry();
+  if (checked_entry != nullptr) {
+    flow_graph()->CodegenBlockOrder(true)->Add(checked_entry);
+  }
   // Build a new block order.  Emit each chain when its first block occurs
   // in the original reverse postorder ordering (which gives a topological
   // sort of the blocks).
   for (intptr_t i = block_count - 1; i >= 0; --i) {
     if (chains[i]->first->block == flow_graph()->postorder()[i]) {
       for (Link* link = chains[i]->first; link != NULL; link = link->next) {
-        flow_graph()->CodegenBlockOrder(true)->Add(link->block);
+        if ((link->block != checked_entry) && (link->block != graph_entry)) {
+          flow_graph()->CodegenBlockOrder(true)->Add(link->block);
+        }
       }
     }
   }
@@ -274,20 +284,20 @@
     }
   }
 
-  // Emit code in reverse postorder but move any throwing blocks to the very
-  // end.
+  // Emit code in reverse postorder but move any throwing blocks (except the
+  // function entry, which needs to come first) to the very end.
   auto& codegen_order = *flow_graph()->CodegenBlockOrder(true);
   for (intptr_t i = 0; i < block_count; ++i) {
     auto block = reverse_postorder[i];
     const intptr_t preorder_nr = block->preorder_number();
-    if (!is_terminating[preorder_nr]) {
+    if (!is_terminating[preorder_nr] || block->IsFunctionEntry()) {
       codegen_order.Add(block);
     }
   }
   for (intptr_t i = 0; i < block_count; ++i) {
     auto block = reverse_postorder[i];
     const intptr_t preorder_nr = block->preorder_number();
-    if (is_terminating[preorder_nr]) {
+    if (is_terminating[preorder_nr] && !block->IsFunctionEntry()) {
       codegen_order.Add(block);
     }
   }
diff --git a/runtime/vm/compiler/backend/constant_propagator.cc b/runtime/vm/compiler/backend/constant_propagator.cc
index acf4f9c..931ffa3 100644
--- a/runtime/vm/compiler/backend/constant_propagator.cc
+++ b/runtime/vm/compiler/backend/constant_propagator.cc
@@ -844,15 +844,9 @@
 }
 
 void ConstantPropagator::VisitLoadClassId(LoadClassIdInstr* instr) {
-  intptr_t cid = instr->object()->Type()->ToCid();
-  if (cid != kDynamicCid) {
-    SetValue(instr, Smi::ZoneHandle(Z, Smi::New(cid)));
-    return;
-  }
-
   const Object& object = instr->object()->definition()->constant_value();
   if (IsConstant(object)) {
-    cid = object.GetClassId();
+    const intptr_t cid = object.GetClassId();
     SetValue(instr, Smi::ZoneHandle(Z, Smi::New(cid)));
     return;
   }
diff --git a/runtime/vm/compiler/backend/flow_graph.cc b/runtime/vm/compiler/backend/flow_graph.cc
index 40eac02..7761a49 100644
--- a/runtime/vm/compiler/backend/flow_graph.cc
+++ b/runtime/vm/compiler/backend/flow_graph.cc
@@ -27,7 +27,6 @@
 DEFINE_FLAG(bool, trace_smi_widening, false, "Trace Smi->Int32 widening pass.");
 #endif
 DEFINE_FLAG(bool, prune_dead_locals, true, "optimize dead locals away");
-DECLARE_FLAG(bool, verify_compiler);
 
 // Quick access to the current zone.
 #define Z (zone())
@@ -154,6 +153,9 @@
 void FlowGraph::AddToInitialDefinitions(BlockEntryWithInitialDefs* entry,
                                         Definition* defn) {
   defn->set_previous(entry);
+  if (auto par = defn->AsParameter()) {
+    par->set_block(entry);  // set cached block
+  }
   entry->initial_definitions()->Add(defn);
 }
 
@@ -299,80 +301,6 @@
   if (changed) DiscoverBlocks();
 }
 
-// Debugging code to verify the construction of use lists.
-static intptr_t MembershipCount(Value* use, Value* list) {
-  intptr_t count = 0;
-  while (list != NULL) {
-    if (list == use) ++count;
-    list = list->next_use();
-  }
-  return count;
-}
-
-static void VerifyUseListsInInstruction(Instruction* instr) {
-  ASSERT(instr != NULL);
-  ASSERT(!instr->IsJoinEntry());
-  for (intptr_t i = 0; i < instr->InputCount(); ++i) {
-    Value* use = instr->InputAt(i);
-    ASSERT(use->definition() != NULL);
-    ASSERT((use->definition() != instr) || use->definition()->IsPhi() ||
-           use->definition()->IsMaterializeObject());
-    ASSERT(use->instruction() == instr);
-    ASSERT(use->use_index() == i);
-    ASSERT(!FLAG_verify_compiler ||
-           (1 == MembershipCount(use, use->definition()->input_use_list())));
-  }
-  if (instr->env() != NULL) {
-    intptr_t use_index = 0;
-    for (Environment::DeepIterator it(instr->env()); !it.Done(); it.Advance()) {
-      Value* use = it.CurrentValue();
-      ASSERT(use->definition() != NULL);
-      ASSERT((use->definition() != instr) || use->definition()->IsPhi());
-      ASSERT(use->instruction() == instr);
-      ASSERT(use->use_index() == use_index++);
-      ASSERT(!FLAG_verify_compiler ||
-             (1 == MembershipCount(use, use->definition()->env_use_list())));
-    }
-  }
-  Definition* defn = instr->AsDefinition();
-  if (defn != NULL) {
-    // Used definitions must have an SSA name.  We use the name to index
-    // into bit vectors during analyses.  Some definitions without SSA names
-    // (e.g., PushArgument) have environment uses.
-    ASSERT((defn->input_use_list() == NULL) || defn->HasSSATemp());
-    Value* prev = NULL;
-    Value* curr = defn->input_use_list();
-    while (curr != NULL) {
-      ASSERT(prev == curr->previous_use());
-      ASSERT(defn == curr->definition());
-      Instruction* instr = curr->instruction();
-      // The instruction should not be removed from the graph.
-      ASSERT((instr->IsPhi() && instr->AsPhi()->is_alive()) ||
-             (instr->previous() != NULL));
-      ASSERT(curr == instr->InputAt(curr->use_index()));
-      prev = curr;
-      curr = curr->next_use();
-    }
-
-    prev = NULL;
-    curr = defn->env_use_list();
-    while (curr != NULL) {
-      ASSERT(prev == curr->previous_use());
-      ASSERT(defn == curr->definition());
-      Instruction* instr = curr->instruction();
-      ASSERT(curr == instr->env()->ValueAtUseIndex(curr->use_index()));
-      // BlockEntry instructions have environments attached to them but
-      // have no reliable way to verify if they are still in the graph.
-      // Thus we just assume they are.
-      ASSERT(instr->IsBlockEntry() ||
-             (instr->IsPhi() && instr->AsPhi()->is_alive()) ||
-             (instr->previous() != NULL));
-      prev = curr;
-      curr = curr->next_use();
-    }
-  }
-}
-
 void FlowGraph::ComputeIsReceiverRecursive(
     PhiInstr* phi,
     GrowableArray<PhiInstr*>* unmark) const {
@@ -574,31 +502,6 @@
   InsertBefore(call, guard, call->env(), FlowGraph::kEffect);
 }
 
-bool FlowGraph::VerifyUseLists() {
-  // Verify the initial definitions.
-  for (intptr_t i = 0; i < graph_entry_->initial_definitions()->length(); ++i) {
-    VerifyUseListsInInstruction((*graph_entry_->initial_definitions())[i]);
-  }
-
-  // Verify phis in join entries and the instructions in each block.
-  for (intptr_t i = 0; i < preorder_.length(); ++i) {
-    BlockEntryInstr* entry = preorder_[i];
-    JoinEntryInstr* join = entry->AsJoinEntry();
-    if (join != NULL) {
-      for (PhiIterator it(join); !it.Done(); it.Advance()) {
-        PhiInstr* phi = it.Current();
-        ASSERT(phi != NULL);
-        VerifyUseListsInInstruction(phi);
-      }
-    }
-    for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) {
-      VerifyUseListsInInstruction(it.Current());
-    }
-  }
-
-  return true;  // Return true so we can ASSERT validation.
-}
-
 // Verify that a redefinition dominates all uses of the redefined value.
 bool FlowGraph::VerifyRedefinitions() {
   for (BlockIterator block_it = reverse_postorder_iterator(); !block_it.Done();
@@ -1240,7 +1143,7 @@
 
     param->set_ssa_temp_index(alloc_ssa_temp_index());  // New SSA temp.
     (*env)[i] = param;
-    catch_entry->initial_definitions()->Add(param);
+    AddToInitialDefinitions(catch_entry, param);
   }
 }
 
@@ -1595,11 +1498,11 @@
                                                  Definition* original,
                                                  CompileType compile_type) {
   RedefinitionInstr* first = prev->next()->AsRedefinition();
-  if (first != NULL && (first->constrained_type() != NULL)) {
+  if (first != nullptr && (first->constrained_type() != nullptr)) {
     if ((first->value()->definition() == original) &&
         first->constrained_type()->IsEqualTo(&compile_type)) {
       // Already redefined. Do nothing.
-      return NULL;
+      return nullptr;
     }
   }
   RedefinitionInstr* redef = new RedefinitionInstr(new Value(original));
@@ -1610,8 +1513,17 @@
     redef->set_constrained_type(new CompileType(compile_type));
   }
 
-  InsertAfter(prev, redef, NULL, FlowGraph::kValue);
+  InsertAfter(prev, redef, nullptr, FlowGraph::kValue);
   RenameDominatedUses(original, redef, redef);
+
+  if (redef->input_use_list() == nullptr) {
+    // There are no dominated uses, so the newly added Redefinition is useless.
+    // Remove Redefinition to avoid interfering with
+    // BranchSimplifier::Simplify which needs empty blocks.
+    redef->RemoveFromGraph();
+    return nullptr;
+  }
+
   return redef;
 }
 
diff --git a/runtime/vm/compiler/backend/flow_graph.h b/runtime/vm/compiler/backend/flow_graph.h
index 67f47ce..abbfcac 100644
--- a/runtime/vm/compiler/backend/flow_graph.h
+++ b/runtime/vm/compiler/backend/flow_graph.h
@@ -264,8 +264,7 @@
   void ComputeSSA(intptr_t next_virtual_register_number,
                   ZoneGrowableArray<Definition*>* inlining_parameters);
 
-  // Verification methods for debugging.
-  bool VerifyUseLists();
+  // Verification method for debugging.
   bool VerifyRedefinitions();
 
   void DiscoverBlocks();
diff --git a/runtime/vm/compiler/backend/flow_graph_checker.cc b/runtime/vm/compiler/backend/flow_graph_checker.cc
index 8872e8a..8502f63 100644
--- a/runtime/vm/compiler/backend/flow_graph_checker.cc
+++ b/runtime/vm/compiler/backend/flow_graph_checker.cc
@@ -13,6 +13,22 @@
 
 namespace dart {
 
+DECLARE_FLAG(bool, trace_compiler);
+
+DEFINE_FLAG(int,
+            verify_definitions_threshold,
+            250,
+            "Definition count threshold for extensive instruction checks");
+
+// Returns true for the "optimized out" and "null" constant.
+static bool IsSpecialConstant(Definition* def) {
+  if (auto c = def->AsConstant()) {
+    return c->value().raw() == Symbols::OptimizedOut().raw() ||
+           c->value().raw() == Object::ZoneHandle().raw();
+  }
+  return false;
+}
+
 // Returns true if block is a predecessor of succ.
 static bool IsPred(BlockEntryInstr* block, BlockEntryInstr* succ) {
   for (intptr_t i = 0, n = succ->PredecessorCount(); i < n; ++i) {
@@ -44,10 +60,9 @@
   return false;
 }
 
-// Returns true if instruction appears on def's use list.
-static bool IsInDefUseList(Definition* def, Instruction* instruction) {
-  for (Value* use = def->input_use_list(); use != nullptr;
-       use = use->next_use()) {
+// Returns true if instruction appears in use list.
+static bool IsInUseList(Value* use, Instruction* instruction) {
+  for (; use != nullptr; use = use->next_use()) {
     if (use->instruction() == instruction) {
       return true;
     }
@@ -55,6 +70,32 @@
   return false;
 }
 
+// Returns true if definition dominates instruction. Note that this
+// helper is required to account for some situations that are not
+// accounted for in the IR methods that compute dominance.
+static bool DefDominatesUse(Definition* def, Instruction* instruction) {
+  if (instruction->IsPhi()) {
+    // A phi use is not necessarily dominated by a definition.
+    // Proper dominance relation on the input values of Phis is
+    // checked by the Phi visitor below.
+    return true;
+  } else if (def->IsMaterializeObject() || instruction->IsMaterializeObject()) {
+    // These instructions reside outside the IR.
+    return true;
+  } else if (auto entry =
+                 instruction->GetBlock()->AsBlockEntryWithInitialDefs()) {
+    // An initial definition in the same block.
+    // TODO(ajcbik): use an initial def too?
+    for (auto idef : *entry->initial_definitions()) {
+      if (idef == def) {
+        return true;
+      }
+    }
+  }
+  // Use the standard IR method for dominance.
+  return instruction->IsDominatedBy(def);
+}
+
 // Returns true if instruction forces control flow.
 static bool IsControlFlow(Instruction* instruction) {
   return instruction->IsBranch() || instruction->IsGoto() ||
@@ -108,27 +149,44 @@
     // Visit all instructions in this block.
     VisitInstructions(block);
   }
-
-  // Flow graph built-in verification.
-  // TODO(ajcbik): migrate actual code into checker too?
-  ASSERT(flow_graph_->VerifyUseLists());
 }
 
 void FlowGraphChecker::VisitInstructions(BlockEntryInstr* block) {
   // To avoid excessive runtimes, skip the instructions check if there
   // are many definitions (as happens in e.g. an initialization block).
-  if (flow_graph_->current_ssa_temp_index() > 10000) {
+  if (flow_graph_->current_ssa_temp_index() >
+      FLAG_verify_definitions_threshold) {
     return;
   }
   // Give all visitors quick access.
   current_block_ = block;
+  // Visit initial definitions.
+  if (auto entry = block->AsBlockEntryWithInitialDefs()) {
+    for (auto def : *entry->initial_definitions()) {
+      ASSERT(def != nullptr);
+      ASSERT(def->IsConstant() || def->IsParameter() ||
+             def->IsSpecialParameter());
+      // Special constants reside outside the IR.
+      if (IsSpecialConstant(def)) continue;
+      // Make sure block lookup agrees.
+      ASSERT(def->GetBlock() == entry);
+      // Initial definitions are partially linked into graph.
+      ASSERT(def->next() == nullptr);
+      ASSERT(def->previous() == entry);
+      // Visit the initial definition as instruction.
+      VisitInstruction(def);
+    }
+  }
   // Visit phis in join.
-  if (auto join_entry = block->AsJoinEntry()) {
-    for (PhiIterator it(join_entry); !it.Done(); it.Advance()) {
+  if (auto entry = block->AsJoinEntry()) {
+    for (PhiIterator it(entry); !it.Done(); it.Advance()) {
       PhiInstr* phi = it.Current();
       // Make sure block lookup agrees.
-      ASSERT(phi->GetBlock() == join_entry);
-      // Visit phi as instruction.
+      ASSERT(phi->GetBlock() == entry);
+      // Phis are never linked into graph.
+      ASSERT(phi->next() == nullptr);
+      ASSERT(phi->previous() == nullptr);
+      // Visit the phi as instruction.
       VisitInstruction(phi);
     }
   }
@@ -147,9 +205,11 @@
     prev = instruction;
     // Make sure control flow makes sense.
     ASSERT(IsControlFlow(instruction) == (instruction == last));
-    // Perform instruction specific checks.
+    ASSERT(!instruction->IsPhi());
+    // Visit the instruction.
     VisitInstruction(instruction);
   }
+  ASSERT(prev->next() == nullptr);
   ASSERT(prev == last);
   // Make sure loop information, when up-to-date, agrees.
   if (flow_graph_->loop_hierarchy_ != nullptr) {
@@ -161,30 +221,16 @@
 }
 
 void FlowGraphChecker::VisitInstruction(Instruction* instruction) {
-  // Make sure all inputs are properly defined by something that
-  // dominates the use that is not a Phi instruction (note that the
-  // proper dominance relation on the input values of Phis are checked
-  // by the Phi visitor below). Also verify some graph sanity.
+  ASSERT(!instruction->IsBlockEntry());
+  // Check all regular inputs.
   for (intptr_t i = 0, n = instruction->InputCount(); i < n; ++i) {
-    Definition* def = instruction->InputAt(i)->definition();
-    bool test_def = def->HasSSATemp();
-    if (def->IsPhi()) {
-      // Phis are never linked into graph.
-      ASSERT(def->next() == nullptr);
-      ASSERT(def->previous() == nullptr);
-    } else if (def->IsConstant() || def->IsParameter() ||
-               def->IsSpecialParameter()) {
-      test_def = false;
-    } else {
-      ASSERT(def->next() != nullptr);
-      ASSERT(def->previous() != nullptr);
-    }
-    if (test_def) {
-      ASSERT(IsInDefUseList(def, instruction));  // proper def-use
-      ASSERT(instruction->IsPhi() ||
-             instruction->IsMaterializeObject() ||  // does not have dominance
-             instruction->IsDominatedBy(def));
-    }
+    VisitUseDef(instruction, instruction->InputAt(i), i, /*is_env*/ false);
+  }
+  // Check all environment inputs.
+  intptr_t i = 0;
+  for (Environment::DeepIterator it(instruction->env()); !it.Done();
+       it.Advance()) {
+    VisitUseDef(instruction, it.CurrentValue(), i++, /*is_env*/ true);
   }
   // Visit specific instructions (definitions and anything with Visit()).
   if (auto def = instruction->AsDefinition()) {
@@ -194,53 +240,125 @@
 }
 
 void FlowGraphChecker::VisitDefinition(Definition* def) {
-  // Make sure each outgoing use is dominated by this def, or is a
-  // Phi instruction (note that the proper dominance relation on
-  // the input values of Phis are checked by the Phi visitor below).
-  // Also verify some graph sanity.
+  // Used definitions must have an SSA name.
+  ASSERT(def->HasSSATemp() || def->input_use_list() == nullptr);
+  // Check all regular uses.
+  Value* prev = nullptr;
   for (Value* use = def->input_use_list(); use != nullptr;
        use = use->next_use()) {
-    ASSERT(use->definition() == def);  // proper use-def
-    Instruction* use_instr = use->instruction();
-    ASSERT(use_instr != nullptr);
-    if (use_instr->IsPhi()) {
-      ASSERT(use_instr->next() == nullptr);
-      ASSERT(use_instr->previous() == nullptr);
-      ASSERT(use_instr->GetBlock()->IsJoinEntry());
+    VisitDefUse(def, use, prev, /*is_env*/ false);
+    prev = use;
+  }
+  // Check all environment uses.
+  prev = nullptr;
+  for (Value* use = def->env_use_list(); use != nullptr;
+       use = use->next_use()) {
+    VisitDefUse(def, use, prev, /*is_env*/ true);
+    prev = use;
+  }
+}
+
+void FlowGraphChecker::VisitUseDef(Instruction* instruction,
+                                   Value* use,
+                                   intptr_t index,
+                                   bool is_env) {
+  ASSERT(use->instruction() == instruction);
+  ASSERT(use->use_index() == index);
+  // Get definition.
+  Definition* def = use->definition();
+  ASSERT(def != nullptr);
+  ASSERT(def != instruction || def->IsPhi() || def->IsMaterializeObject());
+  // Make sure each input is properly defined in the graph by something
+  // that dominates the input (note that the proper dominance relation
+  // on the input values of Phis is checked by the Phi visitor below).
+  bool test_def = def->HasSSATemp();
+  if (def->IsPhi()) {
+    ASSERT(def->GetBlock()->IsJoinEntry());
+    // Phis are never linked into graph.
+    ASSERT(def->next() == nullptr);
+    ASSERT(def->previous() == nullptr);
+  } else if (def->IsConstant() || def->IsParameter() ||
+             def->IsSpecialParameter()) {
+    // Initial definitions are partially linked into graph, but some
+    // constants are fully linked into graph (so no next() assert).
+    ASSERT(def->previous() != nullptr);
+  } else {
+    // Others are fully linked into graph.
+    ASSERT(def->next() != nullptr);
+    ASSERT(def->previous() != nullptr);
+  }
+  if (test_def) {
+    ASSERT(is_env ||  // TODO(dartbug.com/36899)
+           DefDominatesUse(def, instruction));
+    if (is_env) {
+      ASSERT(IsInUseList(def->env_use_list(), instruction));
     } else {
-      ASSERT(IsControlFlow(use_instr) || use_instr->next() != nullptr);
-      ASSERT(use_instr->previous() != nullptr);
-      ASSERT(use_instr->IsMaterializeObject() ||  // does not have dominance
-             use_instr->IsDominatedBy(def));
+      ASSERT(IsInUseList(def->input_use_list(), instruction));
     }
   }
 }
 
+void FlowGraphChecker::VisitDefUse(Definition* def,
+                                   Value* use,
+                                   Value* prev,
+                                   bool is_env) {
+  ASSERT(use->definition() == def);
+  ASSERT(use->previous_use() == prev);
+  // Get using instruction.
+  Instruction* instruction = use->instruction();
+  ASSERT(instruction != nullptr);
+  ASSERT(def != instruction || def->IsPhi() || def->IsMaterializeObject());
+  if (is_env) {
+    ASSERT(instruction->env()->ValueAtUseIndex(use->use_index()) == use);
+  } else {
+    ASSERT(instruction->InputAt(use->use_index()) == use);
+  }
+  // Make sure each use appears in the graph and is properly dominated
+  // by the defintion (note that the proper dominance relation on the
+  // input values of Phis is checked by the Phi visitor below).
+  if (instruction->IsPhi()) {
+    ASSERT(instruction->AsPhi()->is_alive());
+    ASSERT(instruction->GetBlock()->IsJoinEntry());
+    // Phis are never linked into graph.
+    ASSERT(instruction->next() == nullptr);
+    ASSERT(instruction->previous() == nullptr);
+  } else if (instruction->IsBlockEntry()) {
+    // BlockEntry instructions have environments attached to them but
+    // have no reliable way to verify if they are still in the graph.
+    ASSERT(is_env);
+  } else {
+    // Others are fully linked into graph.
+    ASSERT(IsControlFlow(instruction) || instruction->next() != nullptr);
+    ASSERT(instruction->previous() != nullptr);
+    ASSERT(is_env ||  // TODO(dartbug.com/36899)
+           DefDominatesUse(def, instruction));
+  }
+}
+
 void FlowGraphChecker::VisitConstant(ConstantInstr* constant) {
+  // Range check on smi.
   const Object& value = constant->value();
   if (value.IsSmi()) {
     const int64_t smi_value = Integer::Cast(value).AsInt64Value();
     ASSERT(kSmiMin <= smi_value);
     ASSERT(smi_value <= kSmiMax);
   }
-  // TODO(ajcbik): Is this a property we eventually want (all constants
-  // generated by utility that queries pool and put in the graph entry
-  // when seen first)? The inliner still creates some direct constants.
+  // Any constant involved in SSA should appear in the entry (making it more
+  // likely it was inserted by the utility that avoids duplication).
+  //
+  // TODO(dartbug.com/36894)
+  //
   // ASSERT(constant->GetBlock() == flow_graph_->graph_entry());
 }
 
 void FlowGraphChecker::VisitPhi(PhiInstr* phi) {
-  // Phis are never linked into graph.
-  ASSERT(phi->next() == nullptr);
-  ASSERT(phi->previous() == nullptr);
-  // Make sure each incoming input value of a Phi is dominated
-  // on the corresponding incoming edge, as defined by order.
+  // Make sure the definition of each input value of a Phi dominates
+  // the corresponding incoming edge, as defined by order.
   ASSERT(phi->InputCount() == current_block_->PredecessorCount());
   for (intptr_t i = 0, n = phi->InputCount(); i < n; ++i) {
-    Definition* input_def = phi->InputAt(i)->definition();
+    Definition* def = phi->InputAt(i)->definition();
     BlockEntryInstr* edge = current_block_->PredecessorAt(i);
-    ASSERT(input_def->IsConstant() ||  // some constants are in initial defs
-           edge->last_instruction()->IsDominatedBy(input_def));
+    ASSERT(DefDominatesUse(def, edge->last_instruction()));
   }
 }
 
@@ -256,8 +374,15 @@
   ASSERT(branch->SuccessorCount() == 2);
 }
 
+void FlowGraphChecker::VisitRedefinition(RedefinitionInstr* def) {
+  ASSERT(def->value()->definition() != def);
+}
+
 // Main entry point of graph checker.
-void FlowGraphChecker::Check() {
+void FlowGraphChecker::Check(const char* pass_name) {
+  if (FLAG_trace_compiler) {
+    THR_Print("Running checker after %s\n", pass_name);
+  }
   ASSERT(flow_graph_ != nullptr);
   VisitBlocks();
 }
diff --git a/runtime/vm/compiler/backend/flow_graph_checker.h b/runtime/vm/compiler/backend/flow_graph_checker.h
index fba159f..088ad3e 100644
--- a/runtime/vm/compiler/backend/flow_graph_checker.h
+++ b/runtime/vm/compiler/backend/flow_graph_checker.h
@@ -35,7 +35,7 @@
         current_block_(nullptr) {}
 
   // Performs a sanity check on the flow graph.
-  void Check();
+  void Check(const char* pass_name);
 
  private:
   // Custom-made visitors.
@@ -43,6 +43,11 @@
   void VisitInstructions(BlockEntryInstr* block);
   void VisitInstruction(Instruction* instruction);
   void VisitDefinition(Definition* def);
+  void VisitUseDef(Instruction* instruction,
+                   Value* use,
+                   intptr_t index,
+                   bool is_env);
+  void VisitDefUse(Definition* def, Value* use, Value* prev, bool is_env);
 
   // Instruction visitors.
   void VisitConstant(ConstantInstr* constant) override;
@@ -50,6 +55,7 @@
   void VisitGoto(GotoInstr* jmp) override;
   void VisitIndirectGoto(IndirectGotoInstr* jmp) override;
   void VisitBranch(BranchInstr* branch) override;
+  void VisitRedefinition(RedefinitionInstr* def) override;
 
   FlowGraph* const flow_graph_;
   BlockEntryInstr* current_block_;
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler.cc b/runtime/vm/compiler/backend/flow_graph_compiler.cc
index 05a3d92..73c21d8 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler.cc
@@ -321,16 +321,6 @@
 }
 
 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
-#if defined(TARGET_ARCH_ARM64)
-  return 0;
-#endif
-
   BlockEntryInstr* entry = flow_graph().graph_entry()->unchecked_entry();
   if (entry == nullptr) {
     entry = flow_graph().graph_entry()->normal_entry();
@@ -345,12 +335,11 @@
     return target->Position();
   }
 
-// Intrinsification happened.
-#ifdef DART_PRECOMPILER
+  // Intrinsification happened.
   if (parsed_function().function().IsDynamicFunction()) {
     return Instructions::kMonomorphicEntryOffset;
   }
-#endif
+
   return 0;
 }
 
@@ -529,6 +518,13 @@
     flow_graph().ComputeLoops();
   }
 
+  // In precompiled mode, we require the function entry to come first (after the
+  // graph entry), since the polymorphic check is performed in the function
+  // entry (see Instructions::EntryPoint).
+  if (FLAG_precompiled_mode) {
+    ASSERT(block_order()[1] == flow_graph().graph_entry()->normal_entry());
+  }
+
   for (intptr_t i = 0; i < block_order().length(); ++i) {
     // Compile the block entry.
     BlockEntryInstr* entry = block_order()[i];
@@ -561,9 +557,7 @@
     pending_deoptimization_env_ = NULL;
     EndCodeSourceRange(entry->token_pos());
 
-    // The function was fully intrinsified, so there's no need to generate any
-    // more code.
-    if (fully_intrinsified_) {
+    if (skip_body_compilation()) {
       ASSERT(entry == flow_graph().graph_entry()->normal_entry());
       break;
     }
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler.h b/runtime/vm/compiler/backend/flow_graph_compiler.h
index 7f5c1a3..8795377 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler.h
+++ b/runtime/vm/compiler/backend/flow_graph_compiler.h
@@ -418,6 +418,15 @@
   bool CanOSRFunction() const;
   bool is_optimizing() const { return is_optimizing_; }
 
+  // The function was fully intrinsified, so the body is unreachable.
+  //
+  // We still need to compile the body in unoptimized mode because the
+  // 'ICData's are added to the function's 'ic_data_array_' when instance
+  // calls are compiled.
+  bool skip_body_compilation() const {
+    return fully_intrinsified_ && is_optimizing();
+  }
+
   void EnterIntrinsicMode();
   void ExitIntrinsicMode();
   bool intrinsic_mode() const { return intrinsic_mode_; }
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc b/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc
index 0252b7b..d968031 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc
@@ -856,22 +856,13 @@
   __ Ret();
 }
 
-static const Register new_pp = NOTFP;
-
 void FlowGraphCompiler::EmitFrameEntry() {
   const Function& function = parsed_function().function();
   if (CanOptimizeFunction() && function.IsOptimizable() &&
       (!is_optimizing() || may_reoptimize())) {
     __ Comment("Invocation Count Check");
     const Register function_reg = R8;
-    if (!FLAG_precompiled_mode || !FLAG_use_bare_instructions) {
-      // The pool pointer is not setup before entering the Dart frame.
-      // Temporarily setup pool pointer for this dart function.
-      __ LoadPoolPointer(new_pp);
-    }
-    // Load function object from object pool.
-    __ LoadFunctionFromCalleePool(function_reg, function, new_pp);
-
+    __ ldr(function_reg, FieldAddress(CODE_REG, Code::owner_offset()));
     __ ldr(R3, FieldAddress(function_reg, Function::usage_counter_offset()));
     // Reoptimization of an optimized function is triggered by counting in
     // IC stubs, but not at the entry of the function.
@@ -881,8 +872,7 @@
     }
     __ CompareImmediate(R3, GetOptimizationThreshold());
     ASSERT(function_reg == R8);
-    __ Branch(StubCode::OptimizeFunction(),
-              compiler::ObjectPoolBuilderEntry::kNotPatchable, new_pp, GE);
+    __ Branch(Address(THR, Thread::optimize_entry_offset()), GE);
   }
   __ Comment("Enter frame");
   if (flow_graph().IsCompiledForOsr()) {
@@ -944,7 +934,7 @@
 
   __ bkpt(0);
 
-  if (!fully_intrinsified_) {
+  if (!skip_body_compilation()) {
     ASSERT(assembler()->constant_pool_allowed());
     GenerateDeferredCode();
   }
@@ -1071,7 +1061,8 @@
   __ LoadFromOffset(kWord, R0, SP,
                     (ic_data.CountWithoutTypeArgs() - 1) * kWordSize);
   __ LoadUniqueObject(R9, ic_data);
-  GenerateDartCall(deopt_id, token_pos, stub, RawPcDescriptors::kIcCall, locs);
+  GenerateDartCall(deopt_id, token_pos, stub, RawPcDescriptors::kIcCall, locs,
+                   Code::EntryKind::kMonomorphic);
   __ Drop(ic_data.CountWithTypeArgs());
 }
 
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc b/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc
index 0458549..3eeac84 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc
@@ -837,20 +837,11 @@
 
 void FlowGraphCompiler::EmitFrameEntry() {
   const Function& function = parsed_function().function();
-  Register new_pp = kNoRegister;
   if (CanOptimizeFunction() && function.IsOptimizable() &&
       (!is_optimizing() || may_reoptimize())) {
     __ Comment("Invocation Count Check");
     const Register function_reg = R6;
-    new_pp = R13;
-    if (!FLAG_precompiled_mode || !FLAG_use_bare_instructions) {
-      // The pool pointer is not setup before entering the Dart frame.
-      // Temporarily setup pool pointer for this dart function.
-      __ LoadPoolPointer(new_pp);
-    }
-
-    // Load function object using the callee's pool pointer.
-    __ LoadFunctionFromCalleePool(function_reg, function, new_pp);
+    __ ldr(function_reg, FieldAddress(CODE_REG, Code::owner_offset()));
 
     __ LoadFieldFromOffset(R7, function_reg, Function::usage_counter_offset(),
                            kWord);
@@ -865,48 +856,22 @@
     ASSERT(function_reg == R6);
     Label dont_optimize;
     __ b(&dont_optimize, LT);
-    __ Branch(StubCode::OptimizeFunction(), new_pp);
+    __ ldr(TMP, Address(THR, Thread::optimize_entry_offset()));
+    __ br(TMP);
     __ Bind(&dont_optimize);
   }
   __ Comment("Enter frame");
   if (flow_graph().IsCompiledForOsr()) {
     const intptr_t extra_slots = ExtraStackSlotsOnOsrEntry();
     ASSERT(extra_slots >= 0);
-    __ EnterOsrFrame(extra_slots * kWordSize, new_pp);
+    __ EnterOsrFrame(extra_slots * kWordSize);
   } else {
     ASSERT(StackSize() >= 0);
-    __ EnterDartFrame(StackSize() * kWordSize, new_pp);
+    __ EnterDartFrame(StackSize() * kWordSize);
   }
 }
 
-// Input parameters:
-//   LR: return address.
-//   SP: address of last argument.
-//   FP: caller's frame pointer.
-//   PP: caller's pool pointer.
-//   R4: arguments descriptor array.
-void FlowGraphCompiler::CompileGraph() {
-  InitCompiler();
-
-  if (FLAG_precompiled_mode) {
-    const Function& function = parsed_function().function();
-    if (function.IsDynamicFunction()) {
-      SpecialStatsBegin(CombinedCodeStatistics::kTagCheckedEntry);
-      __ MonomorphicCheckedEntry();
-      SpecialStatsEnd(CombinedCodeStatistics::kTagCheckedEntry);
-    }
-  }
-
-  // For JIT we have multiple entrypoints functionality which moved the
-  // intrinsification as well as the setup of the frame to the
-  // [TargetEntryInstr::EmitNativeCode].
-  //
-  // Though this has not been implemented on ARM64, which is why this code here
-  // is outside the "ifdef DART_PRECOMPILER".
-  if (TryIntrinsify()) {
-    // Skip regular code generation.
-    return;
-  }
+void FlowGraphCompiler::EmitPrologue() {
   EmitFrameEntry();
   ASSERT(assembler()->constant_pool_allowed());
 
@@ -933,11 +898,32 @@
   }
 
   EndCodeSourceRange(TokenPosition::kDartCodePrologue);
+}
+
+// Input parameters:
+//   LR: return address.
+//   SP: address of last argument.
+//   FP: caller's frame pointer.
+//   PP: caller's pool pointer.
+//   R4: arguments descriptor array.
+void FlowGraphCompiler::CompileGraph() {
+  InitCompiler();
+
+  // For JIT we have multiple entrypoints functionality which moved the frame
+  // setup into the [TargetEntryInstr] (which will set the constant pool
+  // allowed bit to true).  Despite this we still have to set the
+  // constant pool allowed bit to true here as well, because we can generate
+  // code for [CatchEntryInstr]s, which need the pool.
+  __ set_constant_pool_allowed(true);
+
   VisitBlocks();
 
   __ brk(0);
-  ASSERT(assembler()->constant_pool_allowed());
-  GenerateDeferredCode();
+
+  if (!skip_body_compilation()) {
+    ASSERT(assembler()->constant_pool_allowed());
+    GenerateDeferredCode();
+  }
 }
 
 void FlowGraphCompiler::GenerateCall(TokenPosition token_pos,
@@ -1054,7 +1040,8 @@
   ASSERT(Array::Handle(zone(), ic_data.arguments_descriptor()).Length() > 0);
   __ LoadFromOffset(R0, SP, (ic_data.CountWithoutTypeArgs() - 1) * kWordSize);
   __ LoadUniqueObject(R5, ic_data);
-  GenerateDartCall(deopt_id, token_pos, stub, RawPcDescriptors::kIcCall, locs);
+  GenerateDartCall(deopt_id, token_pos, stub, RawPcDescriptors::kIcCall, locs,
+                   Code::EntryKind::kMonomorphic);
   __ Drop(ic_data.CountWithTypeArgs());
 }
 
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_dbc.cc b/runtime/vm/compiler/backend/flow_graph_compiler_dbc.cc
index 892cdb5..e3729c7 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_dbc.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_dbc.cc
@@ -340,15 +340,12 @@
   }
 }
 
+void FlowGraphCompiler::EmitPrologue() {
+  EmitFrameEntry();
+}
+
 void FlowGraphCompiler::CompileGraph() {
   InitCompiler();
-
-  if (TryIntrinsify()) {
-    // Skip regular code generation.
-    return;
-  }
-
-  EmitFrameEntry();
   VisitBlocks();
 }
 
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc b/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc
index 0336895..5cf94a8 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc
@@ -775,7 +775,10 @@
     __ cmpl(FieldAddress(function_reg, Function::usage_counter_offset()),
             Immediate(GetOptimizationThreshold()));
     ASSERT(function_reg == EBX);
-    __ J(GREATER_EQUAL, StubCode::OptimizeFunction());
+    Label dont_optimize;
+    __ j(LESS, &dont_optimize, Assembler::kNearJump);
+    __ jmp(Address(THR, Thread::optimize_entry_offset()));
+    __ Bind(&dont_optimize);
   }
   __ Comment("Enter frame");
   if (flow_graph().IsCompiledForOsr()) {
@@ -788,14 +791,7 @@
   }
 }
 
-void FlowGraphCompiler::CompileGraph() {
-  InitCompiler();
-
-  if (TryIntrinsify()) {
-    // Skip regular code generation.
-    return;
-  }
-
+void FlowGraphCompiler::EmitPrologue() {
   EmitFrameEntry();
 
   // In unoptimized code, initialize (non-argument) stack allocated slots.
@@ -823,11 +819,18 @@
   }
 
   EndCodeSourceRange(TokenPosition::kDartCodePrologue);
+}
+
+void FlowGraphCompiler::CompileGraph() {
+  InitCompiler();
+
   ASSERT(!block_order().is_empty());
   VisitBlocks();
 
-  __ int3();
-  GenerateDeferredCode();
+  if (!skip_body_compilation()) {
+    __ int3();
+    GenerateDeferredCode();
+  }
 }
 
 void FlowGraphCompiler::GenerateCall(TokenPosition token_pos,
@@ -928,7 +931,8 @@
   // Load receiver into EBX.
   __ movl(EBX, Address(ESP, (ic_data.CountWithoutTypeArgs() - 1) * kWordSize));
   __ LoadObject(ECX, ic_data);
-  GenerateDartCall(deopt_id, token_pos, stub, RawPcDescriptors::kIcCall, locs);
+  GenerateDartCall(deopt_id, token_pos, stub, RawPcDescriptors::kIcCall, locs,
+                   Code::EntryKind::kMonomorphic);
   __ Drop(ic_data.CountWithTypeArgs());
 }
 
@@ -951,7 +955,6 @@
   __ movl(EBX, Address(ESP, (args_desc.Count() - 1) * kWordSize));
   __ LoadObject(ECX, cache);
   __ call(Address(THR, Thread::megamorphic_call_checked_entry_offset()));
-  __ call(EBX);
 
   AddCurrentDescriptor(RawPcDescriptors::kOther, DeoptId::kNone, token_pos);
   RecordSafepoint(locs, slow_path_argument_count);
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc b/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc
index 91fe976..5542b19 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc
@@ -858,18 +858,12 @@
     ASSERT(extra_slots >= 0);
     __ EnterOsrFrame(extra_slots * kWordSize);
   } else {
-    const Register new_pp = R13;
-    if (!FLAG_precompiled_mode || !FLAG_use_bare_instructions) {
-      __ LoadPoolPointer(new_pp);
-    }
-
     const Function& function = parsed_function().function();
     if (CanOptimizeFunction() && function.IsOptimizable() &&
         (!is_optimizing() || may_reoptimize())) {
       __ Comment("Invocation Count Check");
       const Register function_reg = RDI;
-      // Load function object using the callee's pool pointer.
-      __ LoadFunctionFromCalleePool(function_reg, function, new_pp);
+      __ movq(function_reg, FieldAddress(CODE_REG, Code::owner_offset()));
 
       // Reoptimization of an optimized function is triggered by counting in
       // IC stubs, but not at the entry of the function.
@@ -879,11 +873,14 @@
       __ cmpl(FieldAddress(function_reg, Function::usage_counter_offset()),
               Immediate(GetOptimizationThreshold()));
       ASSERT(function_reg == RDI);
-      __ J(GREATER_EQUAL, StubCode::OptimizeFunction(), new_pp);
+      Label dont_optimize;
+      __ j(LESS, &dont_optimize, Assembler::kNearJump);
+      __ jmp(Address(THR, Thread::optimize_entry_offset()));
+      __ Bind(&dont_optimize);
     }
     ASSERT(StackSize() >= 0);
     __ Comment("Enter frame");
-    __ EnterDartFrame(StackSize() * kWordSize, new_pp);
+    __ EnterDartFrame(StackSize() * kWordSize);
   }
 }
 
@@ -933,7 +930,7 @@
 
   __ int3();
 
-  if (!fully_intrinsified_) {
+  if (!skip_body_compilation()) {
     ASSERT(assembler()->constant_pool_allowed());
     GenerateDeferredCode();
   }
@@ -1063,7 +1060,8 @@
   // Load receiver into RDX.
   __ movq(RDX, Address(RSP, (ic_data.CountWithoutTypeArgs() - 1) * kWordSize));
   __ LoadUniqueObject(RBX, ic_data);
-  GenerateDartCall(deopt_id, token_pos, stub, RawPcDescriptors::kIcCall, locs);
+  GenerateDartCall(deopt_id, token_pos, stub, RawPcDescriptors::kIcCall, locs,
+                   Code::EntryKind::kMonomorphic);
   __ Drop(ic_data.CountWithTypeArgs(), RCX);
 }
 
diff --git a/runtime/vm/compiler/backend/il.cc b/runtime/vm/compiler/backend/il.cc
index dee6cab..c2aeb5e 100644
--- a/runtime/vm/compiler/backend/il.cc
+++ b/runtime/vm/compiler/backend/il.cc
@@ -3414,6 +3414,15 @@
   return cids().HasClassId(value_cid) ? NULL : this;
 }
 
+Definition* LoadClassIdInstr::Canonicalize(FlowGraph* flow_graph) {
+  const intptr_t cid = object()->Type()->ToCid();
+  if (cid != kDynamicCid) {
+    const auto& smi = Smi::ZoneHandle(flow_graph->zone(), Smi::New(cid));
+    return flow_graph->GetConstant(smi);
+  }
+  return this;
+}
+
 Instruction* CheckClassIdInstr::Canonicalize(FlowGraph* flow_graph) {
   if (value()->BindsToConstant()) {
     const Object& constant_value = value()->BoundConstant();
@@ -3822,21 +3831,26 @@
 // fall-through code in [FlowGraphCompiler::CompileGraph()].
 // (As opposed to here where we don't check for the return value of
 // [Intrinsify]).
-#if defined(TARGET_ARCH_X64) || defined(TARGET_ARCH_ARM)
-  if (FLAG_precompiled_mode) {
-    const Function& function = compiler->parsed_function().function();
-    if (function.IsDynamicFunction()) {
-      compiler->SpecialStatsBegin(CombinedCodeStatistics::kTagCheckedEntry);
-      __ MonomorphicCheckedEntry();
-      compiler->SpecialStatsEnd(CombinedCodeStatistics::kTagCheckedEntry);
-    }
+  const Function& function = compiler->parsed_function().function();
+  if (function.IsDynamicFunction()) {
+    compiler->SpecialStatsBegin(CombinedCodeStatistics::kTagCheckedEntry);
+    __ MonomorphicCheckedEntry();
+    compiler->SpecialStatsEnd(CombinedCodeStatistics::kTagCheckedEntry);
   }
-  // NOTE: Because in X64/ARM mode the graph can have multiple entrypoints, we
-  // generate several times the same intrinsification & frame setup. That's why
-  // we cannot rely on the constant pool being `false` when we come in here.
+
+  // NOTE: Because of the presence of multiple entry-points, we generate several
+  // times the same intrinsification & frame setup. That's why we cannot rely on
+  // the constant pool being `false` when we come in here.
+#if defined(TARGET_USES_OBJECT_POOL)
   __ set_constant_pool_allowed(false);
-  if (compiler->TryIntrinsify()) return;
+#endif
+
+  if (compiler->TryIntrinsify() && compiler->skip_body_compilation()) {
+    return;
+  }
   compiler->EmitPrologue();
+
+#if defined(TARGET_USES_OBJECT_POOL)
   ASSERT(__ constant_pool_allowed());
 #endif
 
@@ -3874,13 +3888,16 @@
   ASSERT(compiler->is_optimizing());
   __ Bind(compiler->GetJumpLabel(this));
 
-#if defined(TARGET_ARCH_X64) || defined(TARGET_ARCH_ARM)
-  // NOTE: Because in JIT X64/ARM mode the graph can have multiple
-  // entrypoints, so we generate several times the same intrinsification &
-  // frame setup.  That's why we cannot rely on the constant pool being
-  // `false` when we come in here.
+  // NOTE: Because the graph can have multiple entrypoints, we generate several
+  // times the same intrinsification & frame setup. That's why we cannot rely on
+  // the constant pool being `false` when we come in here.
+#if defined(TARGET_USES_OBJECT_POOL)
   __ set_constant_pool_allowed(false);
+#endif
+
   compiler->EmitPrologue();
+
+#if defined(TARGET_USES_OBJECT_POOL)
   ASSERT(__ constant_pool_allowed());
 #endif
 
@@ -4260,7 +4277,7 @@
 }
 
 bool InstanceCallInstr::MatchesCoreName(const String& name) {
-  return function_name().raw() == Library::PrivateCoreLibName(name).raw();
+  return Library::IsPrivateCoreLibName(function_name(), name);
 }
 
 RawFunction* InstanceCallInstr::ResolveForReceiverClass(
@@ -5272,10 +5289,6 @@
 
 #endif  // defined(TARGET_ARCH_ARM)
 
-#if !defined(TARGET_ARCH_DBC)
-
-#define Z zone_
-
 Representation FfiCallInstr::RequiredInputRepresentation(intptr_t idx) const {
   if (idx == TargetAddressIndex()) {
     return kUnboxedFfiIntPtr;
@@ -5284,6 +5297,10 @@
   }
 }
 
+#if !defined(TARGET_ARCH_DBC)
+
+#define Z zone_
+
 LocationSummary* FfiCallInstr::MakeLocationSummary(Zone* zone,
                                                    bool is_optimizing) const {
   // The temporary register needs to be callee-saved and not an argument
@@ -5337,10 +5354,6 @@
   return summary;
 }
 
-Representation FfiCallInstr::representation() const {
-  return compiler::ffi::ResultRepresentation(signature_);
-}
-
 Location FfiCallInstr::UnallocateStackSlots(Location in, bool is_atomic) {
   if (in.IsPairLocation()) {
     ASSERT(!is_atomic);
@@ -5361,21 +5374,34 @@
 
 #else
 
-Representation FfiCallInstr::RequiredInputRepresentation(intptr_t idx) const {
-  UNREACHABLE();
-}
-
 LocationSummary* FfiCallInstr::MakeLocationSummary(Zone* zone,
                                                    bool is_optimizing) const {
-  UNREACHABLE();
-}
+  LocationSummary* summary =
+      new (zone) LocationSummary(zone, /*num_inputs=*/InputCount(),
+                                 /*num_temps=*/0, LocationSummary::kCall);
 
-Representation FfiCallInstr::representation() const {
-  UNREACHABLE();
+  summary->set_in(
+      TargetAddressIndex(),
+      Location::RegisterLocation(compiler::ffi::kFunctionAddressRegister));
+  for (intptr_t i = 0, n = NativeArgCount(); i < n; ++i) {
+    summary->set_in(i, arg_locations_[i]);
+  }
+  summary->set_out(0, compiler::ffi::ResultLocation(
+                          compiler::ffi::ResultHostRepresentation(signature_)));
+
+  return summary;
 }
 
 #endif  // !defined(TARGET_ARCH_DBC)
 
+Representation FfiCallInstr::representation() const {
+#if !defined(TARGET_ARCH_DBC)
+  return compiler::ffi::ResultRepresentation(signature_);
+#else
+  return compiler::ffi::ResultHostRepresentation(signature_);
+#endif  // !defined(TARGET_ARCH_DBC)
+}
+
 // SIMD
 
 SimdOpInstr* SimdOpInstr::CreateFromCall(Zone* zone,
diff --git a/runtime/vm/compiler/backend/il.h b/runtime/vm/compiler/backend/il.h
index 5450f5f..3e91b50 100644
--- a/runtime/vm/compiler/backend/il.h
+++ b/runtime/vm/compiler/backend/il.h
@@ -2160,6 +2160,7 @@
 
   // Get the block entry for that instruction.
   virtual BlockEntryInstr* GetBlock() { return block_; }
+  void set_block(BlockEntryInstr* block) { block_ = block; }
 
   intptr_t InputCount() const { return 0; }
   Value* InputAt(intptr_t i) const {
@@ -4162,13 +4163,15 @@
                intptr_t deopt_id,
                const Function& signature,
                const ZoneGrowableArray<Representation>& arg_reps,
-               const ZoneGrowableArray<Location>& arg_locs)
+               const ZoneGrowableArray<Location>& arg_locs,
+               const ZoneGrowableArray<HostLocation>* arg_host_locs = nullptr)
       : Definition(deopt_id),
         zone_(zone),
         signature_(signature),
         inputs_(arg_reps.length() + 1),
         arg_representations_(arg_reps),
-        arg_locations_(arg_locs) {
+        arg_locations_(arg_locs),
+        arg_host_locations_(arg_host_locs) {
     inputs_.FillWith(nullptr, 0, arg_reps.length() + 1);
     ASSERT(signature.IsZoneHandle());
   }
@@ -4208,6 +4211,7 @@
   GrowableArray<Value*> inputs_;
   const ZoneGrowableArray<Representation>& arg_representations_;
   const ZoneGrowableArray<Location>& arg_locations_;
+  const ZoneGrowableArray<HostLocation>* arg_host_locations_;
 
   DISALLOW_COPY_AND_ASSIGN(FfiCallInstr);
 };
@@ -5243,6 +5247,8 @@
   DECLARE_INSTRUCTION(LoadClassId)
   virtual CompileType ComputeType() const;
 
+  virtual Definition* Canonicalize(FlowGraph* flow_graph);
+
   Value* object() const { return inputs_[0]; }
 
   virtual bool ComputeCanDeoptimize() const { return false; }
diff --git a/runtime/vm/compiler/backend/il_arm.cc b/runtime/vm/compiler/backend/il_arm.cc
index ebe2a08..cf86087 100644
--- a/runtime/vm/compiler/backend/il_arm.cc
+++ b/runtime/vm/compiler/backend/il_arm.cc
@@ -6797,10 +6797,15 @@
 
 void GraphEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   BlockEntryInstr* entry = normal_entry();
-  if (entry == nullptr) entry = osr_entry();
-
-  if (!compiler->CanFallThroughTo(entry)) {
-    __ b(compiler->GetJumpLabel(entry));
+  if (entry != nullptr) {
+    if (!compiler->CanFallThroughTo(entry)) {
+      FATAL("Checked function entry must have no offset");
+    }
+  } else {
+    entry = osr_entry();
+    if (!compiler->CanFallThroughTo(entry)) {
+      __ b(compiler->GetJumpLabel(entry));
+    }
   }
 }
 
diff --git a/runtime/vm/compiler/backend/il_arm64.cc b/runtime/vm/compiler/backend/il_arm64.cc
index 198269b..1bf08fc 100644
--- a/runtime/vm/compiler/backend/il_arm64.cc
+++ b/runtime/vm/compiler/backend/il_arm64.cc
@@ -5954,10 +5954,15 @@
 
 void GraphEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   BlockEntryInstr* entry = normal_entry();
-  if (entry == nullptr) entry = osr_entry();
-
-  if (!compiler->CanFallThroughTo(entry)) {
-    __ b(compiler->GetJumpLabel(entry));
+  if (entry != nullptr) {
+    if (!compiler->CanFallThroughTo(entry)) {
+      FATAL("Checked function entry must have no offset");
+    }
+  } else {
+    entry = osr_entry();
+    if (!compiler->CanFallThroughTo(entry)) {
+      __ b(compiler->GetJumpLabel(entry));
+    }
   }
 }
 
diff --git a/runtime/vm/compiler/backend/il_dbc.cc b/runtime/vm/compiler/backend/il_dbc.cc
index 107a3c8..dad840e 100644
--- a/runtime/vm/compiler/backend/il_dbc.cc
+++ b/runtime/vm/compiler/backend/il_dbc.cc
@@ -992,7 +992,16 @@
 }
 
 void FfiCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  UNREACHABLE();
+  const Representation result_rep =
+      compiler::ffi::ResultHostRepresentation(signature_);
+  // TODO(36809): In 32 bit we'll need a result location as well.
+  const TypedData& signature_descriptor =
+      TypedData::Handle(compiler::ffi::FfiSignatureDescriptor::New(
+          *arg_host_locations_, result_rep));
+
+  const intptr_t sigdesc_kidx = __ AddConstant(signature_descriptor);
+
+  __ FfiCall(sigdesc_kidx);
 }
 
 EMIT_NATIVE_CODE(NativeCall,
@@ -1325,10 +1334,15 @@
 
 void GraphEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   BlockEntryInstr* entry = normal_entry();
-  if (entry == nullptr) entry = osr_entry();
-
-  if (!compiler->CanFallThroughTo(entry)) {
-    __ Jump(compiler->GetJumpLabel(entry));
+  if (entry != nullptr) {
+    if (!compiler->CanFallThroughTo(entry)) {
+      FATAL("Checked function entry must have no offset");
+    }
+  } else {
+    entry = osr_entry();
+    if (!compiler->CanFallThroughTo(entry)) {
+      __ Jump(compiler->GetJumpLabel(entry));
+    }
   }
 }
 
@@ -1704,9 +1718,13 @@
 }
 
 EMIT_NATIVE_CODE(Box, 1, Location::RequiresRegister(), LocationSummary::kCall) {
-  ASSERT(from_representation() == kUnboxedDouble);
+  ASSERT(from_representation() == kUnboxedDouble ||
+         from_representation() == kUnboxedFloat);
   const Register value = locs()->in(0).reg();
   const Register out = locs()->out(0).reg();
+  if (from_representation() == kUnboxedFloat) {
+    __ FloatToDouble(value, value);
+  }
   EmitAllocateBox(compiler);
   __ WriteIntoDouble(out, value);
 }
@@ -1716,24 +1734,31 @@
     EmitLoadInt64FromBoxOrSmi(compiler);
     return;
   }
-  ASSERT(representation() == kUnboxedDouble);
+  ASSERT(representation() == kUnboxedDouble ||
+         representation() == kUnboxedFloat);
   const intptr_t value_cid = value()->Type()->ToCid();
   const intptr_t box_cid = BoxCid();
   const Register box = locs()->in(0).reg();
   const Register result = locs()->out(0).reg();
-  if (value_cid == box_cid) {
+  if (value_cid == box_cid ||
+      (speculative_mode() == kNotSpeculative && value_cid != kSmiCid)) {
     __ UnboxDouble(result, box);
   } else if (CanConvertSmi() && (value_cid == kSmiCid)) {
     __ SmiToDouble(result, box);
   } else if ((value()->Type()->ToNullableCid() == box_cid) &&
              value()->Type()->is_nullable()) {
     __ IfEqNull(box);
+    ASSERT(CanDeoptimize());
     compiler->EmitDeopt(GetDeoptId(), ICData::kDeoptCheckClass);
     __ UnboxDouble(result, box);
   } else {
     __ CheckedUnboxDouble(result, box);
+    ASSERT(CanDeoptimize());
     compiler->EmitDeopt(GetDeoptId(), ICData::kDeoptCheckClass);
   }
+  if (representation() == kUnboxedFloat) {
+    __ DoubleToFloat(result, result);
+  }
 }
 
 EMIT_NATIVE_CODE(UnboxInteger32, 1, Location::RequiresRegister()) {
diff --git a/runtime/vm/compiler/backend/il_ia32.cc b/runtime/vm/compiler/backend/il_ia32.cc
index 349a09c..403ca00 100644
--- a/runtime/vm/compiler/backend/il_ia32.cc
+++ b/runtime/vm/compiler/backend/il_ia32.cc
@@ -6075,10 +6075,15 @@
 
 void GraphEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   BlockEntryInstr* entry = normal_entry();
-  if (entry == nullptr) entry = osr_entry();
-
-  if (!compiler->CanFallThroughTo(entry)) {
-    __ jmp(compiler->GetJumpLabel(entry));
+  if (entry != nullptr) {
+    if (!compiler->CanFallThroughTo(entry)) {
+      FATAL("Checked function entry must have no offset");
+    }
+  } else {
+    entry = osr_entry();
+    if (!compiler->CanFallThroughTo(entry)) {
+      __ jmp(compiler->GetJumpLabel(entry));
+    }
   }
 }
 
diff --git a/runtime/vm/compiler/backend/il_x64.cc b/runtime/vm/compiler/backend/il_x64.cc
index ce0b196..e8bf0f8 100644
--- a/runtime/vm/compiler/backend/il_x64.cc
+++ b/runtime/vm/compiler/backend/il_x64.cc
@@ -6230,10 +6230,15 @@
 
 void GraphEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   BlockEntryInstr* entry = normal_entry();
-  if (entry == nullptr) entry = osr_entry();
-
-  if (!compiler->CanFallThroughTo(entry)) {
-    __ jmp(compiler->GetJumpLabel(entry));
+  if (entry != nullptr) {
+    if (!compiler->CanFallThroughTo(entry)) {
+      FATAL("Checked function entry must have no offset");
+    }
+  } else {
+    entry = osr_entry();
+    if (!compiler->CanFallThroughTo(entry)) {
+      __ jmp(compiler->GetJumpLabel(entry));
+    }
   }
 }
 
diff --git a/runtime/vm/compiler/backend/inliner.cc b/runtime/vm/compiler/backend/inliner.cc
index 634729f8..d3b03a9 100644
--- a/runtime/vm/compiler/backend/inliner.cc
+++ b/runtime/vm/compiler/backend/inliner.cc
@@ -101,7 +101,6 @@
 DECLARE_FLAG(int, max_deoptimization_counter_threshold);
 DECLARE_FLAG(bool, print_flow_graph);
 DECLARE_FLAG(bool, print_flow_graph_optimized);
-DECLARE_FLAG(bool, verify_compiler);
 
 // Quick access to the current zone.
 #define Z (zone())
@@ -738,9 +737,6 @@
       }
     }
   }
-
-  // Check that inlining maintains use lists.
-  DEBUG_ASSERT(!FLAG_verify_compiler || caller_graph->VerifyUseLists());
 }
 
 class CallSiteInliner : public ValueObject {
@@ -1062,11 +1058,9 @@
             entry_kind == Code::EntryKind::kUnchecked);
         {
           callee_graph = builder.BuildGraph();
-
 #if defined(DEBUG)
-          FlowGraphChecker(callee_graph).Check();
+          FlowGraphChecker(callee_graph).Check("Builder (callee)");
 #endif
-
           CalleeGraphValidator::Validate(callee_graph);
         }
 #if defined(DART_PRECOMPILER) && !defined(TARGET_ARCH_DBC) &&                  \
@@ -1149,7 +1143,9 @@
           // Compute SSA on the callee graph, catching bailouts.
           callee_graph->ComputeSSA(caller_graph_->max_virtual_register_number(),
                                    param_stubs);
-          DEBUG_ASSERT(callee_graph->VerifyUseLists());
+#if defined(DEBUG)
+          FlowGraphChecker(callee_graph).Check("SSA (callee)");
+#endif
         }
 
         if (FLAG_support_il_printer && trace_inlining() &&
@@ -4148,12 +4144,16 @@
             FunctionEntryInstr(graph_entry, flow_graph->allocate_block_id(),
                                call->GetBlock()->try_index(), DeoptId::kNone);
         (*entry)->InheritDeoptTarget(Z, call);
-        *last = new (Z) ConstantInstr(type);
+        ConstantInstr* ctype = flow_graph->GetConstant(type);
+        // Create a synthetic (re)definition for return to flag insertion.
+        // TODO(ajcbik): avoid this mechanism altogether
+        RedefinitionInstr* redef =
+            new (Z) RedefinitionInstr(new (Z) Value(ctype));
         flow_graph->AppendTo(
-            *entry, *last,
+            *entry, redef,
             call->deopt_id() != DeoptId::kNone ? call->env() : NULL,
             FlowGraph::kValue);
-        *result = (*last)->AsDefinition();
+        *last = *result = redef;
         return true;
       }
       return false;
diff --git a/runtime/vm/compiler/backend/locations.h b/runtime/vm/compiler/backend/locations.h
index d127790..9147a6a 100644
--- a/runtime/vm/compiler/backend/locations.h
+++ b/runtime/vm/compiler/backend/locations.h
@@ -407,6 +407,9 @@
 
   TemplateLocation Copy() const;
 
+  static TemplateLocation read(uword value) { return TemplateLocation(value); }
+  uword write() const { return value_; }
+
  private:
   explicit TemplateLocation(uword value) : value_(value) {}
 
diff --git a/runtime/vm/compiler/backend/range_analysis.cc b/runtime/vm/compiler/backend/range_analysis.cc
index c2bd37b..d619f96 100644
--- a/runtime/vm/compiler/backend/range_analysis.cc
+++ b/runtime/vm/compiler/backend/range_analysis.cc
@@ -1679,7 +1679,6 @@
                 replacement->ToCString());
     }
     defn->ReplaceWith(replacement, NULL);
-    ASSERT(flow_graph_->VerifyUseLists());
   }
 }
 
diff --git a/runtime/vm/compiler/backend/redundancy_elimination.cc b/runtime/vm/compiler/backend/redundancy_elimination.cc
index f0fa894..27245b2 100644
--- a/runtime/vm/compiler/backend/redundancy_elimination.cc
+++ b/runtime/vm/compiler/backend/redundancy_elimination.cc
@@ -3549,6 +3549,7 @@
             new (flow_graph_->zone()) ConstantInstr(orig->value());
         copy->set_ssa_temp_index(flow_graph_->alloc_ssa_temp_index());
         old->ReplaceUsesWith(copy);
+        copy->set_previous(old->previous());  // partial link
         (*idefs)[j] = copy;
       }
     }
diff --git a/runtime/vm/compiler/backend/type_propagator.cc b/runtime/vm/compiler/backend/type_propagator.cc
index 0352767..413f0d7 100644
--- a/runtime/vm/compiler/backend/type_propagator.cc
+++ b/runtime/vm/compiler/backend/type_propagator.cc
@@ -987,17 +987,11 @@
     return CompileType::Dynamic();
   }
 
-  if (function.HasBytecode() &&
-      graph_entry->parsed_function().node_sequence() == nullptr) {
-    // TODO(alexmarkov): Consider adding node_sequence() and scope.
-    return CompileType::Dynamic();
-  }
-
   // Parameter is the receiver.
   if ((index() == 0) &&
       (function.IsDynamicFunction() || function.IsGenerativeConstructor())) {
     const AbstractType& type =
-        graph_entry->parsed_function().ParameterVariable(index())->type();
+        graph_entry->parsed_function().RawParameterVariable(0)->type();
     if (type.IsObjectType() || type.IsNullType()) {
       // Receiver can be null.
       return CompileType::FromAbstractType(type, CompileType::kNullable);
@@ -1036,6 +1030,12 @@
     return CompileType(CompileType::kNonNullable, cid, &type);
   }
 
+  if (function.HasBytecode() &&
+      graph_entry->parsed_function().node_sequence() == nullptr) {
+    // TODO(alexmarkov): Consider adding node_sequence() and scope.
+    return CompileType::Dynamic();
+  }
+
   const bool is_unchecked_entry_param =
       graph_entry->unchecked_entry() == block_;
 
diff --git a/runtime/vm/compiler/compiler_pass.cc b/runtime/vm/compiler/compiler_pass.cc
index 84f2cad..340b149 100644
--- a/runtime/vm/compiler/compiler_pass.cc
+++ b/runtime/vm/compiler/compiler_pass.cc
@@ -178,7 +178,7 @@
       repeat = DoBody(state);
       thread->CheckForSafepoint();
 #if defined(DEBUG)
-      FlowGraphChecker(state->flow_graph).Check();
+      FlowGraphChecker(state->flow_graph).Check(name());
 #endif
     }
     PrintGraph(state, kTraceAfter, round);
@@ -448,8 +448,8 @@
     Definition* last_allocated = nullptr;
     for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) {
       Instruction* current = it.Current();
-      if (StoreInstanceFieldInstr* instr = current->AsStoreInstanceField()) {
-        if (!current->CanTriggerGC()) {
+      if (!current->CanTriggerGC()) {
+        if (StoreInstanceFieldInstr* instr = current->AsStoreInstanceField()) {
           if (instr->instance()->definition() == last_allocated) {
             instr->set_emit_store_barrier(kNoStoreBarrier);
           }
@@ -457,10 +457,11 @@
         }
       }
 
-      AllocationInstr* alloc = current->AsAllocation();
-      if (alloc != nullptr && alloc->WillAllocateNewOrRemembered()) {
-        last_allocated = alloc;
-        continue;
+      if (AllocationInstr* alloc = current->AsAllocation()) {
+        if (alloc->WillAllocateNewOrRemembered()) {
+          last_allocated = alloc;
+          continue;
+        }
       }
 
       if (current->CanTriggerGC()) {
diff --git a/runtime/vm/compiler/compiler_sources.gni b/runtime/vm/compiler/compiler_sources.gni
index f388295..632e5b4 100644
--- a/runtime/vm/compiler/compiler_sources.gni
+++ b/runtime/vm/compiler/compiler_sources.gni
@@ -146,6 +146,17 @@
   "stub_code_compiler_x64.cc",
 ]
 
+# The most common way to include assembly files in C projects is to have
+# separate assembly files per architecture and operating system (for example
+# boringssl).
+#
+# Not that this diverges from our convention to build every file on every OS
+# but have ifdef guards which make the files empty on some configurations.
+if (is_linux || is_mac) {
+  # MASM on Windows does not support c preproccesor style flags.
+  compiler_sources += [ "ffi_dbc_trampoline_x64_linux_mac.S" ]
+}
+
 compiler_sources_tests = [
   "assembler/assembler_arm64_test.cc",
   "assembler/assembler_arm_test.cc",
diff --git a/runtime/vm/compiler/ffi.cc b/runtime/vm/compiler/ffi.cc
index f01e742..823e8ef 100644
--- a/runtime/vm/compiler/ffi.cc
+++ b/runtime/vm/compiler/ffi.cc
@@ -7,6 +7,7 @@
 #include <algorithm>
 
 #include "platform/globals.h"
+#include "vm/compiler/backend/locations.h"
 #include "vm/compiler/runtime_api.h"
 
 namespace dart {
@@ -88,8 +89,6 @@
   }
 }
 
-#if !defined(TARGET_ARCH_DBC)
-
 bool NativeTypeIsVoid(const AbstractType& result_type) {
   return result_type.type_class_id() == kFfiVoidCid;
 }
@@ -117,7 +116,8 @@
 
 // Converts a Ffi [signature] to a list of Representations.
 // Note that this ignores first argument (receiver) which is dynamic.
-ZoneGrowableArray<Representation>* ArgumentRepresentations(
+template <class CallingConventions>
+ZoneGrowableArray<Representation>* ArgumentRepresentationsBase(
     const Function& signature) {
   intptr_t num_arguments = signature.num_fixed_parameters() - 1;
   auto result = new ZoneGrowableArray<Representation>(num_arguments);
@@ -125,6 +125,8 @@
     AbstractType& arg_type =
         AbstractType::Handle(signature.ParameterTypeAt(i + 1));
     Representation rep = TypeRepresentation(arg_type);
+    // In non simulator mode host::CallingConventions == CallingConventions.
+    // In simulator mode convert arguments to host representation.
     if (rep == kUnboxedFloat && CallingConventions::kAbiSoftFP) {
       rep = kUnboxedInt32;
     } else if (rep == kUnboxedDouble && CallingConventions::kAbiSoftFP) {
@@ -135,9 +137,51 @@
   return result;
 }
 
+template <class CallingConventions>
+Representation ResultRepresentationBase(const Function& signature) {
+  AbstractType& arg_type = AbstractType::Handle(signature.result_type());
+  Representation rep = TypeRepresentation(arg_type);
+  if (rep == kUnboxedFloat && CallingConventions::kAbiSoftFP) {
+    rep = kUnboxedInt32;
+  } else if (rep == kUnboxedDouble && CallingConventions::kAbiSoftFP) {
+    rep = kUnboxedInt64;
+  }
+  return rep;
+}
+
+#if !defined(TARGET_ARCH_DBC)
+
+ZoneGrowableArray<Representation>* ArgumentRepresentations(
+    const Function& signature) {
+  return ArgumentRepresentationsBase<CallingConventions>(signature);
+}
+
+Representation ResultRepresentation(const Function& signature) {
+  return ResultRepresentationBase<CallingConventions>(signature);
+}
+
+#endif  // !defined(TARGET_ARCH_DBC)
+
+#if defined(USING_SIMULATOR)
+
+ZoneGrowableArray<Representation>* ArgumentHostRepresentations(
+    const Function& signature) {
+  return ArgumentRepresentationsBase<host::CallingConventions>(signature);
+}
+
+Representation ResultHostRepresentation(const Function& signature) {
+  return ResultRepresentationBase<host::CallingConventions>(signature);
+}
+
+#endif  // defined(USING_SIMULATOR)
+
 // Represents the state of a stack frame going into a call, between allocations
 // of argument locations. Acts like a register allocator but for arguments in
 // the native ABI.
+template <class CallingConventions,
+          class Location,
+          class Register,
+          class FpuRegister>
 class ArgumentFrameState : public ValueObject {
  public:
   Location AllocateArgument(Representation rep) {
@@ -173,7 +217,8 @@
 
  private:
   Location AllocateStackSlot() {
-    return Location::StackSlot(stack_height_in_slots++, SPREG);
+    return Location::StackSlot(stack_height_in_slots++,
+                               CallingConventions::kStackPointerRegister);
   }
 
   // Allocates a pair of stack slots where the first stack slot is aligned to an
@@ -186,7 +231,8 @@
 
     Location result;
     if (rep == kUnboxedDouble) {
-      result = Location::DoubleStackSlot(stack_height_in_slots, SPREG);
+      result = Location::DoubleStackSlot(
+          stack_height_in_slots, CallingConventions::kStackPointerRegister);
       stack_height_in_slots += 2;
     } else {
       const Location low = AllocateStackSlot();
@@ -243,13 +289,18 @@
 
 // Takes a list of argument representations, and converts it to a list of
 // argument locations based on calling convention.
-ZoneGrowableArray<Location>* ArgumentLocations(
+template <class CallingConventions,
+          class Location,
+          class Register,
+          class FpuRegister>
+ZoneGrowableArray<Location>* ArgumentLocationsBase(
     const ZoneGrowableArray<Representation>& arg_reps) {
   intptr_t num_arguments = arg_reps.length();
   auto result = new ZoneGrowableArray<Location>(num_arguments);
 
   // Loop through all arguments and assign a register or a stack location.
-  ArgumentFrameState frame_state;
+  ArgumentFrameState<CallingConventions, Location, Register, FpuRegister>
+      frame_state;
   for (intptr_t i = 0; i < num_arguments; i++) {
     Representation rep = arg_reps[i];
     result->Add(frame_state.AllocateArgument(rep));
@@ -257,18 +308,35 @@
   return result;
 }
 
-Representation ResultRepresentation(const Function& signature) {
-  AbstractType& arg_type = AbstractType::Handle(signature.result_type());
-  Representation rep = TypeRepresentation(arg_type);
-  if (rep == kUnboxedFloat && CallingConventions::kAbiSoftFP) {
-    rep = kUnboxedInt32;
-  } else if (rep == kUnboxedDouble && CallingConventions::kAbiSoftFP) {
-    rep = kUnboxedInt64;
+ZoneGrowableArray<Location>* ArgumentLocations(
+    const ZoneGrowableArray<Representation>& arg_reps) {
+#if !defined(TARGET_ARCH_DBC)
+  return ArgumentLocationsBase<dart::CallingConventions, Location,
+                               dart::Register, dart::FpuRegister>(arg_reps);
+#else
+  intptr_t next_free_register = compiler::ffi::kFirstArgumentRegister;
+  intptr_t num_arguments = arg_reps.length();
+  auto result = new ZoneGrowableArray<Location>(num_arguments);
+  for (intptr_t i = 0; i < num_arguments; i++) {
+    // TODO(dacoharkes): In 32 bits, use pair locations.
+    result->Add(Location::RegisterLocation(next_free_register));
+    next_free_register++;
   }
-  return rep;
+  return result;
+#endif
 }
 
+#if defined(TARGET_ARCH_DBC)
+ZoneGrowableArray<HostLocation>* HostArgumentLocations(
+    const ZoneGrowableArray<Representation>& arg_reps) {
+  return ArgumentLocationsBase<dart::host::CallingConventions, HostLocation,
+                               dart::host::Register, dart::host::FpuRegister>(
+      arg_reps);
+}
+#endif
+
 Location ResultLocation(Representation result_rep) {
+#ifndef TARGET_ARCH_DBC
   switch (result_rep) {
     case kUnboxedFloat:
     case kUnboxedDouble:
@@ -293,10 +361,15 @@
     default:
       UNREACHABLE();
   }
+#else
+  // TODO(dacoharkes): Support 64 bit result values on 32 bit DBC.
+  return Location::RegisterLocation(0);
+#endif
 }
 
 // Accounts for alignment, where some stack slots are used as padding.
-intptr_t NumStackSlots(const ZoneGrowableArray<Location>& locations) {
+template <class Location>
+intptr_t TemplateNumStackSlots(const ZoneGrowableArray<Location>& locations) {
   intptr_t num_arguments = locations.length();
   intptr_t max_height_in_slots = 0;
   for (intptr_t i = 0; i < num_arguments; i++) {
@@ -316,7 +389,88 @@
   return max_height_in_slots;
 }
 
-#endif  // !defined(TARGET_ARCH_DBC)
+intptr_t NumStackSlots(const ZoneGrowableArray<Location>& locations) {
+  return TemplateNumStackSlots(locations);
+}
+
+#if defined(TARGET_ARCH_DBC)
+
+static RawTypedData* typed_data_new_uintptr(intptr_t length) {
+#if defined(ARCH_IS_32_BIT)
+  return TypedData::New(kTypedDataUint32ArrayCid, length);
+#else
+  return TypedData::New(kTypedDataUint64ArrayCid, length);
+#endif
+}
+
+static void typed_data_set_uintptr(const TypedData& typed_data,
+                                   intptr_t index,
+                                   uintptr_t value) {
+#if defined(ARCH_IS_32_BIT)
+  typed_data.SetUint32(target::kWordSize * index, value);
+#else
+  typed_data.SetUint64(target::kWordSize * index, value);
+#endif
+}
+
+static uintptr_t typed_data_get_uintptr(const TypedData& typed_data,
+                                        intptr_t index) {
+#if defined(ARCH_IS_32_BIT)
+  return typed_data.GetUint32(target::kWordSize * index);
+#else
+  return typed_data.GetUint64(target::kWordSize * index);
+#endif
+}
+
+// Number of host stack slots used in 'locations'.
+static intptr_t HostNumStackSlots(
+    const ZoneGrowableArray<HostLocation>& locations) {
+  return TemplateNumStackSlots(locations);
+}
+
+RawTypedData* FfiSignatureDescriptor::New(
+    const ZoneGrowableArray<HostLocation>& arg_host_locations,
+    const Representation result_representation) {
+  const uintptr_t num_arguments = arg_host_locations.length();
+  const uintptr_t num_stack_slots = HostNumStackSlots(arg_host_locations);
+
+  const TypedData& result = TypedData::Handle(
+      typed_data_new_uintptr(kOffsetArgumentLocations + num_arguments));
+
+  typed_data_set_uintptr(result, kOffsetNumArguments, num_arguments);
+  typed_data_set_uintptr(result, kOffsetNumStackSlots, num_stack_slots);
+  typed_data_set_uintptr(result, kOffsetResultRepresentation,
+                         result_representation);
+
+  for (uintptr_t i = 0; i < num_arguments; i++) {
+    typed_data_set_uintptr(result, kOffsetArgumentLocations + i,
+                           arg_host_locations.At(i).write());
+  }
+
+  return result.raw();
+}
+
+intptr_t FfiSignatureDescriptor::length() const {
+  return typed_data_get_uintptr(typed_data_, kOffsetNumArguments);
+}
+
+intptr_t FfiSignatureDescriptor::num_stack_slots() const {
+  return typed_data_get_uintptr(typed_data_, kOffsetNumStackSlots);
+}
+
+HostLocation FfiSignatureDescriptor::LocationAt(intptr_t index) const {
+  return HostLocation::read(
+      typed_data_get_uintptr(typed_data_, kOffsetArgumentLocations + index));
+}
+
+Representation FfiSignatureDescriptor::ResultRepresentation() const {
+  uintptr_t result_int =
+      typed_data_get_uintptr(typed_data_, kOffsetResultRepresentation);
+  ASSERT(result_int < kNumRepresentations);
+  return static_cast<Representation>(result_int);
+}
+
+#endif  // defined(TARGET_ARCH_DBC)
 
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
 
diff --git a/runtime/vm/compiler/ffi.h b/runtime/vm/compiler/ffi.h
index 63700b5..cd8e96f 100644
--- a/runtime/vm/compiler/ffi.h
+++ b/runtime/vm/compiler/ffi.h
@@ -38,16 +38,31 @@
 // Whether a type is 'ffi.Void'.
 bool NativeTypeIsVoid(const AbstractType& result_type);
 
-// Unboxed representation of the result of a C signature function.
-Representation ResultRepresentation(const Function& signature);
-
 // Location for the result of a C signature function.
 Location ResultLocation(Representation result_rep);
 
+#if !defined(TARGET_ARCH_DBC)
+
 // Unboxed representations of the arguments to a C signature function.
 ZoneGrowableArray<Representation>* ArgumentRepresentations(
     const Function& signature);
 
+// Unboxed representation of the result of a C signature function.
+Representation ResultRepresentation(const Function& signature);
+
+#endif  // !defined(TARGET_ARCH_DBC)
+
+#if defined(USING_SIMULATOR)
+
+// Unboxed host representations of the arguments to a C signature function.
+ZoneGrowableArray<Representation>* ArgumentHostRepresentations(
+    const Function& signature);
+
+// Unboxed host representation of the result of a C signature function.
+Representation ResultHostRepresentation(const Function& signature);
+
+#endif  // defined(USING_SIMULATOR)
+
 // Location for the arguments of a C signature function.
 ZoneGrowableArray<Location>* ArgumentLocations(
     const ZoneGrowableArray<Representation>& arg_reps);
@@ -55,6 +70,44 @@
 // Number of stack slots used in 'locations'.
 intptr_t NumStackSlots(const ZoneGrowableArray<Location>& locations);
 
+#if defined(TARGET_ARCH_DBC)
+
+// The first argument to a ffi trampoline is the function address, the arguments
+// to the call follow the function address.
+const intptr_t kFunctionAddressRegister = 0;
+const intptr_t kFirstArgumentRegister = 1;
+
+// Location in host for the arguments of a C signature function.
+ZoneGrowableArray<HostLocation>* HostArgumentLocations(
+    const ZoneGrowableArray<Representation>& arg_reps);
+
+// A signature descriptor consists of the signature length, argument locations,
+// and result representation.
+class FfiSignatureDescriptor : public ValueObject {
+ public:
+  explicit FfiSignatureDescriptor(const TypedData& typed_data)
+      : typed_data_(typed_data) {}
+
+  static RawTypedData* New(
+      const ZoneGrowableArray<HostLocation>& arg_host_locations,
+      const Representation result_representation);
+
+  intptr_t length() const;
+  intptr_t num_stack_slots() const;
+  HostLocation LocationAt(intptr_t index) const;
+  Representation ResultRepresentation() const;
+
+ private:
+  const TypedData& typed_data_;
+
+  static const intptr_t kOffsetNumArguments = 0;
+  static const intptr_t kOffsetNumStackSlots = 1;
+  static const intptr_t kOffsetResultRepresentation = 2;
+  static const intptr_t kOffsetArgumentLocations = 3;
+};
+
+#endif  // defined(TARGET_ARCH_DBC)
+
 }  // namespace ffi
 
 }  // namespace compiler
diff --git a/runtime/vm/compiler/ffi_dbc_trampoline.h b/runtime/vm/compiler/ffi_dbc_trampoline.h
new file mode 100644
index 0000000..656d1e1
--- /dev/null
+++ b/runtime/vm/compiler/ffi_dbc_trampoline.h
@@ -0,0 +1,28 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#ifndef RUNTIME_VM_COMPILER_FFI_DBC_TRAMPOLINE_H_
+#define RUNTIME_VM_COMPILER_FFI_DBC_TRAMPOLINE_H_
+
+#include "vm/globals.h"
+
+namespace dart {
+
+#if defined(HOST_ARCH_X64) && !defined(HOST_OS_WINDOWS)
+
+// Generic Trampoline for DBC dart:ffi calls. Argument needs to be layed out as
+// a FfiMarshalledArguments.
+extern "C" void FfiTrampolineCall(uint64_t* ffi_marshalled_args);
+
+#else
+
+void FfiTrampolineCall(uint64_t* ffi_marshalled_args) {
+  UNREACHABLE();
+}
+
+#endif  //  defined(HOST_ARCH_X64) && !defined(HOST_OS_WINDOWS)
+
+}  // namespace dart
+
+#endif  // RUNTIME_VM_COMPILER_FFI_DBC_TRAMPOLINE_H_
diff --git a/runtime/vm/compiler/ffi_dbc_trampoline_x64_linux_mac.S b/runtime/vm/compiler/ffi_dbc_trampoline_x64_linux_mac.S
new file mode 100644
index 0000000..efec2db
--- /dev/null
+++ b/runtime/vm/compiler/ffi_dbc_trampoline_x64_linux_mac.S
@@ -0,0 +1,63 @@
+#if defined(_M_X64) || defined(__x86_64__) /* HOST_ARCH_X64 */
+
+.intel_syntax noprefix
+.text
+
+#if defined(__linux__) || defined(__FreeBSD__) /* HOST_OS_LINUX */
+.globl FfiTrampolineCall
+.type FfiTrampolineCall, @function
+FfiTrampolineCall:
+#else /* HOST_OS_MACOS */
+.globl _FfiTrampolineCall
+_FfiTrampolineCall:
+#endif
+
+push  rbx
+mov   rbx,  rdi        /* Save argument in scratch register. */
+
+/* Copy stack arguments. */
+mov   rax,  [rbx+0x78] /* Load number of stack arguments. */
+cmp   rax,  0x0        /* Check if number of stack arguments is 0. */
+jz    2f               /* Skip loop if no stack arguments. */
+add   rbx,  0x78       /* Offset RBX to point to stack arguments */
+1:                     /* Copy stack arguments loop. */
+push  [rbx+0x8*rax]    /* Push stack argument. */
+sub   rax,  0x1        /* Decrement stack argument iterator. */
+cmp   rax,  0x0        /* Compare iterator with 0 */
+jnz   1b               /* Loop while iterator is not 0 */
+sub   rbx,  0x78       /* Restore RBX to original value. */
+2:                     /* End stack arguments loop. */
+
+/* Copy registers and fpu registers. */
+mov   rdi,  [rbx+0x8]  /* kArg1Reg */
+mov   rsi,  [rbx+0x10] /* kArg2Reg */
+mov   rdx,  [rbx+0x18] /* kArg3Reg */
+mov   rcx,  [rbx+0x20] /* kArg4Reg */
+mov   r8,   [rbx+0x28] /* kArg5Reg */
+mov   r9,   [rbx+0x30] /* kArg6Reg */
+movsd xmm0, [rbx+0x38]
+movsd xmm1, [rbx+0x40]
+movsd xmm2, [rbx+0x48]
+movsd xmm3, [rbx+0x50]
+movsd xmm4, [rbx+0x58]
+movsd xmm5, [rbx+0x60]
+movsd xmm6, [rbx+0x68]
+movsd xmm7, [rbx+0x70]
+
+/* Do call. */
+mov   rax,  [rbx] /* function address */
+call  rax         /* Call the function. */
+
+/* Copy results back. */
+mov   [rbx],   rax  /* Move integer result in kOffsetIntResult */
+movsd [rbx+8], xmm0 /* Move double result in kOffsetDoubleResult */
+
+/* Clean up stack arguments. */
+mov   rax,  [rbx+0x78] /* Load number of stack arguments. */
+imul  rax,  0x8        /* Multiply by stack argument size. */
+add   rsp,  rax        /* Clean up the stack. */
+
+pop   rbx
+ret
+
+#endif /* HOST_ARCH_X64 */
diff --git a/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.cc b/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.cc
index 35ee872..61f37dfe 100644
--- a/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.cc
+++ b/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.cc
@@ -26,7 +26,6 @@
 
 namespace kernel {
 
-// 8-bit unsigned operand at bits 8-15.
 BytecodeFlowGraphBuilder::Operand BytecodeFlowGraphBuilder::DecodeOperandA() {
   if (is_generating_interpreter()) {
     UNIMPLEMENTED();  // TODO(alexmarkov): interpreter
@@ -36,7 +35,6 @@
   }
 }
 
-// 8-bit unsigned operand at bits 16-23.
 BytecodeFlowGraphBuilder::Operand BytecodeFlowGraphBuilder::DecodeOperandB() {
   if (is_generating_interpreter()) {
     UNIMPLEMENTED();  // TODO(alexmarkov): interpreter
@@ -46,7 +44,6 @@
   }
 }
 
-// 8-bit unsigned operand at bits 24-31.
 BytecodeFlowGraphBuilder::Operand BytecodeFlowGraphBuilder::DecodeOperandC() {
   if (is_generating_interpreter()) {
     UNIMPLEMENTED();  // TODO(alexmarkov): interpreter
@@ -56,7 +53,6 @@
   }
 }
 
-// 16-bit unsigned operand at bits 16-31.
 BytecodeFlowGraphBuilder::Operand BytecodeFlowGraphBuilder::DecodeOperandD() {
   if (is_generating_interpreter()) {
     UNIMPLEMENTED();  // TODO(alexmarkov): interpreter
@@ -66,7 +62,24 @@
   }
 }
 
-// 16-bit signed operand at bits 16-31.
+BytecodeFlowGraphBuilder::Operand BytecodeFlowGraphBuilder::DecodeOperandE() {
+  if (is_generating_interpreter()) {
+    UNIMPLEMENTED();  // TODO(alexmarkov): interpreter
+  } else {
+    intptr_t value = KernelBytecode::DecodeE(bytecode_instr_);
+    return Operand(value);
+  }
+}
+
+BytecodeFlowGraphBuilder::Operand BytecodeFlowGraphBuilder::DecodeOperandF() {
+  if (is_generating_interpreter()) {
+    UNIMPLEMENTED();  // TODO(alexmarkov): interpreter
+  } else {
+    intptr_t value = KernelBytecode::DecodeF(bytecode_instr_);
+    return Operand(value);
+  }
+}
+
 BytecodeFlowGraphBuilder::Operand BytecodeFlowGraphBuilder::DecodeOperandX() {
   if (is_generating_interpreter()) {
     UNIMPLEMENTED();  // TODO(alexmarkov): interpreter
@@ -76,7 +89,15 @@
   }
 }
 
-// 24-bit signed operand at bits 8-31.
+BytecodeFlowGraphBuilder::Operand BytecodeFlowGraphBuilder::DecodeOperandY() {
+  if (is_generating_interpreter()) {
+    UNIMPLEMENTED();  // TODO(alexmarkov): interpreter
+  } else {
+    intptr_t value = KernelBytecode::DecodeY(bytecode_instr_);
+    return Operand(value);
+  }
+}
+
 BytecodeFlowGraphBuilder::Operand BytecodeFlowGraphBuilder::DecodeOperandT() {
   if (is_generating_interpreter()) {
     UNIMPLEMENTED();  // TODO(alexmarkov): interpreter
@@ -86,22 +107,6 @@
   }
 }
 
-KBCInstr BytecodeFlowGraphBuilder::InstructionAt(
-    intptr_t pc,
-    KernelBytecode::Opcode expect_opcode) {
-  ASSERT(!is_generating_interpreter());
-  ASSERT((0 <= pc) && (pc < bytecode_length_));
-
-  const KBCInstr instr = raw_bytecode_[pc];
-  if (KernelBytecode::DecodeOpcode(instr) != expect_opcode) {
-    FATAL3("Expected bytecode instruction %s, but found %s at %" Pd "",
-           KernelBytecode::NameOf(KernelBytecode::Encode(expect_opcode)),
-           KernelBytecode::NameOf(instr), pc);
-  }
-
-  return instr;
-}
-
 BytecodeFlowGraphBuilder::Constant BytecodeFlowGraphBuilder::ConstantAt(
     Operand entry_index,
     intptr_t add_index) {
@@ -369,17 +374,50 @@
 
 void BytecodeFlowGraphBuilder::BuildInstruction(KernelBytecode::Opcode opcode) {
   switch (opcode) {
-#define BUILD_BYTECODE_CASE(name, encoding, op1, op2, op3)                     \
+#define WIDE_CASE(name) case KernelBytecode::k##name##_Wide:
+#define WIDE_CASE_0(name)
+#define WIDE_CASE_A(name)
+#define WIDE_CASE_D(name) WIDE_CASE(name)
+#define WIDE_CASE_X(name) WIDE_CASE(name)
+#define WIDE_CASE_T(name) WIDE_CASE(name)
+#define WIDE_CASE_A_E(name) WIDE_CASE(name)
+#define WIDE_CASE_A_Y(name) WIDE_CASE(name)
+#define WIDE_CASE_D_F(name) WIDE_CASE(name)
+#define WIDE_CASE_A_B_C(name)
+
+#define BUILD_BYTECODE_CASE(name, encoding, kind, op1, op2, op3)               \
+  BUILD_BYTECODE_CASE_##kind(name, encoding)
+
+#define BUILD_BYTECODE_CASE_OLD(name, encoding)
+#define BUILD_BYTECODE_CASE_WIDE(name, encoding)
+#define BUILD_BYTECODE_CASE_RESV(name, encoding)
+#define BUILD_BYTECODE_CASE_ORDN(name, encoding)                               \
   case KernelBytecode::k##name:                                                \
-    Build##name();                                                             \
+  case KernelBytecode::k##name##_Old:                                          \
+    WIDE_CASE_##encoding(name) Build##name();                                  \
     break;
 
     PUBLIC_KERNEL_BYTECODES_LIST(BUILD_BYTECODE_CASE)
 
+#undef WIDE_CASE
+#undef WIDE_CASE_0
+#undef WIDE_CASE_A
+#undef WIDE_CASE_D
+#undef WIDE_CASE_X
+#undef WIDE_CASE_T
+#undef WIDE_CASE_A_E
+#undef WIDE_CASE_A_Y
+#undef WIDE_CASE_D_F
+#undef WIDE_CASE_A_B_C
 #undef BUILD_BYTECODE_CASE
+#undef BUILD_BYTECODE_CASE_OLD
+#undef BUILD_BYTECODE_CASE_WIDE
+#undef BUILD_BYTECODE_CASE_RESV
+#undef BUILD_BYTECODE_CASE_ORDN
+
     default:
       FATAL1("Unsupported bytecode instruction %s\n",
-             KernelBytecode::NameOf(bytecode_instr_));
+             KernelBytecode::NameOf(opcode));
   }
 }
 
@@ -396,7 +434,7 @@
   const intptr_t num_fixed_params = DecodeOperandA().value();
   ASSERT(num_fixed_params == function().num_fixed_parameters());
 
-  AllocateLocalVariables(DecodeOperandD());
+  AllocateLocalVariables(DecodeOperandE());
   AllocateFixedParameters();
 
   Fragment check_args;
@@ -444,8 +482,12 @@
   ASSERT((num_opt_pos_params == 0) || (num_opt_named_params == 0));
   const intptr_t num_load_const = num_opt_pos_params + 2 * num_opt_named_params;
 
-  const KBCInstr frame_instr =
-      InstructionAt(pc_ + 1 + num_load_const, KernelBytecode::kFrame);
+  const KBCInstr* instr = KernelBytecode::Next(bytecode_instr_);
+  const KBCInstr* frame_instr = instr;
+  for (intptr_t i = 0; i < num_load_const; ++i) {
+    frame_instr = KernelBytecode::Next(frame_instr);
+  }
+  ASSERT(KernelBytecode::IsFrameOpcode(frame_instr));
   const intptr_t num_extra_locals = KernelBytecode::DecodeD(frame_instr);
   const intptr_t num_params =
       num_fixed_params + num_opt_pos_params + num_opt_named_params;
@@ -467,11 +509,12 @@
   }
 
   for (intptr_t i = 0; i < num_opt_pos_params; ++i, ++param) {
-    const KBCInstr load_value_instr =
-        InstructionAt(pc_ + 1 + i, KernelBytecode::kLoadConstant);
-    const Object& default_value =
-        ConstantAt(Operand(KernelBytecode::DecodeD(load_value_instr))).value();
+    const KBCInstr* load_value_instr = instr;
+    instr = KernelBytecode::Next(instr);
+    ASSERT(KernelBytecode::IsLoadConstantOpcode(load_value_instr));
     ASSERT(KernelBytecode::DecodeA(load_value_instr) == param);
+    const Object& default_value =
+        ConstantAt(Operand(KernelBytecode::DecodeE(load_value_instr))).value();
 
     LocalVariable* param_var = AllocateParameter(param, VariableIndex(-param));
     raw_parameters->Add(param_var);
@@ -487,16 +530,17 @@
     temp_var = scratch_var_;
 
     for (intptr_t i = 0; i < num_opt_named_params; ++i, ++param) {
-      const KBCInstr load_name_instr =
-          InstructionAt(pc_ + 1 + i * 2, KernelBytecode::kLoadConstant);
-      const KBCInstr load_value_instr =
-          InstructionAt(pc_ + 1 + i * 2 + 1, KernelBytecode::kLoadConstant);
+      const KBCInstr* load_name_instr = instr;
+      const KBCInstr* load_value_instr = KernelBytecode::Next(load_name_instr);
+      instr = KernelBytecode::Next(load_value_instr);
+      ASSERT(KernelBytecode::IsLoadConstantOpcode(load_name_instr));
+      ASSERT(KernelBytecode::IsLoadConstantOpcode(load_value_instr));
       const String& param_name = String::Cast(
-          ConstantAt(Operand(KernelBytecode::DecodeD(load_name_instr)))
+          ConstantAt(Operand(KernelBytecode::DecodeE(load_name_instr)))
               .value());
       ASSERT(param_name.IsSymbol());
       const Object& default_value =
-          ConstantAt(Operand(KernelBytecode::DecodeD(load_value_instr)))
+          ConstantAt(Operand(KernelBytecode::DecodeE(load_value_instr)))
               .value();
 
       intptr_t param_index = num_fixed_params;
@@ -521,6 +565,8 @@
     }
   }
 
+  ASSERT(instr == frame_instr);
+
   parsed_function()->set_default_parameter_values(default_values);
   parsed_function()->SetRawParameters(raw_parameters);
 
@@ -556,7 +602,7 @@
       PrologueInfo(prologue_entry->block_id(), prologue_exit->block_id() - 1);
 
   // Skip LoadConstant and Frame instructions.
-  pc_ += num_load_const + 1;
+  next_pc_ = pc_ + (KernelBytecode::Next(instr) - bytecode_instr_);
 
   ASSERT(IsStackEmpty());
 }
@@ -585,7 +631,7 @@
   }
 
   const intptr_t expected_num_type_args = DecodeOperandA().value();
-  LocalVariable* type_args_var = LocalVariableAt(DecodeOperandD().value());
+  LocalVariable* type_args_var = LocalVariableAt(DecodeOperandE().value());
   ASSERT(function().IsGeneric());
 
   if (throw_no_such_method_ == nullptr) {
@@ -710,42 +756,13 @@
   LoadLocal(local_index);
 }
 
-void BytecodeFlowGraphBuilder::BuildIndirectStaticCall() {
-  if (is_generating_interpreter()) {
-    UNIMPLEMENTED();  // TODO(alexmarkov): interpreter
-  }
-
-  const ICData& icdata = ICData::Cast(PopConstant().value());
-
-  const Function& target = Function::ZoneHandle(Z, icdata.GetTargetAt(0));
-  const ArgumentsDescriptor arg_desc(
-      Array::Cast(ConstantAt(DecodeOperandD()).value()));
-  intptr_t argc = DecodeOperandA().value();
-  ASSERT(ic_data_array_->At(icdata.deopt_id())->Original() == icdata.raw());
-
-  ArgumentArray arguments = GetArguments(argc);
-
-  // TODO(alexmarkov): pass ICData::kSuper for super calls
-  // (need to distinguish them in bytecode).
-  StaticCallInstr* call = new (Z) StaticCallInstr(
-      position_, target, arg_desc.TypeArgsLen(),
-      Array::ZoneHandle(Z, arg_desc.GetArgumentNames()), arguments,
-      *ic_data_array_, icdata.deopt_id(), ICData::kStatic);
-
-  // TODO(alexmarkov): add type info
-  // SetResultTypeForStaticCall(call, target, argument_count, result_type);
-
-  code_ <<= call;
-  B->Push(call);
-}
-
 void BytecodeFlowGraphBuilder::BuildDirectCall() {
   if (is_generating_interpreter()) {
     UNIMPLEMENTED();  // TODO(alexmarkov): interpreter
   }
 
   const Function& target = Function::Cast(ConstantAt(DecodeOperandD()).value());
-  const intptr_t argc = DecodeOperandA().value();
+  const intptr_t argc = DecodeOperandF().value();
 
   // Recognize identical() call.
   // Note: similar optimization is performed in AST flow graph builder - see
@@ -795,7 +812,7 @@
       Array::Cast(ConstantAt(DecodeOperandD(), 1).value());
   const ArgumentsDescriptor arg_desc(arg_desc_array);
 
-  const intptr_t argc = DecodeOperandA().value();
+  const intptr_t argc = DecodeOperandF().value();
   Token::Kind token_kind = MethodTokenRecognizer::RecognizeTokenKind(name);
 
   intptr_t checked_argument_count = 1;
@@ -803,13 +820,12 @@
     intptr_t argument_count = arg_desc.Count();
     ASSERT(argument_count <= 2);
     checked_argument_count = argument_count;
-  } else if (name.raw() ==
-             Library::PrivateCoreLibName(Symbols::_simpleInstanceOf()).raw()) {
+  } else if (Library::IsPrivateCoreLibName(name,
+                                           Symbols::_simpleInstanceOf())) {
     ASSERT(arg_desc.Count() == 2);
     checked_argument_count = 2;
     token_kind = Token::kIS;
-  } else if (name.raw() ==
-             Library::PrivateCoreLibName(Symbols::_instanceOf()).raw()) {
+  } else if (Library::IsPrivateCoreLibName(name, Symbols::_instanceOf())) {
     token_kind = Token::kIS;
   }
 
@@ -846,7 +862,7 @@
   const ICData& icdata = ICData::Cast(ConstantAt(DecodeOperandD()).value());
   ASSERT(ic_data_array_->At(icdata.deopt_id())->Original() == icdata.raw());
 
-  const intptr_t argc = DecodeOperandA().value();
+  const intptr_t argc = DecodeOperandF().value();
   const ArgumentsDescriptor arg_desc(
       Array::Handle(Z, icdata.arguments_descriptor()));
 
@@ -1106,7 +1122,7 @@
   }
 
   const intptr_t context_id = DecodeOperandA().value();
-  const intptr_t num_context_vars = DecodeOperandD().value();
+  const intptr_t num_context_vars = DecodeOperandE().value();
 
   auto& context_variables = CompilerState::Current().GetDummyContextVariables(
       context_id, num_context_vars);
@@ -1120,7 +1136,7 @@
 
   LoadStackSlots(1);
   const intptr_t context_id = DecodeOperandA().value();
-  const intptr_t num_context_vars = DecodeOperandD().value();
+  const intptr_t num_context_vars = DecodeOperandE().value();
 
   auto& context_variables = CompilerState::Current().GetDummyContextVariables(
       context_id, num_context_vars);
@@ -1216,7 +1232,7 @@
 
   LoadStackSlots(2);
   const intptr_t context_id = DecodeOperandA().value();
-  const intptr_t var_index = DecodeOperandD().value();
+  const intptr_t var_index = DecodeOperandE().value();
 
   auto var =
       CompilerState::Current().GetDummyCapturedVariable(context_id, var_index);
@@ -1231,7 +1247,7 @@
 
   LoadStackSlots(1);
   const intptr_t context_id = DecodeOperandA().value();
-  const intptr_t var_index = DecodeOperandD().value();
+  const intptr_t var_index = DecodeOperandE().value();
 
   auto var =
       CompilerState::Current().GetDummyCapturedVariable(context_id, var_index);
@@ -1301,7 +1317,7 @@
   }
 
   const TypeArguments& type_args =
-      TypeArguments::Cast(ConstantAt(DecodeOperandD()).value());
+      TypeArguments::Cast(ConstantAt(DecodeOperandE()).value());
 
   LoadStackSlots(2);
   code_ += B->InstantiateTypeArguments(type_args);
@@ -1375,9 +1391,8 @@
     // (if it contains jumps) and generated. The problem is that generated
     // code may expect values left on the stack from unreachable
     // (and not generated) code which immediately follows this Jump.
-    const intptr_t target_pc = pc_ + DecodeOperandT().value();
-    ASSERT(target_pc > pc_);
-    pc_ = target_pc - 1;
+    next_pc_ = pc_ + DecodeOperandT().value();
+    ASSERT(next_pc_ > pc_);
   }
 }
 
@@ -1523,7 +1538,7 @@
   }
 
   code_ += B->LoadLocal(special_var);
-  StoreLocal(DecodeOperandX());
+  StoreLocal(DecodeOperandY());
   code_ += B->Drop();
 }
 
@@ -1785,15 +1800,22 @@
   return join;
 }
 
-bool BytecodeFlowGraphBuilder::RequiresScratchVar(KBCInstr instr) {
+bool BytecodeFlowGraphBuilder::RequiresScratchVar(const KBCInstr* instr) {
   switch (KernelBytecode::DecodeOpcode(instr)) {
     case KernelBytecode::kEntryOptional:
+    case KernelBytecode::kEntryOptional_Old:
       return KernelBytecode::DecodeC(instr) > 0;
+
     case KernelBytecode::kEqualsNull:
+    case KernelBytecode::kEqualsNull_Old:
       return true;
+
     case KernelBytecode::kNativeCall:
+    case KernelBytecode::kNativeCall_Wide:
+    case KernelBytecode::kNativeCall_Old:
       return MethodRecognizer::RecognizeKind(function()) ==
              MethodRecognizer::kListFactory;
+
     default:
       return false;
   }
@@ -1803,14 +1825,13 @@
     const PcDescriptors& descriptors,
     const ExceptionHandlers& handlers,
     GraphEntryInstr* graph_entry) {
-  for (intptr_t pc = 0; pc < bytecode_length_; ++pc) {
-    const KBCInstr instr = raw_bytecode_[pc];
+  for (intptr_t pc = 0; pc < bytecode_length_;) {
+    const KBCInstr* instr = &(raw_bytecode_[pc]);
 
     if (KernelBytecode::IsJumpOpcode(instr)) {
       const intptr_t target = pc + KernelBytecode::DecodeT(instr);
       EnsureControlFlowJoin(descriptors, target);
-    } else if ((KernelBytecode::DecodeOpcode(instr) ==
-                KernelBytecode::kCheckStack) &&
+    } else if (KernelBytecode::IsCheckStackOpcode(instr) &&
                (KernelBytecode::DecodeA(instr) != 0)) {
       // (dartbug.com/36590) BlockEntryInstr::FindOsrEntryAndRelink assumes
       // that CheckStackOverflow instruction is at the beginning of a join
@@ -1823,6 +1844,8 @@
           LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource,
                         Symbols::ExprTemp(), Object::dynamic_type());
     }
+
+    pc += (KernelBytecode::Next(instr) - instr);
   }
 
   PcDescriptors::Iterator iter(descriptors, RawPcDescriptors::kAnyKind);
@@ -1859,7 +1882,7 @@
     JoinEntryInstr* join = EnsureControlFlowJoin(descriptors, handler_pc);
 
     // Make sure exception handler starts with SetFrame bytecode instruction.
-    InstructionAt(handler_pc, KernelBytecode::kSetFrame);
+    ASSERT(KernelBytecode::IsSetFrameOpcode(&(raw_bytecode_[handler_pc])));
 
     const Array& handler_types =
         Array::ZoneHandle(Z, handlers.GetHandledTypes(try_index));
@@ -1880,7 +1903,7 @@
   const Bytecode& bytecode = Bytecode::Handle(Z, function().bytecode());
 
   object_pool_ = bytecode.object_pool();
-  raw_bytecode_ = reinterpret_cast<KBCInstr*>(bytecode.PayloadStart());
+  raw_bytecode_ = reinterpret_cast<const KBCInstr*>(bytecode.PayloadStart());
   bytecode_length_ = bytecode.Size() / sizeof(KBCInstr);
 
   ProcessICDataInObjectPool(object_pool_);
@@ -1903,8 +1926,9 @@
 
   code_ = Fragment(normal_entry);
 
-  for (pc_ = 0; pc_ < bytecode_length_; ++pc_) {
-    bytecode_instr_ = raw_bytecode_[pc_];
+  for (pc_ = 0; pc_ < bytecode_length_; pc_ = next_pc_) {
+    bytecode_instr_ = &(raw_bytecode_[pc_]);
+    next_pc_ = pc_ + (KernelBytecode::Next(bytecode_instr_) - bytecode_instr_);
 
     JoinEntryInstr* join = jump_targets_.Lookup(pc_);
     if (join != nullptr) {
diff --git a/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.h b/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.h
index c085374..833deb2 100644
--- a/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.h
+++ b/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.h
@@ -31,10 +31,8 @@
         parsed_function_(parsed_function),
         ic_data_array_(ic_data_array),
         object_pool_(ObjectPool::Handle(zone_)),
-        raw_bytecode_(nullptr),
         bytecode_length_(0),
         pc_(0),
-        bytecode_instr_(KernelBytecode::kTrap),
         position_(TokenPosition::kNoSource),
         local_vars_(zone_, 0),
         parameters_(zone_, 0),
@@ -110,9 +108,11 @@
   Operand DecodeOperandB();
   Operand DecodeOperandC();
   Operand DecodeOperandD();
+  Operand DecodeOperandE();
+  Operand DecodeOperandF();
   Operand DecodeOperandX();
+  Operand DecodeOperandY();
   Operand DecodeOperandT();
-  KBCInstr InstructionAt(intptr_t pc, KernelBytecode::Opcode expect_opcode);
   Constant ConstantAt(Operand entry_index, intptr_t add_index = 0);
   void PushConstant(Constant constant);
   Constant PopConstant();
@@ -142,7 +142,8 @@
 
   void BuildInstruction(KernelBytecode::Opcode opcode);
 
-#define DECLARE_BUILD_METHOD(name, encoding, op1, op2, op3) void Build##name();
+#define DECLARE_BUILD_METHOD(name, encoding, kind, op1, op2, op3)              \
+  void Build##name();
   KERNEL_BYTECODES_LIST(DECLARE_BUILD_METHOD)
 #undef DECLARE_BUILD_METHOD
 
@@ -150,7 +151,7 @@
   intptr_t GetTryIndex(const PcDescriptors& descriptors, intptr_t pc);
   JoinEntryInstr* EnsureControlFlowJoin(const PcDescriptors& descriptors,
                                         intptr_t pc);
-  bool RequiresScratchVar(KBCInstr instr);
+  bool RequiresScratchVar(const KBCInstr* instr);
   void CollectControlFlow(const PcDescriptors& descriptors,
                           const ExceptionHandlers& handlers,
                           GraphEntryInstr* graph_entry);
@@ -173,10 +174,11 @@
   ParsedFunction* parsed_function_;
   ZoneGrowableArray<const ICData*>* ic_data_array_;
   ObjectPool& object_pool_;
-  KBCInstr* raw_bytecode_;
+  const KBCInstr* raw_bytecode_ = nullptr;
   intptr_t bytecode_length_;
   intptr_t pc_;
-  KBCInstr bytecode_instr_;
+  intptr_t next_pc_ = -1;
+  const KBCInstr* bytecode_instr_ = nullptr;
   TokenPosition position_;  // TODO(alexmarkov): Set/update.
   Fragment code_;
   ZoneGrowableArray<LocalVariable*> local_vars_;
diff --git a/runtime/vm/compiler/frontend/bytecode_reader.cc b/runtime/vm/compiler/frontend/bytecode_reader.cc
index 2b3f515..690d873 100644
--- a/runtime/vm/compiler/frontend/bytecode_reader.cc
+++ b/runtime/vm/compiler/frontend/bytecode_reader.cc
@@ -373,6 +373,8 @@
       Z, Function::NewClosureFunction(name, Function::Cast(parent),
                                       TokenPosition::kNoSource));
 
+  closure.set_is_declared_in_bytecode(true);
+
   closures_->SetAt(closureIndex, closure);
 
   Type& signature_type =
@@ -686,9 +688,16 @@
                     "BytecodeReaderHelper::ReadBytecode");
 #endif  // defined(SUPPORT_TIMELINE)
   intptr_t size = helper_->ReadUInt();
-  intptr_t offset = Utils::RoundUp(helper_->reader_.offset(), sizeof(KBCInstr));
+  intptr_t offset = helper_->reader_.offset();
+
+  static_assert(KernelBytecode::kMinSupportedBytecodeFormatVersion < 7,
+                "Cleanup support for old bytecode format versions");
+  if (bytecode_component_->GetVersion() < 7) {
+    const intptr_t kAlignment = 4;
+    offset = Utils::RoundUp(offset, kAlignment);
+  }
+
   const uint8_t* data = helper_->reader_.BufferAt(offset);
-  ASSERT(Utils::IsAligned(data, sizeof(KBCInstr)));
   helper_->reader_.set_offset(offset + size);
 
   // Create and return bytecode object.
@@ -712,6 +721,10 @@
     ExceptionHandlerList* exception_handlers_list =
         new (Z) ExceptionHandlerList();
 
+    static_assert(KernelBytecode::kMinSupportedBytecodeFormatVersion < 7,
+                  "Cleanup support for old bytecode format versions");
+    const int kPCShifter = (bytecode_component_->GetVersion() < 7) ? 2 : 0;
+
     // Encoding of ExceptionsTable is described in
     // pkg/vm/lib/bytecode/exceptions.dart.
     for (intptr_t try_index = 0; try_index < try_block_count; try_index++) {
@@ -719,11 +732,14 @@
       intptr_t outer_try_index = outer_try_index_plus1 - 1;
       // PcDescriptors are expressed in terms of return addresses.
       intptr_t start_pc = KernelBytecode::BytecodePcToOffset(
-          helper_->reader_.ReadUInt(), /* is_return_address = */ true);
+          helper_->reader_.ReadUInt() << kPCShifter,
+          /* is_return_address = */ true);
       intptr_t end_pc = KernelBytecode::BytecodePcToOffset(
-          helper_->reader_.ReadUInt(), /* is_return_address = */ true);
+          helper_->reader_.ReadUInt() << kPCShifter,
+          /* is_return_address = */ true);
       intptr_t handler_pc = KernelBytecode::BytecodePcToOffset(
-          helper_->reader_.ReadUInt(), /* is_return_address = */ false);
+          helper_->reader_.ReadUInt() << kPCShifter,
+          /* is_return_address = */ false);
       uint8_t flags = helper_->reader_.ReadByte();
       const uint8_t kFlagNeedsStackTrace = 1 << 0;
       const uint8_t kFlagIsSynthetic = 1 << 1;
@@ -850,7 +866,7 @@
 
   intptr_t magic = helper_->reader_.ReadUInt32();
   if (magic != KernelBytecode::kMagicValue) {
-    return ReadBytecodeComponentV2(md_offset);
+    FATAL1("Unexpected Dart bytecode magic %" Px, magic);
   }
 
   const intptr_t version = helper_->reader_.ReadUInt32();
@@ -863,6 +879,7 @@
            version, KernelBytecode::kMinSupportedBytecodeFormatVersion,
            KernelBytecode::kMaxSupportedBytecodeFormatVersion);
   }
+  BytecodeReader::UseBytecodeVersion(version);
 
   helper_->reader_.ReadUInt32();  // Skip stringTable.numItems
   const intptr_t string_table_offset =
@@ -927,59 +944,6 @@
   return bytecode_component_array.raw();
 }
 
-// TODO(alexmarkov): obsolete, remove when dropping support for old bytecode
-// format version.
-RawArray* BytecodeReaderHelper::ReadBytecodeComponentV2(intptr_t md_offset) {
-  AlternativeReadingScope alt(&helper_->reader_, &H.metadata_payloads(),
-                              md_offset);
-
-  const intptr_t kMinVersion = 1;
-  const intptr_t kMaxVersion = 2;
-
-  const intptr_t version = helper_->reader_.ReadUInt();
-  if ((version < kMinVersion) || (version > kMaxVersion)) {
-    FATAL1("Unsupported Dart bytecode format version %" Pd ".", version);
-  }
-
-  const intptr_t strings_size = helper_->reader_.ReadUInt();
-  helper_->reader_.ReadUInt();  // Objects table size.
-
-  // Read header of strings table.
-  const intptr_t strings_header_offset = helper_->reader_.offset();
-  const intptr_t num_one_byte_strings = helper_->reader_.ReadUInt32();
-  const intptr_t num_two_byte_strings = helper_->reader_.ReadUInt32();
-  const intptr_t strings_contents_offset =
-      helper_->reader_.offset() +
-      (num_one_byte_strings + num_two_byte_strings) * 4;
-
-  // Read header of objects table.
-  helper_->reader_.set_offset(strings_header_offset + strings_size);
-  const intptr_t num_objects = helper_->reader_.ReadUInt();
-  const intptr_t objects_size = helper_->reader_.ReadUInt();
-
-  // Skip over contents of objects.
-  const intptr_t objects_contents_offset = helper_->reader_.offset();
-  helper_->reader_.set_offset(objects_contents_offset + objects_size);
-
-  const Array& bytecode_component_array =
-      Array::Handle(Z, BytecodeComponentData::New(
-                           Z, version, num_objects, strings_header_offset,
-                           strings_contents_offset, objects_contents_offset, 0,
-                           0, 0, 0, 0, Heap::kOld));
-  BytecodeComponentData bytecode_component(bytecode_component_array);
-
-  // Read object offsets.
-  Smi& offs = Smi::Handle(Z);
-  for (intptr_t i = 0; i < num_objects; ++i) {
-    offs = Smi::New(helper_->reader_.ReadUInt());
-    bytecode_component.SetObject(i, offs);
-  }
-
-  H.SetBytecodeComponent(bytecode_component_array);
-
-  return bytecode_component_array.raw();
-}
-
 RawObject* BytecodeReaderHelper::ReadObject() {
   uint32_t header = helper_->reader_.ReadUInt();
   if ((header & kReferenceBit) != 0) {
@@ -2030,10 +1994,10 @@
 
   if (function.HasOptionalParameters()) {
     const KBCInstr* raw_bytecode =
-        reinterpret_cast<KBCInstr*>(target_bytecode.PayloadStart());
-    KBCInstr entry = raw_bytecode[0];
-    ASSERT(KernelBytecode::DecodeOpcode(entry) ==
-           KernelBytecode::kEntryOptional);
+        reinterpret_cast<const KBCInstr*>(target_bytecode.PayloadStart());
+    const KBCInstr* entry = raw_bytecode;
+    raw_bytecode = KernelBytecode::Next(raw_bytecode);
+    ASSERT(KernelBytecode::IsEntryOptionalOpcode(entry));
     ASSERT(KernelBytecode::DecodeB(entry) ==
            function.NumOptionalPositionalParameters());
     ASSERT(KernelBytecode::DecodeC(entry) ==
@@ -2046,11 +2010,11 @@
     if (function.HasOptionalPositionalParameters()) {
       for (intptr_t i = 0, n = function.NumOptionalPositionalParameters();
            i < n; ++i) {
-        const KBCInstr load = raw_bytecode[1 + i];
-        ASSERT(KernelBytecode::DecodeOpcode(load) ==
-               KernelBytecode::kLoadConstant);
+        const KBCInstr* load = raw_bytecode;
+        raw_bytecode = KernelBytecode::Next(raw_bytecode);
+        ASSERT(KernelBytecode::IsLoadConstantOpcode(load));
         const auto& value = Instance::CheckedZoneHandle(
-            Z, obj_pool.ObjectAt(KernelBytecode::DecodeD(load)));
+            Z, obj_pool.ObjectAt(KernelBytecode::DecodeE(load)));
         default_values->Add(&value);
       }
     } else {
@@ -2058,15 +2022,14 @@
       auto& param_name = String::Handle(Z);
       default_values->EnsureLength(num_opt_params, nullptr);
       for (intptr_t i = 0; i < num_opt_params; ++i) {
-        const KBCInstr load_name = raw_bytecode[1 + 2 * i];
-        const KBCInstr load_value = raw_bytecode[1 + 2 * i + 1];
-        ASSERT(KernelBytecode::DecodeOpcode(load_name) ==
-               KernelBytecode::kLoadConstant);
-        ASSERT(KernelBytecode::DecodeOpcode(load_value) ==
-               KernelBytecode::kLoadConstant);
-        param_name ^= obj_pool.ObjectAt(KernelBytecode::DecodeD(load_name));
+        const KBCInstr* load_name = raw_bytecode;
+        const KBCInstr* load_value = KernelBytecode::Next(load_name);
+        raw_bytecode = KernelBytecode::Next(load_value);
+        ASSERT(KernelBytecode::IsLoadConstantOpcode(load_name));
+        ASSERT(KernelBytecode::IsLoadConstantOpcode(load_value));
+        param_name ^= obj_pool.ObjectAt(KernelBytecode::DecodeE(load_name));
         const auto& value = Instance::CheckedZoneHandle(
-            Z, obj_pool.ObjectAt(KernelBytecode::DecodeD(load_value)));
+            Z, obj_pool.ObjectAt(KernelBytecode::DecodeE(load_value)));
 
         const intptr_t num_params = function.NumParameters();
         intptr_t param_index = num_fixed_params;
@@ -2250,6 +2213,28 @@
       annotation_field.bytecode_offset());
 }
 
+static_assert(KernelBytecode::kMinSupportedBytecodeFormatVersion < 7,
+              "Cleanup support for old bytecode format versions");
+void BytecodeReader::UseBytecodeVersion(intptr_t version) {
+  Isolate* isolate = Isolate::Current();
+  bool using_old = isolate->is_using_old_bytecode_instructions();
+  bool using_new = isolate->is_using_new_bytecode_instructions();
+  if (version < 7) {
+    using_old = true;
+    isolate->set_is_using_old_bytecode_instructions(true);
+  } else {
+    using_new = true;
+    isolate->set_is_using_new_bytecode_instructions(true);
+  }
+
+  if (using_old && using_new) {
+    FATAL1(
+        "Unable to use both new and old bytecode instructions in the same Dart "
+        "isolate (%s)",
+        isolate->name());
+  }
+}
+
 bool IsStaticFieldGetterGeneratedAsInitializer(const Function& function,
                                                Zone* zone) {
   ASSERT(function.kind() == RawFunction::kImplicitStaticGetter);
diff --git a/runtime/vm/compiler/frontend/bytecode_reader.h b/runtime/vm/compiler/frontend/bytecode_reader.h
index bb858c3..701cc2d 100644
--- a/runtime/vm/compiler/frontend/bytecode_reader.h
+++ b/runtime/vm/compiler/frontend/bytecode_reader.h
@@ -72,7 +72,6 @@
   RawLibrary* ReadMain();
 
   RawArray* ReadBytecodeComponent(intptr_t md_offset);
-  RawArray* ReadBytecodeComponentV2(intptr_t md_offset);
 
   // Fills in [is_covariant] and [is_generic_covariant_impl] vectors
   // according to covariance attributes of [function] parameters.
@@ -261,6 +260,8 @@
 
   // Read annotation for the given annotation field.
   static RawObject* ReadAnnotation(const Field& annotation_field);
+
+  static void UseBytecodeVersion(intptr_t version);
 };
 
 class BytecodeSourcePositionsIterator : ValueObject {
@@ -268,6 +269,8 @@
   BytecodeSourcePositionsIterator(Zone* zone, const Bytecode& bytecode)
       : reader_(ExternalTypedData::Handle(zone, bytecode.GetBinary(zone))),
         pairs_remaining_(0),
+        pc_shifter_(
+            Isolate::Current()->is_using_old_bytecode_instructions() ? 2 : 0),
         cur_bci_(0),
         cur_token_pos_(TokenPosition::kNoSource.value()) {
     if (bytecode.HasSourcePositions()) {
@@ -282,7 +285,7 @@
     }
     ASSERT(pairs_remaining_ > 0);
     --pairs_remaining_;
-    cur_bci_ += reader_.ReadUInt();
+    cur_bci_ += reader_.ReadUInt() << pc_shifter_;
     cur_token_pos_ += reader_.ReadSLEB128();
     return true;
   }
@@ -299,6 +302,7 @@
  private:
   Reader reader_;
   intptr_t pairs_remaining_;
+  intptr_t pc_shifter_;
   intptr_t cur_bci_;
   intptr_t cur_token_pos_;
 };
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
index 37236d7..706d2e6 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
@@ -168,14 +168,18 @@
     if (H.thread()->IsMutatorThread()) {
       field.RecordStore(Object::null_object());
     } else {
-      ASSERT(field.is_nullable());
+      ASSERT(field.is_nullable(/* silence_assert = */ true));
     }
     return Fragment();
   }
 
   Fragment instructions;
   instructions += LoadLocal(parsed_function()->receiver_var());
+  // All closures created inside BuildExpression will have
+  // field.RawOwner() as its owner.
+  closure_owner_ = field.RawOwner();
   instructions += BuildExpression();
+  closure_owner_ = Object::null();
   instructions += flow_graph_builder_->StoreInstanceFieldGuarded(field, true);
   return instructions;
 }
@@ -963,27 +967,15 @@
     return bytecode_compiler.BuildGraph();
   }
 
-  // This is the legacy code path to handle bytecode attached to kernel AST
-  // members.
-  // TODO(alexmarkov): clean this up after dropping old format versions.
-  if ((FLAG_use_bytecode_compiler || FLAG_enable_interpreter) &&
-      function.IsBytecodeAllowed(Z)) {
-    if (!function.HasBytecode()) {
-      bytecode_metadata_helper_.ReadMetadata(function);
-    }
-    if (function.HasBytecode() &&
-        (function.kind() != RawFunction::kImplicitGetter) &&
-        (function.kind() != RawFunction::kImplicitSetter) &&
-        (function.kind() != RawFunction::kImplicitStaticGetter) &&
-        (function.kind() != RawFunction::kMethodExtractor) &&
-        (function.kind() != RawFunction::kInvokeFieldDispatcher) &&
-        (function.kind() != RawFunction::kNoSuchMethodDispatcher)) {
-      BytecodeFlowGraphBuilder bytecode_compiler(
-          flow_graph_builder_, parsed_function(),
-          &(flow_graph_builder_->ic_data_array_));
-      return bytecode_compiler.BuildGraph();
-    }
-  }
+  // Certain special functions could have a VM-internal bytecode
+  // attached to them.
+  ASSERT((!function.HasBytecode()) ||
+         (function.kind() == RawFunction::kImplicitGetter) ||
+         (function.kind() == RawFunction::kImplicitSetter) ||
+         (function.kind() == RawFunction::kImplicitStaticGetter) ||
+         (function.kind() == RawFunction::kMethodExtractor) ||
+         (function.kind() == RawFunction::kInvokeFieldDispatcher) ||
+         (function.kind() == RawFunction::kNoSuchMethodDispatcher));
 
   ParseKernelASTFunction();
 
@@ -4914,8 +4906,14 @@
         name = &Symbols::AnonymousClosure();
       }
       // NOTE: This is not TokenPosition in the general sense!
-      function = Function::NewClosureFunction(
-          *name, parsed_function()->function(), position);
+      if (!closure_owner_.IsNull()) {
+        function = Function::NewClosureFunctionWithKind(
+            RawFunction::kClosureFunction, *name, parsed_function()->function(),
+            position, closure_owner_);
+      } else {
+        function = Function::NewClosureFunction(
+            *name, parsed_function()->function(), position);
+      }
 
       function.set_is_debuggable(function_node_helper.dart_async_marker_ ==
                                  FunctionNodeHelper::kSync);
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
index edf29ea..2006924 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
@@ -43,7 +43,8 @@
         direct_call_metadata_helper_(this),
         inferred_type_metadata_helper_(this),
         procedure_attributes_metadata_helper_(this),
-        call_site_attributes_metadata_helper_(this, &type_translator_) {}
+        call_site_attributes_metadata_helper_(this, &type_translator_),
+        closure_owner_(Object::Handle(flow_graph_builder->zone_)) {}
 
   virtual ~StreamingFlowGraphBuilder() {}
 
@@ -358,6 +359,7 @@
   InferredTypeMetadataHelper inferred_type_metadata_helper_;
   ProcedureAttributesMetadataHelper procedure_attributes_metadata_helper_;
   CallSiteAttributesMetadataHelper call_site_attributes_metadata_helper_;
+  Object& closure_owner_;
 
   friend class KernelLoader;
 
diff --git a/runtime/vm/compiler/frontend/kernel_to_il.cc b/runtime/vm/compiler/frontend/kernel_to_il.cc
index 755ccb6..6049959 100644
--- a/runtime/vm/compiler/frontend/kernel_to_il.cc
+++ b/runtime/vm/compiler/frontend/kernel_to_il.cc
@@ -3,11 +3,12 @@
 // BSD-style license that can be found in the LICENSE file.
 
 #include "vm/compiler/frontend/kernel_to_il.h"
-#include "vm/compiler/aot/precompiler.h"
-#include "vm/compiler/backend/locations.h"
 
+#include "platform/assert.h"
+#include "vm/compiler/aot/precompiler.h"
 #include "vm/compiler/backend/il.h"
 #include "vm/compiler/backend/il_printer.h"
+#include "vm/compiler/backend/locations.h"
 #include "vm/compiler/ffi.h"
 #include "vm/compiler/frontend/kernel_binary_flowgraph.h"
 #include "vm/compiler/frontend/kernel_translation_helper.h"
@@ -388,11 +389,12 @@
 Fragment FlowGraphBuilder::FfiCall(
     const Function& signature,
     const ZoneGrowableArray<Representation>& arg_reps,
-    const ZoneGrowableArray<Location>& arg_locs) {
+    const ZoneGrowableArray<Location>& arg_locs,
+    const ZoneGrowableArray<HostLocation>* arg_host_locs) {
   Fragment body;
 
-  FfiCallInstr* call =
-      new (Z) FfiCallInstr(Z, GetNextDeoptId(), signature, arg_reps, arg_locs);
+  FfiCallInstr* const call = new (Z) FfiCallInstr(
+      Z, GetNextDeoptId(), signature, arg_reps, arg_locs, arg_host_locs);
 
   for (intptr_t i = call->InputCount() - 1; i >= 0; --i) {
     call->SetInputAt(i, Pop());
@@ -1949,14 +1951,9 @@
     function = owner.LookupFunction(func_name);
   }
 
-  auto& tmp = Object::Handle(Z);
-  tmp = function.Owner();
-  tmp = Class::Cast(tmp).library();
-  auto& library = Library::Cast(tmp);
-
   Object& options = Object::Handle(Z);
-  if (!library.FindPragma(thread_, function, Symbols::vm_trace_entrypoints(),
-                          &options) ||
+  if (!Library::FindPragma(thread_, /*only_core=*/false, function,
+                           Symbols::vm_trace_entrypoints(), &options) ||
       options.IsNull() || !options.IsClosure()) {
     return Drop();
   }
@@ -2503,7 +2500,6 @@
 
 FlowGraph* FlowGraphBuilder::BuildGraphOfFfiTrampoline(
     const Function& function) {
-#if !defined(TARGET_ARCH_DBC)
   graph_entry_ =
       new (Z) GraphEntryInstr(*parsed_function_, Compiler::kNoOSRDeoptId);
 
@@ -2519,7 +2515,13 @@
   body += CheckStackOverflowInPrologue(function.token_pos());
 
   const Function& signature = Function::ZoneHandle(Z, function.FfiCSignature());
+#if !defined(TARGET_ARCH_DBC)
   const auto& arg_reps = *compiler::ffi::ArgumentRepresentations(signature);
+  const ZoneGrowableArray<HostLocation>* arg_host_locs = nullptr;
+#else
+  const auto& arg_reps = *compiler::ffi::ArgumentHostRepresentations(signature);
+  const auto* arg_host_locs = compiler::ffi::HostArgumentLocations(arg_reps);
+#endif
   const auto& arg_locs = *compiler::ffi::ArgumentLocations(arg_reps);
 
   BuildArgumentTypeChecks(TypeChecksToBuild::kCheckAllTypeParameterBounds,
@@ -2564,7 +2566,7 @@
                     Z, Class::Handle(I->object_store()->ffi_pointer_class()))
                     ->context_variables()[0]));
   body += UnboxTruncate(kUnboxedFfiIntPtr);
-  body += FfiCall(signature, arg_reps, arg_locs);
+  body += FfiCall(signature, arg_reps, arg_locs, arg_host_locs);
 
   ffi_type = signature.result_type();
   if (compiler::ffi::NativeTypeIsPointer(ffi_type)) {
@@ -2574,7 +2576,12 @@
     body += Drop();
     body += NullConstant();
   } else {
+#if !defined(TARGET_ARCH_DBC)
     Representation from_rep = compiler::ffi::ResultRepresentation(signature);
+#else
+    Representation from_rep =
+        compiler::ffi::ResultHostRepresentation(signature);
+#endif  // !defined(TARGET_ARCH_DBC)
     Representation to_rep = compiler::ffi::TypeRepresentation(ffi_type);
     if (from_rep != to_rep) {
       body += BitCast(from_rep, to_rep);
@@ -2588,9 +2595,6 @@
 
   return new (Z) FlowGraph(*parsed_function_, graph_entry_, last_used_block_id_,
                            prologue_info);
-#else
-  UNREACHABLE();
-#endif
 }
 
 void FlowGraphBuilder::SetCurrentTryCatchBlock(TryCatchBlock* try_catch_block) {
diff --git a/runtime/vm/compiler/frontend/kernel_to_il.h b/runtime/vm/compiler/frontend/kernel_to_il.h
index 0b18641..1e34e13 100644
--- a/runtime/vm/compiler/frontend/kernel_to_il.h
+++ b/runtime/vm/compiler/frontend/kernel_to_il.h
@@ -151,9 +151,12 @@
                        intptr_t argument_count,
                        const Array& argument_names,
                        bool use_unchecked_entry = false);
-  Fragment FfiCall(const Function& signature,
-                   const ZoneGrowableArray<Representation>& arg_reps,
-                   const ZoneGrowableArray<Location>& arg_locs);
+
+  Fragment FfiCall(
+      const Function& signature,
+      const ZoneGrowableArray<Representation>& arg_reps,
+      const ZoneGrowableArray<Location>& arg_locs,
+      const ZoneGrowableArray<HostLocation>* arg_host_locs = nullptr);
 
   Fragment RethrowException(TokenPosition position, int catch_try_index);
   Fragment LoadLocal(LocalVariable* variable);
diff --git a/runtime/vm/compiler/jit/compiler.cc b/runtime/vm/compiler/jit/compiler.cc
index d334330..da82ceb 100644
--- a/runtime/vm/compiler/jit/compiler.cc
+++ b/runtime/vm/compiler/jit/compiler.cc
@@ -84,10 +84,6 @@
             false,
             "Trace only optimizing compiler operations.");
 DEFINE_FLAG(bool, trace_bailout, false, "Print bailout from ssa compiler.");
-DEFINE_FLAG(bool,
-            verify_compiler,
-            false,
-            "Enable compiler verification assertions");
 
 DECLARE_FLAG(bool, enable_interpreter);
 DECLARE_FLAG(bool, huge_method_cutoff_in_code_size);
@@ -885,6 +881,8 @@
       if (optimized) {
         if (error.IsLanguageError() &&
             LanguageError::Cast(error).kind() == Report::kBailout) {
+          // Functions which cannot deoptimize should never bail out.
+          ASSERT(!function.ForceOptimize());
           // Optimizer bailed out. Disable optimizations and never try again.
           if (trace_compiler) {
             THR_Print("--> disabling optimizations for '%s'\n",
@@ -1160,8 +1158,8 @@
   for (int i = 0; i < functions.Length(); i++) {
     func ^= functions.At(i);
     ASSERT(!func.IsNull());
-    if (!func.HasCode() &&
-        !func.is_abstract() && !func.IsRedirectingFactory()) {
+    if (!func.HasCode() && !func.is_abstract() &&
+        !func.IsRedirectingFactory()) {
       result = CompileFunction(thread, func);
       if (result.IsError()) {
         return Error::Cast(result).raw();
@@ -1395,18 +1393,16 @@
 
 BackgroundCompiler::BackgroundCompiler(Isolate* isolate)
     : isolate_(isolate),
-      queue_monitor_(new Monitor()),
+      queue_monitor_(),
       function_queue_(new BackgroundCompilationQueue()),
-      done_monitor_(new Monitor()),
+      done_monitor_(),
       running_(false),
       done_(true),
       disabled_depth_(0) {}
 
 // Fields all deleted in ::Stop; here clear them.
 BackgroundCompiler::~BackgroundCompiler() {
-  delete queue_monitor_;
   delete function_queue_;
-  delete done_monitor_;
 }
 
 void BackgroundCompiler::Run() {
@@ -1422,7 +1418,7 @@
       HANDLESCOPE(thread);
       Function& function = Function::Handle(zone);
       {
-        MonitorLocker ml(queue_monitor_);
+        MonitorLocker ml(&queue_monitor_);
         function = function_queue()->PeekFunction();
       }
       while (running_ && !function.IsNull()) {
@@ -1439,7 +1435,7 @@
 
         QueueElement* qelem = NULL;
         {
-          MonitorLocker ml(queue_monitor_);
+          MonitorLocker ml(&queue_monitor_);
           if (function_queue()->IsEmpty()) {
             // We are shutting down, queue was cleared.
             function = Function::null();
@@ -1468,7 +1464,7 @@
     Thread::ExitIsolateAsHelper();
     {
       // Wait to be notified when the work queue is not empty.
-      MonitorLocker ml(queue_monitor_);
+      MonitorLocker ml(&queue_monitor_);
       while (function_queue()->IsEmpty() && running_) {
         ml.Wait();
       }
@@ -1477,7 +1473,7 @@
 
   {
     // Notify that the thread is done.
-    MonitorLocker ml_done(done_monitor_);
+    MonitorLocker ml_done(&done_monitor_);
     done_ = true;
     ml_done.Notify();
   }
@@ -1491,7 +1487,7 @@
     isolate_->heap()->CollectMostGarbage();
   }
   {
-    MonitorLocker ml(queue_monitor_);
+    MonitorLocker ml(&queue_monitor_);
     ASSERT(running_);
     if (function_queue()->ContainsObj(function)) {
       return;
@@ -1525,7 +1521,7 @@
   ASSERT(thread->IsMutatorThread());
   ASSERT(!thread->IsAtSafepoint());
 
-  MonitorLocker ml(done_monitor_);
+  MonitorLocker ml(&done_monitor_);
   if (running_ || !done_) return;
   running_ = true;
   done_ = false;
@@ -1543,14 +1539,14 @@
   ASSERT(!thread->IsAtSafepoint());
 
   {
-    MonitorLocker ml(queue_monitor_);
+    MonitorLocker ml(&queue_monitor_);
     running_ = false;
     function_queue_->Clear();
     ml.Notify();  // Stop waiting for the queue.
   }
 
   {
-    MonitorLocker ml_done(done_monitor_);
+    MonitorLocker ml_done(&done_monitor_);
     while (!done_) {
       ml_done.WaitWithSafepointCheck(thread);
     }
diff --git a/runtime/vm/compiler/jit/compiler.h b/runtime/vm/compiler/jit/compiler.h
index c7e6412..b804a70 100644
--- a/runtime/vm/compiler/jit/compiler.h
+++ b/runtime/vm/compiler/jit/compiler.h
@@ -226,10 +226,10 @@
 
   Isolate* isolate_;
 
-  Monitor* queue_monitor_;  // Controls access to the queue.
+  Monitor queue_monitor_;  // Controls access to the queue.
   BackgroundCompilationQueue* function_queue_;
 
-  Monitor* done_monitor_;   // Notify/wait that the thread is done.
+  Monitor done_monitor_;    // Notify/wait that the thread is done.
   bool running_;            // While true, will try to read queue and compile.
   bool done_;               // True if the thread is done.
 
diff --git a/runtime/vm/compiler/method_recognizer.cc b/runtime/vm/compiler/method_recognizer.cc
index 0973fed..e36397c 100644
--- a/runtime/vm/compiler/method_recognizer.cc
+++ b/runtime/vm/compiler/method_recognizer.cc
@@ -37,56 +37,40 @@
 
 intptr_t MethodRecognizer::ResultCidFromPragma(
     const Object& function_or_field) {
-  // TODO(vm-team): The caller should only call us if the
-  // function_or_field.has_pragma(). If this method turns out to be a
-  // performance problem nonetheless, we could consider adding a cache.
   auto T = Thread::Current();
   auto Z = T->zone();
-  auto& klass = Class::Handle(Z);
-  if (function_or_field.IsFunction()) {
-    auto& function = Function::Cast(function_or_field);
-    ASSERT(function.has_pragma());
-    klass = function.Owner();
-  } else {
-    auto& field = Field::Cast(function_or_field);
-    ASSERT(field.has_pragma());
-    klass = field.Owner();
-  }
-  auto& library = Library::Handle(Z, klass.library());
-  const bool can_use_pragma = library.IsAnyCoreLibrary();
-  if (can_use_pragma) {
-    auto& option = Object::Handle(Z);
-    if (library.FindPragma(T, function_or_field,
-                           Symbols::vm_exact_result_type(), &option)) {
-      if (option.IsType()) {
-        return Type::Cast(option).type_class_id();
-      } else if (option.IsString()) {
-        auto& str = String::Cast(option);
-        // 'str' should match the pattern '([^#]+)#([^#\?]+)' where group 1
-        // is the library URI and group 2 is the class name.
-        bool parse_failure = false;
-        intptr_t library_end = -1;
-        for (intptr_t i = 0; i < str.Length(); ++i) {
-          if (str.CharAt(i) == '#') {
-            if (library_end != -1) {
-              parse_failure = true;
-              break;
-            } else {
-              library_end = i;
-            }
+  auto& option = Object::Handle(Z);
+  if (Library::FindPragma(T, /*only_core=*/true, function_or_field,
+                          Symbols::vm_exact_result_type(), &option)) {
+    if (option.IsType()) {
+      return Type::Cast(option).type_class_id();
+    } else if (option.IsString()) {
+      auto& str = String::Cast(option);
+      // 'str' should match the pattern '([^#]+)#([^#\?]+)' where group 1
+      // is the library URI and group 2 is the class name.
+      bool parse_failure = false;
+      intptr_t library_end = -1;
+      for (intptr_t i = 0; i < str.Length(); ++i) {
+        if (str.CharAt(i) == '#') {
+          if (library_end != -1) {
+            parse_failure = true;
+            break;
+          } else {
+            library_end = i;
           }
         }
-        if (!parse_failure && library_end > 0) {
-          auto& tmp = String::Handle(Z);
-          tmp = String::SubString(str, 0, library_end, Heap::kOld);
-          library = Library::LookupLibrary(Thread::Current(), tmp);
-          if (!library.IsNull()) {
-            tmp = String::SubString(str, library_end + 1,
-                                    str.Length() - library_end - 1, Heap::kOld);
-            klass = library.LookupClassAllowPrivate(tmp);
-            if (!klass.IsNull()) {
-              return klass.id();
-            }
+      }
+      if (!parse_failure && library_end > 0) {
+        auto& tmp =
+            String::Handle(String::SubString(str, 0, library_end, Heap::kOld));
+        const auto& library = Library::Handle(Library::LookupLibrary(T, tmp));
+        if (!library.IsNull()) {
+          tmp = String::SubString(str, library_end + 1,
+                                  str.Length() - library_end - 1, Heap::kOld);
+          const auto& klass =
+              Class::Handle(library.LookupClassAllowPrivate(tmp));
+          if (!klass.IsNull()) {
+            return klass.id();
           }
         }
       }
@@ -100,24 +84,10 @@
     const Object& function_or_field) {
   auto T = Thread::Current();
   auto Z = T->zone();
-  auto& klass = Class::Handle(Z);
-  if (function_or_field.IsFunction()) {
-    auto& function = Function::Cast(function_or_field);
-    ASSERT(function.has_pragma());
-    klass = function.Owner();
-  } else {
-    auto& field = Field::Cast(function_or_field);
-    ASSERT(field.has_pragma());
-    klass = field.Owner();
-  }
-  auto& library = Library::Handle(Z, klass.library());
-  const bool can_use_pragma = library.IsAnyCoreLibrary();
-  if (can_use_pragma) {
-    auto& option = Object::Handle(Z);
-    if (library.FindPragma(T, function_or_field,
-                           Symbols::vm_non_nullable_result_type(), &option)) {
-      return true;
-    }
+  auto& option = Object::Handle(Z);
+  if (Library::FindPragma(T, /*only_core=*/true, function_or_field,
+                          Symbols::vm_non_nullable_result_type(), &option)) {
+    return true;
   }
 
   // If nothing said otherwise, the return type is nullable.
diff --git a/runtime/vm/compiler/runtime_api.cc b/runtime/vm/compiler/runtime_api.cc
index 8f927b8..758e065 100644
--- a/runtime/vm/compiler/runtime_api.cc
+++ b/runtime/vm/compiler/runtime_api.cc
@@ -368,8 +368,8 @@
   return dart::ICData::TargetIndexFor(num_args);
 }
 
-word ICData::ExactnessOffsetFor(word num_args) {
-  return dart::ICData::ExactnessOffsetFor(num_args);
+word ICData::ExactnessIndexFor(word num_args) {
+  return dart::ICData::ExactnessIndexFor(num_args);
 }
 
 word ICData::TestEntryLengthFor(word num_args, bool exactness_check) {
diff --git a/runtime/vm/compiler/runtime_api.h b/runtime/vm/compiler/runtime_api.h
index d910575..29ff5ba 100644
--- a/runtime/vm/compiler/runtime_api.h
+++ b/runtime/vm/compiler/runtime_api.h
@@ -419,7 +419,7 @@
   static word CodeIndexFor(word num_args);
   static word CountIndexFor(word num_args);
   static word TargetIndexFor(word num_args);
-  static word ExactnessOffsetFor(word num_args);
+  static word ExactnessIndexFor(word num_args);
   static word TestEntryLengthFor(word num_args, bool exactness_check);
   static word EntryPointIndexFor(word num_args);
   static word NumArgsTestedShift();
diff --git a/runtime/vm/compiler/stub_code_compiler_arm.cc b/runtime/vm/compiler/stub_code_compiler_arm.cc
index 5d9aad0..e82fa9f 100644
--- a/runtime/vm/compiler/stub_code_compiler_arm.cc
+++ b/runtime/vm/compiler/stub_code_compiler_arm.cc
@@ -2905,6 +2905,7 @@
 // R8: function to be reoptimized.
 // R4: argument descriptor (preserved).
 void StubCodeCompiler::GenerateOptimizeFunctionStub(Assembler* assembler) {
+  __ ldr(CODE_REG, Address(THR, Thread::optimize_stub_offset()));
   __ EnterStubFrame();
   __ Push(R4);
   __ LoadImmediate(IP, 0);
diff --git a/runtime/vm/compiler/stub_code_compiler_arm64.cc b/runtime/vm/compiler/stub_code_compiler_arm64.cc
index 211a6c4..9bee589 100644
--- a/runtime/vm/compiler/stub_code_compiler_arm64.cc
+++ b/runtime/vm/compiler/stub_code_compiler_arm64.cc
@@ -2993,6 +2993,7 @@
 // R6: function to be re-optimized.
 // R4: argument descriptor (preserved).
 void StubCodeCompiler::GenerateOptimizeFunctionStub(Assembler* assembler) {
+  __ LoadFromOffset(CODE_REG, THR, Thread::optimize_stub_offset());
   __ EnterStubFrame();
   __ Push(R4);
   // Setup space on stack for the return value.
diff --git a/runtime/vm/compiler/stub_code_compiler_ia32.cc b/runtime/vm/compiler/stub_code_compiler_ia32.cc
index 657ec31..806c130 100644
--- a/runtime/vm/compiler/stub_code_compiler_ia32.cc
+++ b/runtime/vm/compiler/stub_code_compiler_ia32.cc
@@ -359,8 +359,7 @@
   // Remove the stub frame as we are about to jump to the dart function.
   __ LeaveFrame();
 
-  __ movl(ECX, FieldAddress(EAX, target::Code::entry_point_offset()));
-  __ jmp(ECX);
+  __ jmp(FieldAddress(EAX, target::Code::entry_point_offset()));
 }
 
 // Called from a static call only when an invalid code has been entered
@@ -666,8 +665,7 @@
     __ Bind(&call_target_function);
   }
 
-  __ movl(EBX, FieldAddress(EAX, target::Function::entry_point_offset()));
-  __ jmp(EBX);
+  __ jmp(FieldAddress(EAX, target::Function::entry_point_offset()));
 }
 
 // Called for inline allocation of arrays.
@@ -1779,8 +1777,7 @@
   __ Bind(&call_target_function);
   __ Comment("Call target");
   // EAX: Target function.
-  __ movl(EBX, FieldAddress(EAX, target::Function::entry_point_offset()));
-  __ jmp(EBX);
+  __ jmp(FieldAddress(EAX, target::Function::entry_point_offset()));
 
 #if !defined(PRODUCT)
   if (optimized == kUnoptimized) {
@@ -1942,8 +1939,7 @@
 
   // Get function and call it, if possible.
   __ movl(EAX, Address(EBX, target_offset));
-  __ movl(EBX, FieldAddress(EAX, target::Function::entry_point_offset()));
-  __ jmp(EBX);
+  __ jmp(FieldAddress(EAX, target::Function::entry_point_offset()));
 
 #if !defined(PRODUCT)
   __ Bind(&stepping);
@@ -1990,8 +1986,7 @@
 
   // When using the interpreter, the function's code may now point to the
   // InterpretCall stub. Make sure EAX, ECX, and EDX are preserved.
-  __ movl(EBX, FieldAddress(EAX, target::Function::entry_point_offset()));
-  __ jmp(EBX);
+  __ jmp(FieldAddress(EAX, target::Function::entry_point_offset()));
 }
 
 // Stub for interpreting a function call.
@@ -2075,8 +2070,7 @@
   __ popl(EBX);  // Restore receiver.
   __ LeaveFrame();
   // Jump to original stub.
-  __ movl(EAX, FieldAddress(EAX, target::Code::entry_point_offset()));
-  __ jmp(EAX);
+  __ jmp(FieldAddress(EAX, target::Code::entry_point_offset()));
 #endif  // defined(PRODUCT)
 }
 
@@ -2092,8 +2086,7 @@
   __ popl(EAX);  // Code of the original stub
   __ LeaveFrame();
   // Jump to original stub.
-  __ movl(EAX, FieldAddress(EAX, target::Code::entry_point_offset()));
-  __ jmp(EAX);
+  __ jmp(FieldAddress(EAX, target::Code::entry_point_offset()));
 #endif  // defined(PRODUCT)
 }
 
@@ -2411,6 +2404,7 @@
 // EBX: function to be reoptimized.
 // EDX: argument descriptor (preserved).
 void StubCodeCompiler::GenerateOptimizeFunctionStub(Assembler* assembler) {
+  __ movl(CODE_REG, Address(THR, Thread::optimize_stub_offset()));
   __ EnterStubFrame();
   __ pushl(EDX);
   __ pushl(Immediate(0));  // Setup space on stack for return value.
@@ -2421,8 +2415,7 @@
   __ popl(EDX);  // Restore argument descriptor.
   __ LeaveFrame();
   __ movl(CODE_REG, FieldAddress(EAX, target::Function::code_offset()));
-  __ movl(EAX, FieldAddress(EAX, target::Function::entry_point_offset()));
-  __ jmp(EAX);
+  __ jmp(FieldAddress(EAX, target::Function::entry_point_offset()));
   __ int3();
 }
 
@@ -2583,8 +2576,7 @@
   __ movl(EDX,
           FieldAddress(
               ECX, target::MegamorphicCache::arguments_descriptor_offset()));
-  __ movl(EBX, FieldAddress(EAX, target::Function::entry_point_offset()));
-  __ ret();
+  __ jmp(FieldAddress(EAX, target::Function::entry_point_offset()));
 
   __ Bind(&probe_failed);
   // Probe failed, check if it is a miss.
diff --git a/runtime/vm/compiler/stub_code_compiler_x64.cc b/runtime/vm/compiler/stub_code_compiler_x64.cc
index 6179c7d..91728ca 100644
--- a/runtime/vm/compiler/stub_code_compiler_x64.cc
+++ b/runtime/vm/compiler/stub_code_compiler_x64.cc
@@ -2036,7 +2036,7 @@
   const intptr_t count_offset =
       target::ICData::CountIndexFor(num_args) * target::kWordSize;
   const intptr_t exactness_offset =
-      target::ICData::ExactnessOffsetFor(num_args) * target::kWordSize;
+      target::ICData::ExactnessIndexFor(num_args) * target::kWordSize;
 
   __ Bind(&loop);
   for (int unroll = optimize ? 4 : 2; unroll >= 0; unroll--) {
@@ -2988,6 +2988,7 @@
 // RDI: function to be reoptimized.
 // R10: argument descriptor (preserved).
 void StubCodeCompiler::GenerateOptimizeFunctionStub(Assembler* assembler) {
+  __ movq(CODE_REG, Address(THR, Thread::optimize_stub_offset()));
   __ EnterStubFrame();
   __ pushq(R10);           // Preserve args descriptor.
   __ pushq(Immediate(0));  // Result slot.
diff --git a/runtime/vm/constants_arm.h b/runtime/vm/constants_arm.h
index ff89001..36ae1dc 100644
--- a/runtime/vm/constants_arm.h
+++ b/runtime/vm/constants_arm.h
@@ -371,6 +371,7 @@
   static constexpr Register kFirstNonArgumentRegister = R8;
   static constexpr Register kSecondNonArgumentRegister = R9;
   static constexpr Register kFirstCalleeSavedCpuReg = NOTFP;
+  static constexpr Register kStackPointerRegister = SPREG;
 };
 
 #undef R
diff --git a/runtime/vm/constants_arm64.h b/runtime/vm/constants_arm64.h
index b84d411..75ecfea 100644
--- a/runtime/vm/constants_arm64.h
+++ b/runtime/vm/constants_arm64.h
@@ -213,6 +213,7 @@
   static constexpr Register kFirstCalleeSavedCpuReg = kAbiFirstPreservedCpuReg;
   static constexpr Register kFirstNonArgumentRegister = R8;
   static constexpr Register kSecondNonArgumentRegister = R9;
+  static constexpr Register kStackPointerRegister = SPREG;
 };
 
 #undef R
diff --git a/runtime/vm/constants_dbc.h b/runtime/vm/constants_dbc.h
index 2d7483b..6a8cd80 100644
--- a/runtime/vm/constants_dbc.h
+++ b/runtime/vm/constants_dbc.h
@@ -170,6 +170,11 @@
 //    Invoke native function at pool[ArgB] with argc_tag at pool[ArgC] using
 //    wrapper at pool[ArgA].
 //
+//  - FfiCall ArgD
+//
+//    Invoke foreign function with unboxed arguments using the signature
+//    descriptor PP[D].
+//
 //  - PushPolymorphicInstanceCall ArgC, D
 //
 //    Skips 2*D + 1 instructions and pushes a function object onto the stack
@@ -801,6 +806,7 @@
   V(PushPolymorphicInstanceCall,         A_D, num, num, ___) \
   V(PushPolymorphicInstanceCallByRange,  A_D, num, num, ___) \
   V(NativeCall,                        A_B_C, num, num, num) \
+  V(FfiCall,                               D, lit, ___, ___) \
   V(OneByteStringFromCharCode,           A_X, reg, xeg, ___) \
   V(StringToCharCode,                    A_X, reg, xeg, ___) \
   V(AddTOS,                                0, ___, ___, ___) \
diff --git a/runtime/vm/constants_ia32.h b/runtime/vm/constants_ia32.h
index 8e8c304..d2cbb93 100644
--- a/runtime/vm/constants_ia32.h
+++ b/runtime/vm/constants_ia32.h
@@ -151,6 +151,7 @@
   static constexpr Register kFirstCalleeSavedCpuReg = EBX;
   static constexpr Register kFirstNonArgumentRegister = EAX;
   static constexpr Register kSecondNonArgumentRegister = ECX;
+  static constexpr Register kStackPointerRegister = SPREG;
 
   // Whether 64-bit arguments must be aligned to an even register or 8-byte
   // stack address. On IA32, 64-bit integers and floating-point values do *not*
diff --git a/runtime/vm/constants_kbc.cc b/runtime/vm/constants_kbc.cc
new file mode 100644
index 0000000..d5ed600
--- /dev/null
+++ b/runtime/vm/constants_kbc.cc
@@ -0,0 +1,82 @@
+// 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.
+
+#define RUNTIME_VM_CONSTANTS_H_  // To work around include guard.
+#include "vm/constants_kbc.h"
+
+namespace dart {
+
+static_assert(KernelBytecode::kMinSupportedBytecodeFormatVersion < 7,
+              "Cleanup support for old bytecode format versions");
+static const intptr_t kOldInstructionSize = 4;
+
+static const intptr_t kInstructionSize0 = 1;
+static const intptr_t kInstructionSizeA = 2;
+static const intptr_t kInstructionSizeD = 2;
+static const intptr_t kInstructionSizeWideD = 5;
+static const intptr_t kInstructionSizeX = 2;
+static const intptr_t kInstructionSizeWideX = 5;
+static const intptr_t kInstructionSizeT = 2;
+static const intptr_t kInstructionSizeWideT = 4;
+static const intptr_t kInstructionSizeA_E = 3;
+static const intptr_t kInstructionSizeWideA_E = 6;
+static const intptr_t kInstructionSizeA_Y = 3;
+static const intptr_t kInstructionSizeWideA_Y = 6;
+static const intptr_t kInstructionSizeD_F = 3;
+static const intptr_t kInstructionSizeWideD_F = 6;
+static const intptr_t kInstructionSizeA_B_C = 4;
+
+const intptr_t KernelBytecode::kInstructionSize[] = {
+#define SIZE_OLD(encoding) kOldInstructionSize
+#define SIZE_ORDN(encoding) kInstructionSize##encoding
+#define SIZE_WIDE(encoding) kInstructionSizeWide##encoding
+#define SIZE_RESV(encoding) SIZE_ORDN(encoding)
+#define SIZE(name, encoding, kind, op1, op2, op3) SIZE_##kind(encoding),
+    KERNEL_BYTECODES_LIST(SIZE)
+#undef SIZE_OLD
+#undef SIZE_ORDN
+#undef SIZE_WIDE
+#undef SIZE_RESV
+#undef SIZE
+};
+
+#define DECLARE_INSTRUCTIONS(name, fmt, kind, fmta, fmtb, fmtc)                \
+  static const KBCInstr k##name##Instructions[] = {                            \
+      KernelBytecode::k##name,                                                 \
+      KernelBytecode::kReturnTOS,                                              \
+  };
+INTERNAL_KERNEL_BYTECODES_LIST(DECLARE_INSTRUCTIONS)
+#undef DECLARE_INSTRUCTIONS
+
+void KernelBytecode::GetVMInternalBytecodeInstructions(
+    Opcode opcode,
+    const KBCInstr** instructions,
+    intptr_t* instructions_size) {
+  switch (opcode) {
+#define CASE(name, fmt, kind, fmta, fmtb, fmtc)                                \
+  case k##name:                                                                \
+    *instructions = k##name##Instructions;                                     \
+    *instructions_size = sizeof(k##name##Instructions);                        \
+    return;
+
+    INTERNAL_KERNEL_BYTECODES_LIST(CASE)
+#undef CASE
+
+    default:
+      UNREACHABLE();
+  }
+}
+
+static const KBCInstr kNativeCallToGrowableListReturnTrampoline[] = {
+    KernelBytecode::kDirectCall,
+    0,                                              // target (doesn't matter)
+    KernelBytecode::kNativeCallToGrowableListArgc,  // number of arguments
+    KernelBytecode::kReturnTOS,
+};
+
+const KBCInstr* KernelBytecode::GetNativeCallToGrowableListReturnTrampoline() {
+  return KernelBytecode::Next(&kNativeCallToGrowableListReturnTrampoline[0]);
+}
+
+}  // namespace dart
diff --git a/runtime/vm/constants_kbc.h b/runtime/vm/constants_kbc.h
index bc25ff8..8a26be6 100644
--- a/runtime/vm/constants_kbc.h
+++ b/runtime/vm/constants_kbc.h
@@ -40,44 +40,71 @@
 //
 // ENCODING
 //
-// Each instruction is a 32-bit integer with opcode stored in the least
-// significant byte. The following operand encodings are used:
+// Each instruction starts with opcode byte. Certain instructions have
+// wide encoding variant. In such case, the least significant bit of opcode is
+// not set for compact variant and set for wide variant.
 //
-//   0........8.......16.......24.......32
-//   +--------+--------+--------+--------+
-//   | opcode |~~~~~~~~~~~~~~~~~~~~~~~~~~|   0: no operands
-//   +--------+--------+--------+--------+
+// The following operand encodings are used:
+//
+//   0........8.......16.......24.......32.......40.......48
+//   +--------+
+//   | opcode |                              0: no operands
+//   +--------+
+//
+//   +--------+--------+
+//   | opcode |    A   |                     A: unsigned 8-bit operand
+//   +--------+--------+
+//
+//   +--------+--------+
+//   | opcode |   D    |                     D: unsigned 8/32-bit operand
+//   +--------+--------+
+//
+//   +--------+----------------------------------+
+//   | opcode |                D                 |            D (wide)
+//   +--------+----------------------------------+
+//
+//   +--------+--------+
+//   | opcode |   X    |                     X: signed 8/32-bit operand
+//   +--------+--------+
+//
+//   +--------+----------------------------------+
+//   | opcode |                X                 |            X (wide)
+//   +--------+----------------------------------+
+//
+//   +--------+--------+
+//   | opcode |    T   |                     T: signed 8/24-bit operand
+//   +--------+--------+
+//
+//   +--------+--------------------------+
+//   | opcode |            T             |   T (wide)
+//   +--------+--------------------------+
+//
+//   +--------+--------+--------+
+//   | opcode |    A   |   E    |            A_E: unsigned 8-bit operand and
+//   +--------+--------+--------+                 unsigned 8/32-bit operand
+//
+//   +--------+--------+----------------------------------+
+//   | opcode |    A   |                 E                |   A_E (wide)
+//   +--------+--------+----------------------------------+
+//
+//   +--------+--------+--------+
+//   | opcode |    A   |   Y    |            A_Y: unsigned 8-bit operand and
+//   +--------+--------+--------+                 signed 8/32-bit operand
+//
+//   +--------+--------+----------------------------------+
+//   | opcode |    A   |                 Y                |   A_Y (wide)
+//   +--------+--------+----------------------------------+
+//
+//   +--------+--------+--------+
+//   | opcode |    D   |   F    |            D_F: unsigned 8/32-bit operand and
+//   +--------+--------+--------+                 unsigned 8-bit operand
+//
+//   +--------+----------------------------------+--------+
+//   | opcode |                 D                |    F   |   D_F (wide)
+//   +--------+----------------------------------+--------+
 //
 //   +--------+--------+--------+--------+
-//   | opcode |    A   |~~~~~~~~~~~~~~~~~|   A: single unsigned 8-bit operand
-//   +--------+--------+--------+--------+
-//
-//   +--------+--------+--------+--------+
-//   | opcode |    A   |        D        | A_D: unsigned 8-bit operand and
-//   +--------+--------+--------+--------+      unsigned 16-bit operand
-//
-//   +--------+--------+--------+--------+
-//   | opcode |    A   |        X        | A_X: unsigned 8-bit operand and
-//   +--------+--------+--------+--------+      signed 16-bit operand
-//
-//   +--------+--------+--------+--------+
-//   | opcode |~~~~~~~~|        D        |   D: unsigned 16-bit operand
-//   +--------+--------+--------+--------+
-//
-//   +--------+--------+--------+--------+
-//   | opcode |~~~~~~~~|        X        |   X: signed 16-bit operand
-//   +--------+--------+--------+--------+
-//
-//   +--------+--------+--------+--------+
-//   | opcode |    A   |    B   |    C   | A_B_C: 3 unsigned 8-bit operands
-//   +--------+--------+--------+--------+
-//
-//   +--------+--------+--------+--------+
-//   | opcode |    A   |    B   |    Y   | A_B_Y: 2 unsigned 8-bit operands
-//   +--------+--------+--------+--------+        1 signed 8-bit operand
-//
-//   +--------+--------+--------+--------+
-//   | opcode |             T            |   T: signed 24-bit operand
+//   | opcode |    A   |    B   |    C   |   A_B_C: 3 unsigned 8-bit operands
 //   +--------+--------+--------+--------+
 //
 //
@@ -423,12 +450,14 @@
 //
 // KernelBytecode list below is specified using the following format:
 //
-//     V(BytecodeName, OperandForm, Op1, Op2, Op3)
+//     V(BytecodeName, OperandForm, BytecodeKind, Op1, Op2, Op3)
 //
-// - OperandForm specifies operand encoding and should be one of 0, A, T, A_D,
-//   A_X, X, D (see ENCODING section above).
+// - OperandForm specifies operand encoding and should be one of 0, A, D, X, T,
+//   A_D (old), A_X (old), A_E, A_Y, D_F or A_B_C (see ENCODING section above).
 //
-// - Op1, Op2, Op2 specify operand meaning. Possible values:
+// - BytecodeKind is one of OLD, WIDE, RESV (reserved), ORDN (ordinary)
+//
+// - Op1, Op2, Op3 specify operand meaning. Possible values:
 //
 //     ___ ignored / non-existent operand
 //     num immediate operand
@@ -442,105 +471,266 @@
 //               and before decoding.
 //
 #define PUBLIC_KERNEL_BYTECODES_LIST(V)                                        \
-  V(Trap,                                  0, ___, ___, ___)                   \
-  V(Entry,                                 D, num, ___, ___)                   \
-  V(EntryFixed,                          A_D, num, num, ___)                   \
-  V(EntryOptional,                     A_B_C, num, num, num)                   \
-  V(LoadConstant,                        A_D, reg, lit, ___)                   \
-  V(Frame,                                 D, num, ___, ___)                   \
-  V(CheckFunctionTypeArgs,               A_D, num, reg, ___)                   \
-  V(CheckStack,                            A, num, ___, ___)                   \
-  V(Allocate,                              D, lit, ___, ___)                   \
-  V(AllocateT,                             0, ___, ___, ___)                   \
-  V(CreateArrayTOS,                        0, ___, ___, ___)                   \
-  V(AllocateContext,                       D, num, ___, ___)                   \
-  V(CloneContext,                          D, num, ___, ___)                   \
-  V(LoadContextParent,                     0, ___, ___, ___)                   \
-  V(StoreContextParent,                    0, ___, ___, ___)                   \
-  V(LoadContextVar,                        D, num, ___, ___)                   \
-  V(StoreContextVar,                       D, num, ___, ___)                   \
-  V(PushConstant,                          D, lit, ___, ___)                   \
-  V(PushNull,                              0, ___, ___, ___)                   \
-  V(PushTrue,                              0, ___, ___, ___)                   \
-  V(PushFalse,                             0, ___, ___, ___)                   \
-  V(PushInt,                               X, num, ___, ___)                   \
-  V(Drop1,                                 0, ___, ___, ___)                   \
-  V(Push,                                  X, xeg, ___, ___)                   \
-  V(PopLocal,                              X, xeg, ___, ___)                   \
-  V(StoreLocal,                            X, xeg, ___, ___)                   \
-  V(LoadFieldTOS,                          D, lit, ___, ___)                   \
-  V(StoreFieldTOS,                         D, lit, ___, ___)                   \
-  V(StoreIndexedTOS,                       0, ___, ___, ___)                   \
-  V(PushStatic,                            D, lit, ___, ___)                   \
-  V(StoreStaticTOS,                        D, lit, ___, ___)                   \
-  V(Jump,                                  T, tgt, ___, ___)                   \
-  V(JumpIfNoAsserts,                       T, tgt, ___, ___)                   \
-  V(JumpIfNotZeroTypeArgs,                 T, tgt, ___, ___)                   \
-  V(JumpIfEqStrict,                        T, tgt, ___, ___)                   \
-  V(JumpIfNeStrict,                        T, tgt, ___, ___)                   \
-  V(JumpIfTrue,                            T, tgt, ___, ___)                   \
-  V(JumpIfFalse,                           T, tgt, ___, ___)                   \
-  V(JumpIfNull,                            T, tgt, ___, ___)                   \
-  V(JumpIfNotNull,                         T, tgt, ___, ___)                   \
-  V(IndirectStaticCall,                  A_D, num, num, ___)                   \
-  V(InterfaceCall,                       A_D, num, num, ___)                   \
-  V(DynamicCall,                         A_D, num, num, ___)                   \
-  V(NativeCall,                            D, lit, ___, ___)                   \
-  V(ReturnTOS,                             0, ___, ___, ___)                   \
-  V(AssertAssignable,                    A_D, num, lit, ___)                   \
-  V(AssertBoolean,                         A, num, ___, ___)                   \
-  V(AssertSubtype,                         0, ___, ___, ___)                   \
-  V(LoadTypeArgumentsField,                D, lit, ___, ___)                   \
-  V(InstantiateType,                       D, lit, ___, ___)                   \
-  V(InstantiateTypeArgumentsTOS,         A_D, num, lit, ___)                   \
-  V(Throw,                                 A, num, ___, ___)                   \
-  V(MoveSpecial,                         A_X, num, xeg, ___)                   \
-  V(SetFrame,                              A, num, ___, num)                   \
-  V(BooleanNegateTOS,                      0, ___, ___, ___)                   \
-  V(EqualsNull,                            0, ___, ___, ___)                   \
-  V(NegateInt,                             0, ___, ___, ___)                   \
-  V(AddInt,                                0, ___, ___, ___)                   \
-  V(SubInt,                                0, ___, ___, ___)                   \
-  V(MulInt,                                0, ___, ___, ___)                   \
-  V(TruncDivInt,                           0, ___, ___, ___)                   \
-  V(ModInt,                                0, ___, ___, ___)                   \
-  V(BitAndInt,                             0, ___, ___, ___)                   \
-  V(BitOrInt,                              0, ___, ___, ___)                   \
-  V(BitXorInt,                             0, ___, ___, ___)                   \
-  V(ShlInt,                                0, ___, ___, ___)                   \
-  V(ShrInt,                                0, ___, ___, ___)                   \
-  V(CompareIntEq,                          0, ___, ___, ___)                   \
-  V(CompareIntGt,                          0, ___, ___, ___)                   \
-  V(CompareIntLt,                          0, ___, ___, ___)                   \
-  V(CompareIntGe,                          0, ___, ___, ___)                   \
-  V(CompareIntLe,                          0, ___, ___, ___)                   \
-  V(DirectCall,                          A_D, num, num, ___)                   \
-  V(AllocateClosure,                       D, lit, ___, ___)                   \
-  V(UncheckedInterfaceCall,              A_D, num, num, ___)                   \
-  V(NegateDouble,                          0, ___, ___, ___)                   \
-  V(AddDouble,                             0, ___, ___, ___)                   \
-  V(SubDouble,                             0, ___, ___, ___)                   \
-  V(MulDouble,                             0, ___, ___, ___)                   \
-  V(DivDouble,                             0, ___, ___, ___)                   \
-  V(CompareDoubleEq,                       0, ___, ___, ___)                   \
-  V(CompareDoubleGt,                       0, ___, ___, ___)                   \
-  V(CompareDoubleLt,                       0, ___, ___, ___)                   \
-  V(CompareDoubleGe,                       0, ___, ___, ___)                   \
-  V(CompareDoubleLe,                       0, ___, ___, ___)                   \
+  V(Trap_Old,                              0,  OLD, ___, ___, ___)             \
+  V(Entry_Old,                             D,  OLD, num, ___, ___)             \
+  V(EntryFixed_Old,                      A_D,  OLD, num, num, ___)             \
+  V(EntryOptional_Old,                 A_B_C,  OLD, num, num, num)             \
+  V(LoadConstant_Old,                    A_D,  OLD, reg, lit, ___)             \
+  V(Frame_Old,                             D,  OLD, num, ___, ___)             \
+  V(CheckFunctionTypeArgs_Old,           A_D,  OLD, num, reg, ___)             \
+  V(CheckStack_Old,                        A,  OLD, num, ___, ___)             \
+  V(Allocate_Old,                          D,  OLD, lit, ___, ___)             \
+  V(AllocateT_Old,                         0,  OLD, ___, ___, ___)             \
+  V(CreateArrayTOS_Old,                    0,  OLD, ___, ___, ___)             \
+  V(AllocateContext_Old,                   D,  OLD, num, ___, ___)             \
+  V(CloneContext_Old,                      D,  OLD, num, ___, ___)             \
+  V(LoadContextParent_Old,                 0,  OLD, ___, ___, ___)             \
+  V(StoreContextParent_Old,                0,  OLD, ___, ___, ___)             \
+  V(LoadContextVar_Old,                    D,  OLD, num, ___, ___)             \
+  V(StoreContextVar_Old,                   D,  OLD, num, ___, ___)             \
+  V(PushConstant_Old,                      D,  OLD, lit, ___, ___)             \
+  V(PushNull_Old,                          0,  OLD, ___, ___, ___)             \
+  V(PushTrue_Old,                          0,  OLD, ___, ___, ___)             \
+  V(PushFalse_Old,                         0,  OLD, ___, ___, ___)             \
+  V(PushInt_Old,                           X,  OLD, num, ___, ___)             \
+  V(Drop1_Old,                             0,  OLD, ___, ___, ___)             \
+  V(Push_Old,                              X,  OLD, xeg, ___, ___)             \
+  V(PopLocal_Old,                          X,  OLD, xeg, ___, ___)             \
+  V(StoreLocal_Old,                        X,  OLD, xeg, ___, ___)             \
+  V(LoadFieldTOS_Old,                      D,  OLD, lit, ___, ___)             \
+  V(StoreFieldTOS_Old,                     D,  OLD, lit, ___, ___)             \
+  V(StoreIndexedTOS_Old,                   0,  OLD, ___, ___, ___)             \
+  V(PushStatic_Old,                        D,  OLD, lit, ___, ___)             \
+  V(StoreStaticTOS_Old,                    D,  OLD, lit, ___, ___)             \
+  V(Jump_Old,                              T,  OLD, tgt, ___, ___)             \
+  V(JumpIfNoAsserts_Old,                   T,  OLD, tgt, ___, ___)             \
+  V(JumpIfNotZeroTypeArgs_Old,             T,  OLD, tgt, ___, ___)             \
+  V(JumpIfEqStrict_Old,                    T,  OLD, tgt, ___, ___)             \
+  V(JumpIfNeStrict_Old,                    T,  OLD, tgt, ___, ___)             \
+  V(JumpIfTrue_Old,                        T,  OLD, tgt, ___, ___)             \
+  V(JumpIfFalse_Old,                       T,  OLD, tgt, ___, ___)             \
+  V(JumpIfNull_Old,                        T,  OLD, tgt, ___, ___)             \
+  V(JumpIfNotNull_Old,                     T,  OLD, tgt, ___, ___)             \
+  V(Unused00_Old,                          0, RESV, num, num, ___)             \
+  V(InterfaceCall_Old,                   A_D,  OLD, num, num, ___)             \
+  V(DynamicCall_Old,                     A_D,  OLD, num, num, ___)             \
+  V(NativeCall_Old,                        D,  OLD, lit, ___, ___)             \
+  V(ReturnTOS_Old,                         0,  OLD, ___, ___, ___)             \
+  V(AssertAssignable_Old,                A_D,  OLD, num, lit, ___)             \
+  V(AssertBoolean_Old,                     A,  OLD, num, ___, ___)             \
+  V(AssertSubtype_Old,                     0,  OLD, ___, ___, ___)             \
+  V(LoadTypeArgumentsField_Old,            D,  OLD, lit, ___, ___)             \
+  V(InstantiateType_Old,                   D,  OLD, lit, ___, ___)             \
+  V(InstantiateTypeArgumentsTOS_Old,     A_D,  OLD, num, lit, ___)             \
+  V(Throw_Old,                             A,  OLD, num, ___, ___)             \
+  V(MoveSpecial_Old,                     A_X,  OLD, num, xeg, ___)             \
+  V(SetFrame_Old,                          A,  OLD, num, ___, num)             \
+  V(BooleanNegateTOS_Old,                  0,  OLD, ___, ___, ___)             \
+  V(EqualsNull_Old,                        0,  OLD, ___, ___, ___)             \
+  V(NegateInt_Old,                         0,  OLD, ___, ___, ___)             \
+  V(AddInt_Old,                            0,  OLD, ___, ___, ___)             \
+  V(SubInt_Old,                            0,  OLD, ___, ___, ___)             \
+  V(MulInt_Old,                            0,  OLD, ___, ___, ___)             \
+  V(TruncDivInt_Old,                       0,  OLD, ___, ___, ___)             \
+  V(ModInt_Old,                            0,  OLD, ___, ___, ___)             \
+  V(BitAndInt_Old,                         0,  OLD, ___, ___, ___)             \
+  V(BitOrInt_Old,                          0,  OLD, ___, ___, ___)             \
+  V(BitXorInt_Old,                         0,  OLD, ___, ___, ___)             \
+  V(ShlInt_Old,                            0,  OLD, ___, ___, ___)             \
+  V(ShrInt_Old,                            0,  OLD, ___, ___, ___)             \
+  V(CompareIntEq_Old,                      0,  OLD, ___, ___, ___)             \
+  V(CompareIntGt_Old,                      0,  OLD, ___, ___, ___)             \
+  V(CompareIntLt_Old,                      0,  OLD, ___, ___, ___)             \
+  V(CompareIntGe_Old,                      0,  OLD, ___, ___, ___)             \
+  V(CompareIntLe_Old,                      0,  OLD, ___, ___, ___)             \
+  V(DirectCall_Old,                      A_D,  OLD, num, num, ___)             \
+  V(AllocateClosure_Old,                   D,  OLD, lit, ___, ___)             \
+  V(UncheckedInterfaceCall_Old,          A_D,  OLD, num, num, ___)             \
+  V(NegateDouble_Old,                      0,  OLD, ___, ___, ___)             \
+  V(AddDouble_Old,                         0,  OLD, ___, ___, ___)             \
+  V(SubDouble_Old,                         0,  OLD, ___, ___, ___)             \
+  V(MulDouble_Old,                         0,  OLD, ___, ___, ___)             \
+  V(DivDouble_Old,                         0,  OLD, ___, ___, ___)             \
+  V(CompareDoubleEq_Old,                   0,  OLD, ___, ___, ___)             \
+  V(CompareDoubleGt_Old,                   0,  OLD, ___, ___, ___)             \
+  V(CompareDoubleLt_Old,                   0,  OLD, ___, ___, ___)             \
+  V(CompareDoubleGe_Old,                   0,  OLD, ___, ___, ___)             \
+  V(CompareDoubleLe_Old,                   0,  OLD, ___, ___, ___)             \
+  V(Trap,                                  0, ORDN, ___, ___, ___)             \
+  V(Entry,                                 D, ORDN, num, ___, ___)             \
+  V(Entry_Wide,                            D, WIDE, num, ___, ___)             \
+  V(EntryFixed,                          A_E, ORDN, num, num, ___)             \
+  V(EntryFixed_Wide,                     A_E, WIDE, num, num, ___)             \
+  V(EntryOptional,                     A_B_C, ORDN, num, num, num)             \
+  V(Unused00,                              0, RESV, ___, ___, ___)             \
+  V(LoadConstant,                        A_E, ORDN, reg, lit, ___)             \
+  V(LoadConstant_Wide,                   A_E, WIDE, reg, lit, ___)             \
+  V(Frame,                                 D, ORDN, num, ___, ___)             \
+  V(Frame_Wide,                            D, WIDE, num, ___, ___)             \
+  V(CheckFunctionTypeArgs,               A_E, ORDN, num, reg, ___)             \
+  V(CheckFunctionTypeArgs_Wide,          A_E, WIDE, num, reg, ___)             \
+  V(CheckStack,                            A, ORDN, num, ___, ___)             \
+  V(Unused01,                              0, RESV, ___, ___, ___)             \
+  V(Unused02,                              0, RESV, ___, ___, ___)             \
+  V(Unused03,                              0, RESV, ___, ___, ___)             \
+  V(Allocate,                              D, ORDN, lit, ___, ___)             \
+  V(Allocate_Wide,                         D, WIDE, lit, ___, ___)             \
+  V(AllocateT,                             0, ORDN, ___, ___, ___)             \
+  V(CreateArrayTOS,                        0, ORDN, ___, ___, ___)             \
+  V(AllocateClosure,                       D, ORDN, lit, ___, ___)             \
+  V(AllocateClosure_Wide,                  D, WIDE, lit, ___, ___)             \
+  V(AllocateContext,                     A_E, ORDN, num, ___, ___)             \
+  V(AllocateContext_Wide,                A_E, WIDE, num, ___, ___)             \
+  V(CloneContext,                        A_E, ORDN, num, ___, ___)             \
+  V(CloneContext_Wide,                   A_E, WIDE, num, ___, ___)             \
+  V(LoadContextParent,                     0, ORDN, ___, ___, ___)             \
+  V(StoreContextParent,                    0, ORDN, ___, ___, ___)             \
+  V(LoadContextVar,                      A_E, ORDN, num, ___, ___)             \
+  V(LoadContextVar_Wide,                 A_E, WIDE, num, ___, ___)             \
+  V(Unused04,                              0, RESV, ___, ___, ___)             \
+  V(Unused05,                              0, RESV, ___, ___, ___)             \
+  V(StoreContextVar,                     A_E, ORDN, num, ___, ___)             \
+  V(StoreContextVar_Wide,                A_E, WIDE, num, ___, ___)             \
+  V(PushConstant,                          D, ORDN, lit, ___, ___)             \
+  V(PushConstant_Wide,                     D, WIDE, lit, ___, ___)             \
+  V(Unused06,                              0, RESV, ___, ___, ___)             \
+  V(Unused07,                              0, RESV, ___, ___, ___)             \
+  V(PushTrue,                              0, ORDN, ___, ___, ___)             \
+  V(PushFalse,                             0, ORDN, ___, ___, ___)             \
+  V(PushInt,                               X, ORDN, num, ___, ___)             \
+  V(PushInt_Wide,                          X, WIDE, num, ___, ___)             \
+  V(Unused08,                              0, RESV, ___, ___, ___)             \
+  V(Unused09,                              0, RESV, ___, ___, ___)             \
+  V(Unused10,                              0, RESV, ___, ___, ___)             \
+  V(Unused11,                              0, RESV, ___, ___, ___)             \
+  V(PushNull,                              0, ORDN, ___, ___, ___)             \
+  V(Drop1,                                 0, ORDN, ___, ___, ___)             \
+  V(Push,                                  X, ORDN, xeg, ___, ___)             \
+  V(Push_Wide,                             X, WIDE, xeg, ___, ___)             \
+  V(Unused12,                              0, RESV, ___, ___, ___)             \
+  V(Unused13,                              0, RESV, ___, ___, ___)             \
+  V(Unused14,                              0, RESV, ___, ___, ___)             \
+  V(Unused15,                              0, RESV, ___, ___, ___)             \
+  V(Unused16,                              0, RESV, ___, ___, ___)             \
+  V(Unused17,                              0, RESV, ___, ___, ___)             \
+  V(PopLocal,                              X, ORDN, xeg, ___, ___)             \
+  V(PopLocal_Wide,                         X, WIDE, xeg, ___, ___)             \
+  V(Unused18,                              0, RESV, ___, ___, ___)             \
+  V(Unused19,                              0, RESV, ___, ___, ___)             \
+  V(StoreLocal,                            X, ORDN, xeg, ___, ___)             \
+  V(StoreLocal_Wide,                       X, WIDE, xeg, ___, ___)             \
+  V(LoadFieldTOS,                          D, ORDN, lit, ___, ___)             \
+  V(LoadFieldTOS_Wide,                     D, WIDE, lit, ___, ___)             \
+  V(StoreFieldTOS,                         D, ORDN, lit, ___, ___)             \
+  V(StoreFieldTOS_Wide,                    D, WIDE, lit, ___, ___)             \
+  V(StoreIndexedTOS,                       0, ORDN, ___, ___, ___)             \
+  V(Unused20,                              0, RESV, ___, ___, ___)             \
+  V(PushStatic,                            D, ORDN, lit, ___, ___)             \
+  V(PushStatic_Wide,                       D, WIDE, lit, ___, ___)             \
+  V(StoreStaticTOS,                        D, ORDN, lit, ___, ___)             \
+  V(StoreStaticTOS_Wide,                   D, WIDE, lit, ___, ___)             \
+  V(Jump,                                  T, ORDN, tgt, ___, ___)             \
+  V(Jump_Wide,                             T, WIDE, tgt, ___, ___)             \
+  V(JumpIfNoAsserts,                       T, ORDN, tgt, ___, ___)             \
+  V(JumpIfNoAsserts_Wide,                  T, WIDE, tgt, ___, ___)             \
+  V(JumpIfNotZeroTypeArgs,                 T, ORDN, tgt, ___, ___)             \
+  V(JumpIfNotZeroTypeArgs_Wide,            T, WIDE, tgt, ___, ___)             \
+  V(JumpIfEqStrict,                        T, ORDN, tgt, ___, ___)             \
+  V(JumpIfEqStrict_Wide,                   T, WIDE, tgt, ___, ___)             \
+  V(JumpIfNeStrict,                        T, ORDN, tgt, ___, ___)             \
+  V(JumpIfNeStrict_Wide,                   T, WIDE, tgt, ___, ___)             \
+  V(JumpIfTrue,                            T, ORDN, tgt, ___, ___)             \
+  V(JumpIfTrue_Wide,                       T, WIDE, tgt, ___, ___)             \
+  V(JumpIfFalse,                           T, ORDN, tgt, ___, ___)             \
+  V(JumpIfFalse_Wide,                      T, WIDE, tgt, ___, ___)             \
+  V(JumpIfNull,                            T, ORDN, tgt, ___, ___)             \
+  V(JumpIfNull_Wide,                       T, WIDE, tgt, ___, ___)             \
+  V(JumpIfNotNull,                         T, ORDN, tgt, ___, ___)             \
+  V(JumpIfNotNull_Wide,                    T, WIDE, tgt, ___, ___)             \
+  V(DirectCall,                          D_F, ORDN, num, num, ___)             \
+  V(DirectCall_Wide,                     D_F, WIDE, num, num, ___)             \
+  V(Unused21,                              0, RESV, ___, ___, ___)             \
+  V(Unused22,                              0, RESV, ___, ___, ___)             \
+  V(InterfaceCall,                       D_F, ORDN, num, num, ___)             \
+  V(InterfaceCall_Wide,                  D_F, WIDE, num, num, ___)             \
+  V(Unused23,                              0, RESV, ___, ___, ___)             \
+  V(Unused24,                              0, RESV, ___, ___, ___)             \
+  V(Unused25,                              0, RESV, ___, ___, ___)             \
+  V(Unused26,                              0, RESV, ___, ___, ___)             \
+  V(Unused27,                              0, RESV, ___, ___, ___)             \
+  V(Unused28,                              0, RESV, ___, ___, ___)             \
+  V(UncheckedInterfaceCall,              D_F, ORDN, num, num, ___)             \
+  V(UncheckedInterfaceCall_Wide,         D_F, WIDE, num, num, ___)             \
+  V(DynamicCall,                         D_F, ORDN, num, num, ___)             \
+  V(DynamicCall_Wide,                    D_F, WIDE, num, num, ___)             \
+  V(NativeCall,                            D, ORDN, lit, ___, ___)             \
+  V(NativeCall_Wide,                       D, WIDE, lit, ___, ___)             \
+  V(ReturnTOS,                             0, ORDN, ___, ___, ___)             \
+  V(Unused29,                              0, RESV, ___, ___, ___)             \
+  V(AssertAssignable,                    A_E, ORDN, num, lit, ___)             \
+  V(AssertAssignable_Wide,               A_E, WIDE, num, lit, ___)             \
+  V(Unused30,                              0, RESV, ___, ___, ___)             \
+  V(Unused31,                              0, RESV, ___, ___, ___)             \
+  V(AssertBoolean,                         A, ORDN, num, ___, ___)             \
+  V(AssertSubtype,                         0, ORDN, ___, ___, ___)             \
+  V(LoadTypeArgumentsField,                D, ORDN, lit, ___, ___)             \
+  V(LoadTypeArgumentsField_Wide,           D, WIDE, lit, ___, ___)             \
+  V(InstantiateType,                       D, ORDN, lit, ___, ___)             \
+  V(InstantiateType_Wide,                  D, WIDE, lit, ___, ___)             \
+  V(InstantiateTypeArgumentsTOS,         A_E, ORDN, num, lit, ___)             \
+  V(InstantiateTypeArgumentsTOS_Wide,    A_E, WIDE, num, lit, ___)             \
+  V(Unused32,                              0, RESV, ___, ___, ___)             \
+  V(Unused33,                              0, RESV, ___, ___, ___)             \
+  V(Unused34,                              0, RESV, ___, ___, ___)             \
+  V(Unused35,                              0, RESV, ___, ___, ___)             \
+  V(Throw,                                 A, ORDN, num, ___, ___)             \
+  V(SetFrame,                              A, ORDN, num, ___, num)             \
+  V(MoveSpecial,                         A_Y, ORDN, num, xeg, ___)             \
+  V(MoveSpecial_Wide,                    A_Y, WIDE, num, xeg, ___)             \
+  V(BooleanNegateTOS,                      0, ORDN, ___, ___, ___)             \
+  V(EqualsNull,                            0, ORDN, ___, ___, ___)             \
+  V(Unused36,                              0, RESV, ___, ___, ___)             \
+  V(Unused37,                              0, RESV, ___, ___, ___)             \
+  V(NegateInt,                             0, ORDN, ___, ___, ___)             \
+  V(AddInt,                                0, ORDN, ___, ___, ___)             \
+  V(SubInt,                                0, ORDN, ___, ___, ___)             \
+  V(MulInt,                                0, ORDN, ___, ___, ___)             \
+  V(TruncDivInt,                           0, ORDN, ___, ___, ___)             \
+  V(ModInt,                                0, ORDN, ___, ___, ___)             \
+  V(BitAndInt,                             0, ORDN, ___, ___, ___)             \
+  V(BitOrInt,                              0, ORDN, ___, ___, ___)             \
+  V(BitXorInt,                             0, ORDN, ___, ___, ___)             \
+  V(ShlInt,                                0, ORDN, ___, ___, ___)             \
+  V(ShrInt,                                0, ORDN, ___, ___, ___)             \
+  V(CompareIntEq,                          0, ORDN, ___, ___, ___)             \
+  V(CompareIntGt,                          0, ORDN, ___, ___, ___)             \
+  V(CompareIntLt,                          0, ORDN, ___, ___, ___)             \
+  V(CompareIntGe,                          0, ORDN, ___, ___, ___)             \
+  V(CompareIntLe,                          0, ORDN, ___, ___, ___)             \
+  V(NegateDouble,                          0, ORDN, ___, ___, ___)             \
+  V(AddDouble,                             0, ORDN, ___, ___, ___)             \
+  V(SubDouble,                             0, ORDN, ___, ___, ___)             \
+  V(MulDouble,                             0, ORDN, ___, ___, ___)             \
+  V(DivDouble,                             0, ORDN, ___, ___, ___)             \
+  V(CompareDoubleEq,                       0, ORDN, ___, ___, ___)             \
+  V(CompareDoubleGt,                       0, ORDN, ___, ___, ___)             \
+  V(CompareDoubleLt,                       0, ORDN, ___, ___, ___)             \
+  V(CompareDoubleGe,                       0, ORDN, ___, ___, ___)             \
+  V(CompareDoubleLe,                       0, ORDN, ___, ___, ___)             \
 
   // These bytecodes are only generated within the VM. Reassigning their
   // opcodes is not a breaking change.
 #define INTERNAL_KERNEL_BYTECODES_LIST(V)                                      \
-  V(VMInternal_ImplicitGetter,             0, ___, ___, ___)                   \
-  V(VMInternal_ImplicitSetter,             0, ___, ___, ___)                   \
-  V(VMInternal_ImplicitStaticGetter,       0, ___, ___, ___)                   \
-  V(VMInternal_MethodExtractor,            0, ___, ___, ___)                   \
-  V(VMInternal_InvokeClosure,              0, ___, ___, ___)                   \
-  V(VMInternal_InvokeField,                0, ___, ___, ___)                   \
-  V(VMInternal_ForwardDynamicInvocation,   0, ___, ___, ___)                   \
-  V(VMInternal_NoSuchMethodDispatcher,     0, ___, ___, ___)                   \
-  V(VMInternal_ImplicitStaticClosure,      0, ___, ___, ___)                   \
-  V(VMInternal_ImplicitInstanceClosure,    0, ___, ___, ___)                   \
+  V(VMInternal_ImplicitGetter,             0, ORDN, ___, ___, ___)             \
+  V(VMInternal_ImplicitSetter,             0, ORDN, ___, ___, ___)             \
+  V(VMInternal_ImplicitStaticGetter,       0, ORDN, ___, ___, ___)             \
+  V(VMInternal_MethodExtractor,            0, ORDN, ___, ___, ___)             \
+  V(VMInternal_InvokeClosure,              0, ORDN, ___, ___, ___)             \
+  V(VMInternal_InvokeField,                0, ORDN, ___, ___, ___)             \
+  V(VMInternal_ForwardDynamicInvocation,   0, ORDN, ___, ___, ___)             \
+  V(VMInternal_NoSuchMethodDispatcher,     0, ORDN, ___, ___, ___)             \
+  V(VMInternal_ImplicitStaticClosure,      0, ORDN, ___, ___, ___)             \
+  V(VMInternal_ImplicitInstanceClosure,    0, ORDN, ___, ___, ___)             \
 
 #define KERNEL_BYTECODES_LIST(V)                                               \
   PUBLIC_KERNEL_BYTECODES_LIST(V)                                              \
@@ -548,122 +738,180 @@
 
 // clang-format on
 
-typedef uint32_t KBCInstr;
+typedef uint8_t KBCInstr;
 
 class KernelBytecode {
  public:
   // Magic value of bytecode files.
   static const intptr_t kMagicValue = 0x44424332;  // 'DBC2'
   // Minimum bytecode format version supported by VM.
-  static const intptr_t kMinSupportedBytecodeFormatVersion = 2;
+  static const intptr_t kMinSupportedBytecodeFormatVersion = 3;
   // 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 = 6;
+  static const intptr_t kMaxSupportedBytecodeFormatVersion = 7;
 
   enum Opcode {
-#define DECLARE_BYTECODE(name, encoding, op1, op2, op3) k##name,
+#define DECLARE_BYTECODE(name, encoding, kind, op1, op2, op3) k##name,
     KERNEL_BYTECODES_LIST(DECLARE_BYTECODE)
 #undef DECLARE_BYTECODE
   };
 
-  static const char* NameOf(KBCInstr instr) {
+  static const char* NameOf(Opcode op) {
     const char* names[] = {
-#define NAME(name, encoding, op1, op2, op3) #name,
+#define NAME(name, encoding, kind, op1, op2, op3) #name,
         KERNEL_BYTECODES_LIST(NAME)
 #undef NAME
     };
-    return names[DecodeOpcode(instr)];
+    return names[op];
   }
 
+  static const intptr_t kInstructionSize[];
+
   enum SpecialIndex {
     kExceptionSpecialIndex,
     kStackTraceSpecialIndex,
     kSpecialIndexCount
   };
 
-  static const intptr_t kOpShift = 0;
-  static const intptr_t kAShift = 8;
-  static const intptr_t kAMask = 0xFF;
-  static const intptr_t kBShift = 16;
-  static const intptr_t kBMask = 0xFF;
-  static const intptr_t kCShift = 24;
-  static const intptr_t kCMask = 0xFF;
-  static const intptr_t kDShift = 16;
-  static const intptr_t kDMask = 0xFFFF;
-  static const intptr_t kYShift = 24;
-  static const intptr_t kYMask = 0xFF;
-  static const intptr_t kTShift = 8;
+ private:
+  static const intptr_t kWideModifier = 1;
 
-  static KBCInstr Encode(Opcode op, uintptr_t a, uintptr_t b, uintptr_t c) {
-    ASSERT((a & kAMask) == a);
-    ASSERT((b & kBMask) == b);
-    ASSERT((c & kCMask) == c);
-    return op | (a << kAShift) | (b << kBShift) | (c << kCShift);
+  static_assert(kMinSupportedBytecodeFormatVersion < 7,
+                "Cleanup support for old bytecode format versions");
+  DART_FORCE_INLINE static bool IsOld(const KBCInstr* instr) {
+    return DecodeOpcode(instr) < kTrap;
   }
 
-  static KBCInstr Encode(Opcode op, uintptr_t a, uintptr_t d) {
-    ASSERT((a & kAMask) == a);
-    ASSERT((d & kDMask) == d);
-    return op | (a << kAShift) | (d << kDShift);
+  // Should be used only on instructions with wide variants.
+  DART_FORCE_INLINE static bool IsWide(const KBCInstr* instr) {
+    return ((DecodeOpcode(instr) & kWideModifier) != 0);
   }
 
-  static KBCInstr EncodeSigned(Opcode op, uintptr_t a, intptr_t x) {
-    ASSERT((a & kAMask) == a);
-    ASSERT((x << kDShift) >> kDShift == x);
-    return op | (a << kAShift) | (x << kDShift);
+ public:
+  DART_FORCE_INLINE static uint8_t DecodeA(const KBCInstr* bc) { return bc[1]; }
+
+  DART_FORCE_INLINE static uint8_t DecodeB(const KBCInstr* bc) { return bc[2]; }
+
+  DART_FORCE_INLINE static uint8_t DecodeC(const KBCInstr* bc) { return bc[3]; }
+
+  DART_FORCE_INLINE static uint32_t DecodeD(const KBCInstr* bc) {
+    if (IsOld(bc)) {
+      return static_cast<uint16_t>(bc[2]) | (static_cast<uint16_t>(bc[3]) << 8);
+    } else if (IsWide(bc)) {
+      return static_cast<uint32_t>(bc[1]) |
+             (static_cast<uint32_t>(bc[2]) << 8) |
+             (static_cast<uint32_t>(bc[3]) << 16) |
+             (static_cast<uint32_t>(bc[4]) << 24);
+    } else {
+      return bc[1];
+    }
   }
 
-  static KBCInstr EncodeSigned(Opcode op, intptr_t x) {
-    ASSERT((x << kAShift) >> kAShift == x);
-    return op | (x << kAShift);
+  DART_FORCE_INLINE static int32_t DecodeX(const KBCInstr* bc) {
+    if (IsOld(bc)) {
+      return static_cast<int16_t>(static_cast<uint16_t>(bc[2]) |
+                                  (static_cast<uint16_t>(bc[3]) << 8));
+    } else if (IsWide(bc)) {
+      return static_cast<int32_t>(static_cast<uint32_t>(bc[1]) |
+                                  (static_cast<uint32_t>(bc[2]) << 8) |
+                                  (static_cast<uint32_t>(bc[3]) << 16) |
+                                  (static_cast<uint32_t>(bc[4]) << 24));
+    } else {
+      return static_cast<int8_t>(bc[1]);
+    }
   }
 
-  static KBCInstr Encode(Opcode op) { return op; }
-
-  DART_FORCE_INLINE static uint8_t DecodeA(KBCInstr bc) {
-    return (bc >> kAShift) & kAMask;
+  DART_FORCE_INLINE static int32_t DecodeT(const KBCInstr* bc) {
+    if (IsOld(bc)) {
+      return static_cast<int32_t>((static_cast<uint32_t>(bc[1]) << 8) |
+                                  (static_cast<uint32_t>(bc[2]) << 16) |
+                                  (static_cast<uint32_t>(bc[3]) << 24)) >>
+             (8 - 2);
+    } else if (IsWide(bc)) {
+      return static_cast<int32_t>((static_cast<uint32_t>(bc[1]) << 8) |
+                                  (static_cast<uint32_t>(bc[2]) << 16) |
+                                  (static_cast<uint32_t>(bc[3]) << 24)) >>
+             8;
+    } else {
+      return static_cast<int8_t>(bc[1]);
+    }
   }
 
-  DART_FORCE_INLINE static uint8_t DecodeB(KBCInstr bc) {
-    return (bc >> kBShift) & kBMask;
+  DART_FORCE_INLINE static uint32_t DecodeE(const KBCInstr* bc) {
+    if (IsOld(bc)) {
+      return static_cast<uint16_t>(bc[2]) | (static_cast<uint16_t>(bc[3]) << 8);
+    } else if (IsWide(bc)) {
+      return static_cast<uint32_t>(bc[2]) |
+             (static_cast<uint32_t>(bc[3]) << 8) |
+             (static_cast<uint32_t>(bc[4]) << 16) |
+             (static_cast<uint32_t>(bc[5]) << 24);
+    } else {
+      return bc[2];
+    }
   }
 
-  DART_FORCE_INLINE static uint8_t DecodeC(KBCInstr bc) {
-    return (bc >> kCShift) & kCMask;
+  DART_FORCE_INLINE static int32_t DecodeY(const KBCInstr* bc) {
+    if (IsOld(bc)) {
+      return static_cast<int16_t>(static_cast<uint16_t>(bc[2]) |
+                                  (static_cast<uint16_t>(bc[3]) << 8));
+    } else if (IsWide(bc)) {
+      return static_cast<int32_t>(static_cast<uint32_t>(bc[2]) |
+                                  (static_cast<uint32_t>(bc[3]) << 8) |
+                                  (static_cast<uint32_t>(bc[4]) << 16) |
+                                  (static_cast<uint32_t>(bc[5]) << 24));
+    } else {
+      return static_cast<int8_t>(bc[2]);
+    }
   }
 
-  DART_FORCE_INLINE static uint16_t DecodeD(KBCInstr bc) {
-    return (bc >> kDShift) & kDMask;
+  DART_FORCE_INLINE static uint8_t DecodeF(const KBCInstr* bc) {
+    if (IsOld(bc)) {
+      return bc[1];
+    } else if (IsWide(bc)) {
+      return bc[5];
+    } else {
+      return bc[2];
+    }
   }
 
-  DART_FORCE_INLINE static int16_t DecodeX(KBCInstr bc) {
-    return static_cast<int16_t>((bc >> kDShift) & kDMask);
+  DART_FORCE_INLINE static Opcode DecodeOpcode(const KBCInstr* bc) {
+    return static_cast<Opcode>(bc[0]);
   }
 
-  DART_FORCE_INLINE static int32_t DecodeT(KBCInstr bc) {
-    return static_cast<int32_t>(bc) >> kTShift;
+  DART_FORCE_INLINE static const KBCInstr* Next(const KBCInstr* bc) {
+    return bc + kInstructionSize[DecodeOpcode(bc)];
   }
 
-  DART_FORCE_INLINE static Opcode DecodeOpcode(KBCInstr bc) {
-    return static_cast<Opcode>(bc & 0xFF);
-  }
-
-  DART_FORCE_INLINE static bool IsTrap(KBCInstr instr) {
-    return DecodeOpcode(instr) == KernelBytecode::kTrap;
-  }
-
-  DART_FORCE_INLINE static bool IsJumpOpcode(KBCInstr instr) {
+  DART_FORCE_INLINE static bool IsJumpOpcode(const KBCInstr* instr) {
     switch (DecodeOpcode(instr)) {
+      case KernelBytecode::kJump_Old:
+      case KernelBytecode::kJumpIfNoAsserts_Old:
+      case KernelBytecode::kJumpIfNotZeroTypeArgs_Old:
+      case KernelBytecode::kJumpIfEqStrict_Old:
+      case KernelBytecode::kJumpIfNeStrict_Old:
+      case KernelBytecode::kJumpIfTrue_Old:
+      case KernelBytecode::kJumpIfFalse_Old:
+      case KernelBytecode::kJumpIfNull_Old:
+      case KernelBytecode::kJumpIfNotNull_Old:
       case KernelBytecode::kJump:
+      case KernelBytecode::kJump_Wide:
       case KernelBytecode::kJumpIfNoAsserts:
+      case KernelBytecode::kJumpIfNoAsserts_Wide:
       case KernelBytecode::kJumpIfNotZeroTypeArgs:
+      case KernelBytecode::kJumpIfNotZeroTypeArgs_Wide:
       case KernelBytecode::kJumpIfEqStrict:
+      case KernelBytecode::kJumpIfEqStrict_Wide:
       case KernelBytecode::kJumpIfNeStrict:
+      case KernelBytecode::kJumpIfNeStrict_Wide:
       case KernelBytecode::kJumpIfTrue:
+      case KernelBytecode::kJumpIfTrue_Wide:
       case KernelBytecode::kJumpIfFalse:
+      case KernelBytecode::kJumpIfFalse_Wide:
       case KernelBytecode::kJumpIfNull:
+      case KernelBytecode::kJumpIfNull_Wide:
       case KernelBytecode::kJumpIfNotNull:
+      case KernelBytecode::kJumpIfNotNull_Wide:
         return true;
 
       default:
@@ -671,13 +919,72 @@
     }
   }
 
-  DART_FORCE_INLINE static bool IsCallOpcode(KBCInstr instr) {
+  DART_FORCE_INLINE static bool IsLoadConstantOpcode(const KBCInstr* instr) {
     switch (DecodeOpcode(instr)) {
-      case KernelBytecode::kIndirectStaticCall:
-      case KernelBytecode::kInterfaceCall:
-      case KernelBytecode::kUncheckedInterfaceCall:
-      case KernelBytecode::kDynamicCall:
+      case KernelBytecode::kLoadConstant:
+      case KernelBytecode::kLoadConstant_Wide:
+      case KernelBytecode::kLoadConstant_Old:
+        return true;
+      default:
+        return false;
+    }
+  }
+
+  DART_FORCE_INLINE static bool IsCheckStackOpcode(const KBCInstr* instr) {
+    switch (DecodeOpcode(instr)) {
+      case KernelBytecode::kCheckStack:
+      case KernelBytecode::kCheckStack_Old:
+        return true;
+      default:
+        return false;
+    }
+  }
+
+  DART_FORCE_INLINE static bool IsEntryOptionalOpcode(const KBCInstr* instr) {
+    switch (DecodeOpcode(instr)) {
+      case KernelBytecode::kEntryOptional:
+      case KernelBytecode::kEntryOptional_Old:
+        return true;
+      default:
+        return false;
+    }
+  }
+
+  DART_FORCE_INLINE static bool IsFrameOpcode(const KBCInstr* instr) {
+    switch (DecodeOpcode(instr)) {
+      case KernelBytecode::kFrame:
+      case KernelBytecode::kFrame_Wide:
+      case KernelBytecode::kFrame_Old:
+        return true;
+      default:
+        return false;
+    }
+  }
+
+  DART_FORCE_INLINE static bool IsSetFrameOpcode(const KBCInstr* instr) {
+    switch (DecodeOpcode(instr)) {
+      case KernelBytecode::kSetFrame:
+      case KernelBytecode::kSetFrame_Old:
+        return true;
+      default:
+        return false;
+    }
+  }
+
+  DART_FORCE_INLINE static bool IsCallOpcode(const KBCInstr* instr) {
+    switch (DecodeOpcode(instr)) {
+      case KernelBytecode::kDirectCall_Old:
+      case KernelBytecode::kInterfaceCall_Old:
+      case KernelBytecode::kUncheckedInterfaceCall_Old:
+      case KernelBytecode::kDynamicCall_Old:
       case KernelBytecode::kDirectCall:
+      case KernelBytecode::kDirectCall_Wide:
+      case KernelBytecode::kInterfaceCall:
+      case KernelBytecode::kInterfaceCall_Wide:
+      case KernelBytecode::kUncheckedInterfaceCall:
+      case KernelBytecode::kUncheckedInterfaceCall_Wide:
+      case KernelBytecode::kDynamicCall:
+      case KernelBytecode::kDynamicCall_Wide:
         return true;
 
       default:
@@ -685,31 +992,56 @@
     }
   }
 
+  DART_FORCE_INLINE static bool IsNativeCallOpcode(const KBCInstr* instr) {
+    switch (DecodeOpcode(instr)) {
+      case KernelBytecode::kNativeCall:
+      case KernelBytecode::kNativeCall_Wide:
+      case KernelBytecode::kNativeCall_Old:
+        return true;
+      default:
+        return false;
+    }
+  }
+
   static const uint8_t kNativeCallToGrowableListArgc = 2;
 
-  DART_FORCE_INLINE static uint8_t DecodeArgc(KBCInstr call) {
-    if (DecodeOpcode(call) == KernelBytecode::kNativeCall) {
+  DART_FORCE_INLINE static uint8_t DecodeArgc_Old(const KBCInstr* ret_addr) {
+    const intptr_t kOldInstructionSize = 4;
+    const KBCInstr* call = ret_addr - kOldInstructionSize;
+    ASSERT(IsOld(call));
+    if (DecodeOpcode(call) == KernelBytecode::kNativeCall_Old) {
       // The only NativeCall redirecting to a bytecode function is the call
       // to new _GrowableList<E>(0).
       return kNativeCallToGrowableListArgc;
     }
     ASSERT(IsCallOpcode(call));
-    return (call >> 8) & 0xFF;
+    return DecodeA(call);
   }
 
-  static KBCInstr At(uword pc) { return *reinterpret_cast<KBCInstr*>(pc); }
+  // Returns a fake return address which points after the 2-argument
+  // bytecode call, followed by ReturnTOS instructions.
+  static const KBCInstr* GetNativeCallToGrowableListReturnTrampoline();
+
+  DART_FORCE_INLINE static uint8_t DecodeArgc(const KBCInstr* ret_addr) {
+    // All call instructions have DF encoding, with argc being the last byte
+    // regardless of whether the wide variant is used or not.
+    return ret_addr[-1];
+  }
 
   // Converts bytecode PC into an offset.
-  // For return addresses used in PcDescriptors, PC is also advanced to the
-  // next instruction.
+  // For return addresses used in PcDescriptors, PC is also augmented by 1.
   static intptr_t BytecodePcToOffset(uint32_t pc, bool is_return_address) {
-    return sizeof(KBCInstr) * (pc + (is_return_address ? 1 : 0));
+    return pc + (is_return_address ? 1 : 0);
   }
 
   static uint32_t OffsetToBytecodePc(intptr_t offset, bool is_return_address) {
-    return (offset / sizeof(KBCInstr)) - (is_return_address ? 1 : 0);
+    return offset - (is_return_address ? 1 : 0);
   }
 
+  static void GetVMInternalBytecodeInstructions(Opcode opcode,
+                                                const KBCInstr** instructions,
+                                                intptr_t* instructions_size);
+
  private:
   DISALLOW_ALLOCATION();
   DISALLOW_IMPLICIT_CONSTRUCTORS(KernelBytecode);
diff --git a/runtime/vm/constants_x64.h b/runtime/vm/constants_x64.h
index f6eb461..29a871a 100644
--- a/runtime/vm/constants_x64.h
+++ b/runtime/vm/constants_x64.h
@@ -264,6 +264,7 @@
   static constexpr Register kFirstCalleeSavedCpuReg = RBX;
   static constexpr Register kFirstNonArgumentRegister = RAX;
   static constexpr Register kSecondNonArgumentRegister = RBX;
+  static constexpr Register kStackPointerRegister = SPREG;
 
   COMPILE_ASSERT(((R(kFirstCalleeSavedCpuReg)) & kCalleeSaveCpuRegisters) != 0);
 
diff --git a/runtime/vm/dart_api_impl.h b/runtime/vm/dart_api_impl.h
index f2cd2e8..ca74fa7 100644
--- a/runtime/vm/dart_api_impl.h
+++ b/runtime/vm/dart_api_impl.h
@@ -297,8 +297,15 @@
 
   static bool IsFfiEnabled() {
     // dart:ffi is not implemented for the following configurations
-#if defined(TARGET_ARCH_DBC)
-    // https://github.com/dart-lang/sdk/issues/35773 DBC
+#if defined(TARGET_ARCH_DBC) && !defined(ARCH_IS_64_BIT)
+    // TODO(36809): Support SimDBC32.
+    return false;
+#elif defined(TARGET_ARCH_DBC) && !defined(HOST_ARCH_X64)
+    // TODO(35773): Support ia32, arm64, and arm.
+    return false;
+#elif defined(TARGET_ARCH_DBC) && defined(HOST_ARCH_X64) &&                    \
+    defined(HOST_OS_WINDOWS)
+    // TODO(35773): Support x64 Windows.
     return false;
 #elif defined(TARGET_ARCH_ARM) &&                                              \
     !(defined(TARGET_OS_ANDROID) || defined(TARGET_OS_MACOS_IOS))
diff --git a/runtime/vm/exceptions.cc b/runtime/vm/exceptions.cc
index 4acc536..73a41f0 100644
--- a/runtime/vm/exceptions.cc
+++ b/runtime/vm/exceptions.cc
@@ -159,7 +159,7 @@
   // Iterate through the stack frames and try to find a frame with an
   // exception handler. Once found, set the pc, sp and fp so that execution
   // can continue in that frame. Sets 'needs_stacktrace' if there is no
-  // cath-all handler or if a stack-trace is specified in the catch.
+  // catch-all handler or if a stack-trace is specified in the catch.
   bool Find() {
     StackFrameIterator frames(ValidationPolicy::kDontValidateFrames,
                               Thread::Current(),
@@ -670,6 +670,15 @@
   DEBUG_ASSERT(thread->TopErrorHandlerIsExitFrame());
   Zone* zone = thread->zone();
   Isolate* isolate = thread->isolate();
+#if !defined(PRODUCT)
+  // Do not notify debugger on stack overflow and out of memory exceptions.
+  // The VM would crash when the debugger calls back into the VM to
+  // get values of variables.
+  if (incoming_exception.raw() != isolate->object_store()->out_of_memory() &&
+      incoming_exception.raw() != isolate->object_store()->stack_overflow()) {
+    isolate->debugger()->PauseException(incoming_exception);
+  }
+#endif
   bool use_preallocated_stacktrace = false;
   Instance& exception = Instance::Handle(zone, incoming_exception.raw());
   if (exception.IsNull()) {
@@ -880,16 +889,6 @@
 }
 
 void Exceptions::Throw(Thread* thread, const Instance& exception) {
-  // Do not notify debugger on stack overflow and out of memory exceptions.
-  // The VM would crash when the debugger calls back into the VM to
-  // get values of variables.
-#if !defined(PRODUCT)
-  Isolate* isolate = thread->isolate();
-  if (exception.raw() != isolate->object_store()->out_of_memory() &&
-      exception.raw() != isolate->object_store()->stack_overflow()) {
-    isolate->debugger()->PauseException(exception);
-  }
-#endif
   // Null object is a valid exception object.
   ThrowExceptionHelper(thread, exception, StackTrace::Handle(thread->zone()),
                        false);
diff --git a/runtime/vm/globals.h b/runtime/vm/globals.h
index ad33a42..7336f1f 100644
--- a/runtime/vm/globals.h
+++ b/runtime/vm/globals.h
@@ -161,6 +161,17 @@
 
 #endif  // !defined(HOST_OS_WINDOWS))
 
+#if defined(TARGET_ARCH_ARM) || defined(TARGET_ARCH_ARM64) ||                  \
+    defined(TARGET_ARCH_X64)
+#define TARGET_USES_OBJECT_POOL 1
+#endif
+
+#if defined(DART_PRECOMPILER) &&                                               \
+    (defined(TARGET_ARCH_X64) || defined(TARGET_ARCH_ARM) ||                   \
+     defined(TARGET_ARCH_ARM64))
+#define DART_SUPPORT_PRECOMPILATION 1
+#endif
+
 }  // namespace dart
 
 #endif  // RUNTIME_VM_GLOBALS_H_
diff --git a/runtime/vm/heap/freelist.cc b/runtime/vm/heap/freelist.cc
index 9c2aca1..c98af37 100644
--- a/runtime/vm/heap/freelist.cc
+++ b/runtime/vm/heap/freelist.cc
@@ -55,22 +55,20 @@
 }
 
 FreeList::FreeList()
-    : mutex_(new Mutex()),
-      freelist_search_budget_(kInitialFreeListSearchBudget) {
+    : mutex_(), freelist_search_budget_(kInitialFreeListSearchBudget) {
   Reset();
 }
 
 FreeList::~FreeList() {
-  delete mutex_;
 }
 
 uword FreeList::TryAllocate(intptr_t size, bool is_protected) {
-  MutexLocker ml(mutex_);
+  MutexLocker ml(&mutex_);
   return TryAllocateLocked(size, is_protected);
 }
 
 uword FreeList::TryAllocateLocked(intptr_t size, bool is_protected) {
-  DEBUG_ASSERT(mutex_->IsOwnedByCurrentThread());
+  DEBUG_ASSERT(mutex_.IsOwnedByCurrentThread());
   // Precondition: is_protected is false or else all free list elements are
   // in non-writable pages.
 
@@ -176,12 +174,12 @@
 }
 
 void FreeList::Free(uword addr, intptr_t size) {
-  MutexLocker ml(mutex_);
+  MutexLocker ml(&mutex_);
   FreeLocked(addr, size);
 }
 
 void FreeList::FreeLocked(uword addr, intptr_t size) {
-  DEBUG_ASSERT(mutex_->IsOwnedByCurrentThread());
+  DEBUG_ASSERT(mutex_.IsOwnedByCurrentThread());
   // Precondition required by AsElement and EnqueueElement: the (page
   // containing the) header of the freed block should be writable.  This is
   // the case when called for newly allocated pages because they are
@@ -194,7 +192,7 @@
 }
 
 void FreeList::Reset() {
-  MutexLocker ml(mutex_);
+  MutexLocker ml(&mutex_);
   free_map_.Reset();
   last_free_small_size_ = -1;
   for (int i = 0; i < (kNumLists + 1); i++) {
@@ -214,7 +212,7 @@
 }
 
 intptr_t FreeList::LengthLocked(int index) const {
-  DEBUG_ASSERT(mutex_->IsOwnedByCurrentThread());
+  DEBUG_ASSERT(mutex_.IsOwnedByCurrentThread());
   ASSERT(index >= 0);
   ASSERT(index < kNumLists);
   intptr_t result = 0;
@@ -306,7 +304,7 @@
 }
 
 void FreeList::Print() const {
-  MutexLocker ml(mutex_);
+  MutexLocker ml(&mutex_);
   PrintSmall();
   PrintLarge();
 }
@@ -337,12 +335,12 @@
 }
 
 FreeListElement* FreeList::TryAllocateLarge(intptr_t minimum_size) {
-  MutexLocker ml(mutex_);
+  MutexLocker ml(&mutex_);
   return TryAllocateLargeLocked(minimum_size);
 }
 
 FreeListElement* FreeList::TryAllocateLargeLocked(intptr_t minimum_size) {
-  DEBUG_ASSERT(mutex_->IsOwnedByCurrentThread());
+  DEBUG_ASSERT(mutex_.IsOwnedByCurrentThread());
   FreeListElement* previous = NULL;
   FreeListElement* current = free_lists_[kNumLists];
   // TODO(koda): Find largest.
diff --git a/runtime/vm/heap/freelist.h b/runtime/vm/heap/freelist.h
index 171ff1c..9fac19d 100644
--- a/runtime/vm/heap/freelist.h
+++ b/runtime/vm/heap/freelist.h
@@ -86,7 +86,7 @@
 
   void Print() const;
 
-  Mutex* mutex() { return mutex_; }
+  Mutex* mutex() { return &mutex_; }
   uword TryAllocateLocked(intptr_t size, bool is_protected);
   void FreeLocked(uword addr, intptr_t size);
 
@@ -97,7 +97,7 @@
   // Allocates locked and unprotected memory, but only from small elements
   // (i.e., fixed size lists).
   uword TryAllocateSmallLocked(intptr_t size) {
-    DEBUG_ASSERT(mutex_->IsOwnedByCurrentThread());
+    DEBUG_ASSERT(mutex_.IsOwnedByCurrentThread());
     if (size > last_free_small_size_) {
       return 0;
     }
@@ -159,7 +159,7 @@
   void PrintLarge() const;
 
   // Lock protecting the free list data structures.
-  Mutex* mutex_;
+  mutable Mutex mutex_;
 
   BitSet<kNumLists> free_map_;
 
diff --git a/runtime/vm/heap/heap.cc b/runtime/vm/heap/heap.cc
index 10f20bb..2a53317 100644
--- a/runtime/vm/heap/heap.cc
+++ b/runtime/vm/heap/heap.cc
@@ -39,8 +39,8 @@
     : isolate_(isolate),
       new_space_(this, max_new_gen_semi_words, kNewObjectAlignmentOffset),
       old_space_(this, max_old_gen_words),
-      barrier_(new Monitor()),
-      barrier_done_(new Monitor()),
+      barrier_(),
+      barrier_done_(),
       read_only_(false),
       gc_new_space_in_progress_(false),
       gc_old_space_in_progress_(false) {
@@ -53,9 +53,6 @@
 }
 
 Heap::~Heap() {
-  delete barrier_;
-  delete barrier_done_;
-
   for (int sel = 0; sel < kNumWeakSelectors; sel++) {
     delete new_weak_tables_[sel];
     delete old_weak_tables_[sel];
diff --git a/runtime/vm/heap/heap.h b/runtime/vm/heap/heap.h
index 628ab15..837f2c9 100644
--- a/runtime/vm/heap/heap.h
+++ b/runtime/vm/heap/heap.h
@@ -284,8 +284,8 @@
 
   Isolate* isolate() const { return isolate_; }
 
-  Monitor* barrier() const { return barrier_; }
-  Monitor* barrier_done() const { return barrier_done_; }
+  Monitor* barrier() const { return &barrier_; }
+  Monitor* barrier_done() const { return &barrier_done_; }
 
   void SetupImagePage(void* pointer, uword size, bool is_executable) {
     old_space_.SetupImagePage(pointer, size, is_executable);
@@ -382,8 +382,8 @@
   WeakTable* new_weak_tables_[kNumWeakSelectors];
   WeakTable* old_weak_tables_[kNumWeakSelectors];
 
-  Monitor* barrier_;
-  Monitor* barrier_done_;
+  mutable Monitor barrier_;
+  mutable Monitor barrier_done_;
 
   // GC stats collection.
   GCStats stats_;
diff --git a/runtime/vm/heap/pages.cc b/runtime/vm/heap/pages.cc
index 4f0b6fc..23c83dd 100644
--- a/runtime/vm/heap/pages.cc
+++ b/runtime/vm/heap/pages.cc
@@ -225,7 +225,7 @@
 PageSpace::PageSpace(Heap* heap, intptr_t max_capacity_in_words)
     : freelist_(),
       heap_(heap),
-      pages_lock_(new Mutex()),
+      pages_lock_(),
       pages_(NULL),
       pages_tail_(NULL),
       exec_pages_(NULL),
@@ -237,7 +237,7 @@
       max_capacity_in_words_(max_capacity_in_words),
       usage_(),
       allocated_black_in_words_(0),
-      tasks_lock_(new Monitor()),
+      tasks_lock_(),
       tasks_(0),
       concurrent_marker_tasks_(0),
       phase_(kDone),
@@ -269,8 +269,6 @@
   FreePages(exec_pages_);
   FreePages(large_pages_);
   FreePages(image_pages_);
-  delete pages_lock_;
-  delete tasks_lock_;
   ASSERT(marker_ == NULL);
 }
 
@@ -282,7 +280,7 @@
 
 HeapPage* PageSpace::AllocatePage(HeapPage::PageType type, bool link) {
   {
-    MutexLocker ml(pages_lock_);
+    MutexLocker ml(&pages_lock_);
     if (!CanIncreaseCapacityInWordsLocked(kPageSizeInWords)) {
       return NULL;
     }
@@ -300,7 +298,7 @@
     return NULL;
   }
 
-  MutexLocker ml(pages_lock_);
+  MutexLocker ml(&pages_lock_);
   if (link) {
     if (!is_exec) {
       if (pages_ == NULL) {
@@ -336,7 +334,7 @@
 HeapPage* PageSpace::AllocateLargePage(intptr_t size, HeapPage::PageType type) {
   const intptr_t page_size_in_words = LargePageSizeInWordsFor(size);
   {
-    MutexLocker ml(pages_lock_);
+    MutexLocker ml(&pages_lock_);
     if (!CanIncreaseCapacityInWordsLocked(page_size_in_words)) {
       return NULL;
     }
@@ -379,7 +377,7 @@
 void PageSpace::FreePage(HeapPage* page, HeapPage* previous_page) {
   bool is_exec = (page->type() == HeapPage::kExecutable);
   {
-    MutexLocker ml(pages_lock_);
+    MutexLocker ml(&pages_lock_);
     IncreaseCapacityInWordsLocked(-(page->memory_->size() >> kWordSizeLog2));
     if (!is_exec) {
       // Remove the page from the list of data pages.
@@ -553,7 +551,7 @@
 class ExclusivePageIterator : ValueObject {
  public:
   explicit ExclusivePageIterator(const PageSpace* space)
-      : space_(space), ml_(space->pages_lock_) {
+      : space_(space), ml_(&space->pages_lock_) {
     space_->MakeIterable();
     list_ = kRegular;
     page_ = space_->pages_;
@@ -605,7 +603,7 @@
 class ExclusiveCodePageIterator : ValueObject {
  public:
   explicit ExclusiveCodePageIterator(const PageSpace* space)
-      : space_(space), ml_(space->pages_lock_) {
+      : space_(space), ml_(&space->pages_lock_) {
     space_->MakeIterable();
     page_ = space_->exec_pages_;
   }
@@ -627,7 +625,7 @@
 class ExclusiveLargePageIterator : ValueObject {
  public:
   explicit ExclusiveLargePageIterator(const PageSpace* space)
-      : space_(space), ml_(space->pages_lock_) {
+      : space_(space), ml_(&space->pages_lock_) {
     space_->MakeIterable();
     page_ = space_->large_pages_;
   }
@@ -884,7 +882,7 @@
     // {"object_start": "0x...", "objects": [size, class id, size, ...]}
     // TODO(19445): Use ExclusivePageIterator once HeapMap supports large pages.
     HeapIterationScope iteration(Thread::Current());
-    MutexLocker ml(pages_lock_);
+    MutexLocker ml(&pages_lock_);
     MakeIterable();
     JSONArray all_pages(&heap_map, "pages");
     for (HeapPage* page = pages_; page != NULL; page = page->next()) {
@@ -909,7 +907,7 @@
 
 void PageSpace::WriteProtectCode(bool read_only) {
   if (FLAG_write_protect_code) {
-    MutexLocker ml(pages_lock_);
+    MutexLocker ml(&pages_lock_);
     NoSafepointScope no_safepoint;
     // No need to go through all of the data pages first.
     HeapPage* page = exec_pages_;
@@ -1236,7 +1234,7 @@
 void PageSpace::Compact(Thread* thread) {
   thread->isolate()->set_compaction_in_progress(true);
   GCCompactor compactor(thread, heap_);
-  compactor.Compact(pages_, &freelist_[HeapPage::kData], pages_lock_);
+  compactor.Compact(pages_, &freelist_[HeapPage::kData], &pages_lock_);
   thread->isolate()->set_compaction_in_progress(false);
 
   if (FLAG_verify_after_gc) {
@@ -1330,7 +1328,7 @@
     page->type_ = HeapPage::kData;
   }
 
-  MutexLocker ml(pages_lock_);
+  MutexLocker ml(&pages_lock_);
   page->next_ = image_pages_;
   image_pages_ = page;
 }
diff --git a/runtime/vm/heap/pages.h b/runtime/vm/heap/pages.h
index c1608af..6eb1e32 100644
--- a/runtime/vm/heap/pages.h
+++ b/runtime/vm/heap/pages.h
@@ -298,15 +298,15 @@
 
   int64_t UsedInWords() const { return usage_.used_in_words; }
   int64_t CapacityInWords() const {
-    MutexLocker ml(pages_lock_);
+    MutexLocker ml(&pages_lock_);
     return usage_.capacity_in_words;
   }
   void IncreaseCapacityInWords(intptr_t increase_in_words) {
-    MutexLocker ml(pages_lock_);
+    MutexLocker ml(&pages_lock_);
     IncreaseCapacityInWordsLocked(increase_in_words);
   }
   void IncreaseCapacityInWordsLocked(intptr_t increase_in_words) {
-    DEBUG_ASSERT(pages_lock_->IsOwnedByCurrentThread());
+    DEBUG_ASSERT(pages_lock_.IsOwnedByCurrentThread());
     usage_.capacity_in_words += increase_in_words;
     UpdateMaxCapacityLocked();
   }
@@ -316,7 +316,7 @@
 
   int64_t ExternalInWords() const { return usage_.external_in_words; }
   SpaceUsage GetCurrentUsage() const {
-    MutexLocker ml(pages_lock_);
+    MutexLocker ml(&pages_lock_);
     return usage_;
   }
 
@@ -399,7 +399,7 @@
                                is_protected, is_locked);
   }
 
-  Monitor* tasks_lock() const { return tasks_lock_; }
+  Monitor* tasks_lock() const { return &tasks_lock_; }
   intptr_t tasks() const { return tasks_; }
   void set_tasks(intptr_t val) {
     ASSERT(val >= 0);
@@ -495,7 +495,7 @@
   Heap* heap_;
 
   // Use ExclusivePageIterator for safe access to these.
-  Mutex* pages_lock_;
+  mutable Mutex pages_lock_;
   HeapPage* pages_;
   HeapPage* pages_tail_;
   HeapPage* exec_pages_;
@@ -517,7 +517,7 @@
   intptr_t allocated_black_in_words_;
 
   // Keep track of running MarkSweep tasks.
-  Monitor* tasks_lock_;
+  mutable Monitor tasks_lock_;
   intptr_t tasks_;
   intptr_t concurrent_marker_tasks_;
   Phase phase_;
diff --git a/runtime/vm/heap/pointer_block.cc b/runtime/vm/heap/pointer_block.cc
index 52b4563..19428f7 100644
--- a/runtime/vm/heap/pointer_block.cc
+++ b/runtime/vm/heap/pointer_block.cc
@@ -41,17 +41,16 @@
 }
 
 template <int BlockSize>
-BlockStack<BlockSize>::BlockStack() : mutex_(new Mutex()) {}
+BlockStack<BlockSize>::BlockStack() : mutex_() {}
 
 template <int BlockSize>
 BlockStack<BlockSize>::~BlockStack() {
   Reset();
-  delete mutex_;
 }
 
 template <int BlockSize>
 void BlockStack<BlockSize>::Reset() {
-  MutexLocker local_mutex_locker(mutex_);
+  MutexLocker local_mutex_locker(&mutex_);
   {
     // Empty all blocks and move them to the global cache.
     MutexLocker global_mutex_locker(global_mutex_);
@@ -71,7 +70,7 @@
 
 template <int BlockSize>
 typename BlockStack<BlockSize>::Block* BlockStack<BlockSize>::Blocks() {
-  MutexLocker ml(mutex_);
+  MutexLocker ml(&mutex_);
   while (!partial_.IsEmpty()) {
     full_.Push(partial_.Pop());
   }
@@ -82,14 +81,14 @@
 void BlockStack<BlockSize>::PushBlockImpl(Block* block) {
   ASSERT(block->next() == NULL);  // Should be just a single block.
   if (block->IsFull()) {
-    MutexLocker ml(mutex_);
+    MutexLocker ml(&mutex_);
     full_.Push(block);
   } else if (block->IsEmpty()) {
     MutexLocker ml(global_mutex_);
     global_empty_->Push(block);
     TrimGlobalEmpty();
   } else {
-    MutexLocker ml(mutex_);
+    MutexLocker ml(&mutex_);
     partial_.Push(block);
   }
 }
@@ -104,7 +103,7 @@
 void StoreBuffer::PushBlock(Block* block, ThresholdPolicy policy) {
   BlockStack<Block::kSize>::PushBlockImpl(block);
   if ((policy == kCheckThreshold) && Overflowed()) {
-    MutexLocker ml(mutex_);
+    MutexLocker ml(&mutex_);
     Thread* thread = Thread::Current();
     // Sanity check: it makes no sense to schedule the GC in another isolate.
     // (If Isolate ever gets multiple store buffers, we should avoid this
@@ -118,7 +117,7 @@
 typename BlockStack<BlockSize>::Block*
 BlockStack<BlockSize>::PopNonFullBlock() {
   {
-    MutexLocker ml(mutex_);
+    MutexLocker ml(&mutex_);
     if (!partial_.IsEmpty()) {
       return partial_.Pop();
     }
@@ -140,7 +139,7 @@
 template <int BlockSize>
 typename BlockStack<BlockSize>::Block*
 BlockStack<BlockSize>::PopNonEmptyBlock() {
-  MutexLocker ml(mutex_);
+  MutexLocker ml(&mutex_);
   if (!full_.IsEmpty()) {
     return full_.Pop();
   } else if (!partial_.IsEmpty()) {
@@ -152,7 +151,7 @@
 
 template <int BlockSize>
 bool BlockStack<BlockSize>::IsEmpty() {
-  MutexLocker ml(mutex_);
+  MutexLocker ml(&mutex_);
   return full_.IsEmpty() && partial_.IsEmpty();
 }
 
@@ -189,7 +188,7 @@
 }
 
 bool StoreBuffer::Overflowed() {
-  MutexLocker ml(mutex_);
+  MutexLocker ml(&mutex_);
   return (full_.length() + partial_.length()) > kMaxNonEmpty;
 }
 
diff --git a/runtime/vm/heap/pointer_block.h b/runtime/vm/heap/pointer_block.h
index 609ea97..e9ace07 100644
--- a/runtime/vm/heap/pointer_block.h
+++ b/runtime/vm/heap/pointer_block.h
@@ -7,12 +7,12 @@
 
 #include "platform/assert.h"
 #include "vm/globals.h"
+#include "vm/os_thread.h"
 
 namespace dart {
 
 // Forward declarations.
 class Isolate;
-class Mutex;
 class RawObject;
 class ObjectPointerVisitor;
 
@@ -131,7 +131,7 @@
 
   List full_;
   List partial_;
-  Mutex* mutex_;
+  Mutex mutex_;
 
   // Note: This is shared on the basis of block size.
   static const intptr_t kMaxGlobalEmpty = 100;
diff --git a/runtime/vm/heap/safepoint.cc b/runtime/vm/heap/safepoint.cc
index c231b9c..3888cdf 100644
--- a/runtime/vm/heap/safepoint.cc
+++ b/runtime/vm/heap/safepoint.cc
@@ -39,7 +39,7 @@
 
 SafepointHandler::SafepointHandler(Isolate* isolate)
     : isolate_(isolate),
-      safepoint_lock_(new Monitor()),
+      safepoint_lock_(),
       number_threads_not_at_safepoint_(0),
       safepoint_operation_count_(0),
       owner_(NULL) {}
@@ -47,8 +47,6 @@
 SafepointHandler::~SafepointHandler() {
   ASSERT(owner_ == NULL);
   ASSERT(safepoint_operation_count_ == 0);
-  delete safepoint_lock_;
-  safepoint_lock_ = NULL;
   isolate_ = NULL;
 }
 
@@ -96,7 +94,7 @@
               ASSERT(T->isolate() != NULL);
               current->ScheduleInterruptsLocked(Thread::kVMInterrupt);
             }
-            MonitorLocker sl(safepoint_lock_);
+            MonitorLocker sl(&safepoint_lock_);
             ++number_threads_not_at_safepoint_;
           }
         }
@@ -106,7 +104,7 @@
   }
   // Now wait for all threads that are not already at a safepoint to check-in.
   {
-    MonitorLocker sl(safepoint_lock_);
+    MonitorLocker sl(&safepoint_lock_);
     intptr_t num_attempts = 0;
     while (number_threads_not_at_safepoint_ > 0) {
       Monitor::WaitResult retval = sl.Wait(1000);
@@ -161,7 +159,7 @@
   MonitorLocker tl(T->thread_lock());
   T->SetAtSafepoint(true);
   if (T->IsSafepointRequested()) {
-    MonitorLocker sl(safepoint_lock_);
+    MonitorLocker sl(&safepoint_lock_);
     ASSERT(number_threads_not_at_safepoint_ > 0);
     number_threads_not_at_safepoint_ -= 1;
     sl.Notify();
@@ -185,7 +183,7 @@
   if (T->IsSafepointRequested()) {
     T->SetAtSafepoint(true);
     {
-      MonitorLocker sl(safepoint_lock_);
+      MonitorLocker sl(&safepoint_lock_);
       ASSERT(number_threads_not_at_safepoint_ > 0);
       number_threads_not_at_safepoint_ -= 1;
       sl.Notify();
diff --git a/runtime/vm/heap/safepoint.h b/runtime/vm/heap/safepoint.h
index ce84f85..906933a 100644
--- a/runtime/vm/heap/safepoint.h
+++ b/runtime/vm/heap/safepoint.h
@@ -78,7 +78,7 @@
 
   // Monitor used by thread initiating a safepoint operation to track threads
   // not at a safepoint and wait for these threads to reach a safepoint.
-  Monitor* safepoint_lock_;
+  Monitor safepoint_lock_;
   int32_t number_threads_not_at_safepoint_;
 
   // Count that indicates if a safepoint operation is currently in progress
diff --git a/runtime/vm/instructions_kbc.cc b/runtime/vm/instructions_kbc.cc
index f6d9f61..a8a3608 100644
--- a/runtime/vm/instructions_kbc.cc
+++ b/runtime/vm/instructions_kbc.cc
@@ -17,11 +17,22 @@
     uword pc,
     const Bytecode& bytecode) {
   ASSERT(bytecode.ContainsInstructionAt(pc));
-  const uword call_pc = pc - sizeof(KBCInstr);
-  KBCInstr call_instr = KernelBytecode::At(call_pc);
-  ASSERT(KernelBytecode::DecodeOpcode(call_instr) ==
-         KernelBytecode::kNativeCall);
-  intptr_t native_entry_data_pool_index = KernelBytecode::DecodeD(call_instr);
+
+  const KBCInstr* return_addr = reinterpret_cast<const KBCInstr*>(pc);
+  const KBCInstr* instr =
+      reinterpret_cast<const KBCInstr*>(bytecode.PayloadStart());
+  ASSERT(instr < return_addr);
+  while (!KernelBytecode::IsNativeCallOpcode(instr)) {
+    instr = KernelBytecode::Next(instr);
+    if (instr >= return_addr) {
+      FATAL1(
+          "Unable to find NativeCall bytecode instruction"
+          " corresponding to PC %" Px,
+          pc);
+    }
+  }
+
+  intptr_t native_entry_data_pool_index = KernelBytecode::DecodeD(instr);
   const ObjectPool& obj_pool = ObjectPool::Handle(bytecode.object_pool());
   TypedData& native_entry_data = TypedData::Handle();
   native_entry_data ^= obj_pool.ObjectAt(native_entry_data_pool_index);
diff --git a/runtime/vm/interpreter.cc b/runtime/vm/interpreter.cc
index 5069504..a0ba01e 100644
--- a/runtime/vm/interpreter.cc
+++ b/runtime/vm/interpreter.cc
@@ -12,6 +12,7 @@
 
 #include "vm/compiler/assembler/assembler.h"
 #include "vm/compiler/assembler/disassembler_kbc.h"
+#include "vm/compiler/frontend/bytecode_reader.h"
 #include "vm/compiler/jit/compiler.h"
 #include "vm/cpu.h"
 #include "vm/dart_entry.h"
@@ -229,8 +230,8 @@
   }
 };
 
-DART_FORCE_INLINE static uint32_t* SavedCallerPC(RawObject** FP) {
-  return reinterpret_cast<uint32_t*>(FP[kKBCSavedCallerPcSlotFromFp]);
+DART_FORCE_INLINE static const KBCInstr* SavedCallerPC(RawObject** FP) {
+  return reinterpret_cast<const KBCInstr*>(FP[kKBCSavedCallerPcSlotFromFp]);
 }
 
 DART_FORCE_INLINE static RawFunction* FrameFunction(RawObject** FP) {
@@ -396,11 +397,12 @@
 }
 
 // Prints bytecode instruction at given pc for instruction tracing.
-DART_NOINLINE void Interpreter::TraceInstruction(uint32_t* pc) const {
+DART_NOINLINE void Interpreter::TraceInstruction(const KBCInstr* pc) const {
   THR_Print("%" Pu64 " ", icount_);
   if (FLAG_support_disassembler) {
-    KernelBytecodeDisassembler::Disassemble(reinterpret_cast<uword>(pc),
-                                            reinterpret_cast<uword>(pc + 1));
+    KernelBytecodeDisassembler::Disassemble(
+        reinterpret_cast<uword>(pc),
+        reinterpret_cast<uword>(KernelBytecode::Next(pc)));
   } else {
     THR_Print("Disassembler not supported in this mode.\n");
   }
@@ -430,13 +432,15 @@
   trace_buffer_idx_ = 0;
 }
 
-DART_NOINLINE void Interpreter::WriteInstructionToTrace(uint32_t* pc) {
+DART_NOINLINE void Interpreter::WriteInstructionToTrace(const KBCInstr* pc) {
   Dart_FileWriteCallback file_write = Dart::file_write_callback();
   if (file_write == NULL) {
     return;
   }
-  if (trace_buffer_idx_ < kTraceBufferInstrs) {
-    trace_buffer_[trace_buffer_idx_++] = static_cast<KBCInstr>(*pc);
+  const KBCInstr* next = KernelBytecode::Next(pc);
+  while ((trace_buffer_idx_ < kTraceBufferInstrs) && (pc != next)) {
+    trace_buffer_[trace_buffer_idx_++] = *pc;
+    ++pc;
   }
   if (trace_buffer_idx_ == kTraceBufferInstrs) {
     FlushTraceBuffer();
@@ -460,10 +464,10 @@
 void Interpreter::Exit(Thread* thread,
                        RawObject** base,
                        RawObject** frame,
-                       uint32_t* pc) {
+                       const KBCInstr* pc) {
   frame[0] = Function::null();
   frame[1] = Bytecode::null();
-  frame[2] = reinterpret_cast<RawObject*>(pc);
+  frame[2] = reinterpret_cast<RawObject*>(reinterpret_cast<uword>(pc));
   frame[3] = reinterpret_cast<RawObject*>(base);
 
   RawObject** exit_fp = frame + kKBCDartFrameFixedSize;
@@ -534,7 +538,7 @@
                                                RawFunction* function,
                                                RawObject** call_base,
                                                RawObject** call_top,
-                                               uint32_t** pc,
+                                               const KBCInstr** pc,
                                                RawObject*** FP,
                                                RawObject*** SP) {
   ASSERT(Function::HasCode(function));
@@ -619,7 +623,7 @@
                                                    RawFunction* function,
                                                    RawObject** call_base,
                                                    RawObject** call_top,
-                                                   uint32_t** pc,
+                                                   const KBCInstr** pc,
                                                    RawObject*** FP,
                                                    RawObject*** SP) {
   ASSERT(Function::HasBytecode(function));
@@ -634,10 +638,11 @@
   ASSERT(function == FrameFunction(callee_fp));
   RawBytecode* bytecode = function->ptr()->bytecode_;
   callee_fp[kKBCPcMarkerSlotFromFp] = bytecode;
-  callee_fp[kKBCSavedCallerPcSlotFromFp] = reinterpret_cast<RawObject*>(*pc);
+  callee_fp[kKBCSavedCallerPcSlotFromFp] =
+      reinterpret_cast<RawObject*>(reinterpret_cast<uword>(*pc));
   callee_fp[kKBCSavedCallerFpSlotFromFp] = reinterpret_cast<RawObject*>(*FP);
   pp_ = bytecode->ptr()->object_pool_;
-  *pc = reinterpret_cast<uint32_t*>(bytecode->ptr()->instructions_);
+  *pc = reinterpret_cast<const KBCInstr*>(bytecode->ptr()->instructions_);
   NOT_IN_PRODUCT(pc_ = *pc);  // For the profiler.
   *FP = callee_fp;
   NOT_IN_PRODUCT(fp_ = callee_fp);  // For the profiler.
@@ -648,7 +653,7 @@
 DART_FORCE_INLINE bool Interpreter::Invoke(Thread* thread,
                                            RawObject** call_base,
                                            RawObject** call_top,
-                                           uint32_t** pc,
+                                           const KBCInstr** pc,
                                            RawObject*** FP,
                                            RawObject*** SP) {
   RawObject** callee_fp = call_top + kKBCDartFrameFixedSize;
@@ -682,7 +687,7 @@
                                   RawICData* icdata,
                                   RawObject** args,
                                   RawObject** top,
-                                  uint32_t* pc,
+                                  const KBCInstr* pc,
                                   RawObject** FP,
                                   RawObject** SP) {
   RawObject** result = top;
@@ -725,7 +730,7 @@
                                                   RawString* target_name,
                                                   RawObject** call_base,
                                                   RawObject** top,
-                                                  uint32_t** pc,
+                                                  const KBCInstr** pc,
                                                   RawObject*** FP,
                                                   RawObject*** SP) {
   const intptr_t type_args_len =
@@ -738,6 +743,7 @@
   RawFunction* target;
   if (UNLIKELY(!lookup_cache_.Lookup(receiver_cid, target_name, &target))) {
     // Table lookup miss.
+    top[0] = 0;  // Clean up slot as it may be visited by GC.
     top[1] = call_base[receiver_idx];
     top[2] = target_name;
     top[3] = argdesc_;
@@ -766,7 +772,7 @@
                                                   RawICData* icdata,
                                                   RawObject** call_base,
                                                   RawObject** top,
-                                                  uint32_t** pc,
+                                                  const KBCInstr** pc,
                                                   RawObject*** FP,
                                                   RawObject*** SP,
                                                   bool optimized) {
@@ -787,7 +793,7 @@
   intptr_t i;
   for (i = 0; i < (length - (kCheckedArgs + 2)); i += (kCheckedArgs + 2)) {
     if (cache->data()[i + 0] == receiver_cid) {
-      top[0] = cache->data()[i + kCheckedArgs];
+      top[0] = cache->data()[i + ICData::TargetIndexFor(kCheckedArgs)];
       found = true;
       break;
     }
@@ -811,7 +817,7 @@
                                                   RawICData* icdata,
                                                   RawObject** call_base,
                                                   RawObject** top,
-                                                  uint32_t** pc,
+                                                  const KBCInstr** pc,
                                                   RawObject*** FP,
                                                   RawObject*** SP,
                                                   bool optimized) {
@@ -835,7 +841,7 @@
   for (i = 0; i < (length - (kCheckedArgs + 2)); i += (kCheckedArgs + 2)) {
     if ((cache->data()[i + 0] == receiver_cid) &&
         (cache->data()[i + 1] == arg0_cid)) {
-      top[0] = cache->data()[i + kCheckedArgs];
+      top[0] = cache->data()[i + ICData::TargetIndexFor(kCheckedArgs)];
       found = true;
       break;
     }
@@ -862,10 +868,10 @@
 #if defined(DEBUG)
 #define TRACE_INSTRUCTION                                                      \
   if (IsTracingExecution()) {                                                  \
-    TraceInstruction(pc - 1);                                                  \
+    TraceInstruction(pc);                                                      \
   }                                                                            \
   if (IsWritingTraceFile()) {                                                  \
-    WriteInstructionToTrace(pc - 1);                                           \
+    WriteInstructionToTrace(pc);                                               \
   }                                                                            \
   icount_++;
 #else
@@ -878,77 +884,207 @@
 #define DISPATCH_OP(val)                                                       \
   do {                                                                         \
     op = (val);                                                                \
-    rA = ((op >> 8) & 0xFF);                                                   \
     TRACE_INSTRUCTION                                                          \
-    goto* dispatch[op & 0xFF];                                                 \
+    goto* dispatch[op];                                                        \
   } while (0)
 #else
 #define DISPATCH_OP(val)                                                       \
   do {                                                                         \
     op = (val);                                                                \
-    rA = ((op >> 8) & 0xFF);                                                   \
     TRACE_INSTRUCTION                                                          \
     goto SwitchDispatch;                                                       \
   } while (0)
 #endif
 
 // Fetch next operation from PC, increment program counter and dispatch.
-#define DISPATCH() DISPATCH_OP(*pc++)
+#define DISPATCH() DISPATCH_OP(*pc)
 
 // Load target of a jump instruction into PC.
-#define LOAD_JUMP_TARGET() pc += ((static_cast<int32_t>(op) >> 8) - 1)
+#define LOAD_JUMP_TARGET() pc = rT
+
+#define BYTECODE_ENTRY_LABEL(Name) bc##Name:
+#define BYTECODE_WIDE_ENTRY_LABEL(Name) bc##Name##_Wide:
+#define BYTECODE_OLD_ENTRY_LABEL(Name) bc##Name##_Old:
+#define BYTECODE_IMPL_LABEL(Name) bc##Name##Impl:
+#define GOTO_BYTECODE_IMPL(Name) goto bc##Name##Impl;
 
 // Define entry point that handles bytecode Name with the given operand format.
-#define BYTECODE(Name, Operands)                                               \
-  BYTECODE_HEADER(Name, DECLARE_##Operands, DECODE_##Operands)
+#define BYTECODE(Name, Operands) BYTECODE_HEADER_##Operands##_WITH_OLD(Name)
 
-#define BYTECODE_HEADER(Name, Declare, Decode)                                 \
-  Declare;                                                                     \
-  bc##Name : Decode
+// TODO(alexmarkov): switch BYTECODE macro to BYTECODE_NEW implementation
+// and replace BYTECODE_NEW with BYTECODE when old instructions are gone.
+// Cleanup BYTECODE_HEADER_*_WITH_OLD macros and drop _WITH_OLD.
+static_assert(KernelBytecode::kMinSupportedBytecodeFormatVersion < 7,
+              "Cleanup support for old bytecode format versions");
+
+#define BYTECODE_NEW(Name, Operands) BYTECODE_HEADER_##Operands(Name)
 
 // Helpers to decode common instruction formats. Used in conjunction with
 // BYTECODE() macro.
-#define DECLARE_A_B_C                                                          \
-  uint16_t rB, rC;                                                             \
-  USE(rB);                                                                     \
-  USE(rC)
-#define DECODE_A_B_C                                                           \
-  rB = ((op >> KernelBytecode::kBShift) & KernelBytecode::kBMask);             \
-  rC = ((op >> KernelBytecode::kCShift) & KernelBytecode::kCMask);
 
-#define DECLARE_A_B_Y                                                          \
-  uint16_t rB;                                                                 \
-  int8_t rY;                                                                   \
-  USE(rB);                                                                     \
-  USE(rY)
-#define DECODE_A_B_Y                                                           \
-  rB = ((op >> KernelBytecode::kBShift) & KernelBytecode::kBMask);             \
-  rY = ((op >> KernelBytecode::kYShift) & KernelBytecode::kYMask);
+#define BYTECODE_HEADER_0(Name)                                                \
+  BYTECODE_ENTRY_LABEL(Name)                                                   \
+  pc += 1;
 
-#define DECLARE_0
-#define DECODE_0
+#define BYTECODE_HEADER_0_WITH_OLD(Name)                                       \
+  BYTECODE_OLD_ENTRY_LABEL(Name)                                               \
+  pc += 4;                                                                     \
+  GOTO_BYTECODE_IMPL(Name);                                                    \
+  BYTECODE_HEADER_0(Name)                                                      \
+  BYTECODE_IMPL_LABEL(Name)
 
-#define DECLARE_A
-#define DECODE_A
+#define BYTECODE_HEADER_A_WITH_OLD(Name)                                       \
+  uint32_t rA;                                                                 \
+  USE(rA);                                                                     \
+  BYTECODE_OLD_ENTRY_LABEL(Name)                                               \
+  rA = pc[1];                                                                  \
+  pc += 4;                                                                     \
+  GOTO_BYTECODE_IMPL(Name);                                                    \
+  BYTECODE_ENTRY_LABEL(Name)                                                   \
+  rA = pc[1];                                                                  \
+  pc += 2;                                                                     \
+  BYTECODE_IMPL_LABEL(Name)
 
-#define DECLARE_T
-#define DECODE_T
-
-#define DECLARE_D                                                              \
+#define BYTECODE_HEADER_D_WITH_OLD(Name)                                       \
   uint32_t rD;                                                                 \
-  USE(rD)
-#define DECODE_D rD = (op >> KernelBytecode::kDShift);
+  USE(rD);                                                                     \
+  BYTECODE_OLD_ENTRY_LABEL(Name)                                               \
+  rD = static_cast<uint32_t>(pc[2]) | (static_cast<uint32_t>(pc[3]) << 8);     \
+  pc += 4;                                                                     \
+  GOTO_BYTECODE_IMPL(Name);                                                    \
+  BYTECODE_WIDE_ENTRY_LABEL(Name)                                              \
+  rD = static_cast<uint32_t>(pc[1]) | (static_cast<uint32_t>(pc[2]) << 8) |    \
+       (static_cast<uint32_t>(pc[3]) << 16) |                                  \
+       (static_cast<uint32_t>(pc[4]) << 24);                                   \
+  pc += 5;                                                                     \
+  GOTO_BYTECODE_IMPL(Name);                                                    \
+  BYTECODE_ENTRY_LABEL(Name)                                                   \
+  rD = pc[1];                                                                  \
+  pc += 2;                                                                     \
+  BYTECODE_IMPL_LABEL(Name)
 
-#define DECLARE_A_D DECLARE_D
-#define DECODE_A_D DECODE_D
+#define BYTECODE_HEADER_X_WITH_OLD(Name)                                       \
+  int32_t rX;                                                                  \
+  USE(rX);                                                                     \
+  BYTECODE_OLD_ENTRY_LABEL(Name)                                               \
+  rX = static_cast<int16_t>(static_cast<uint16_t>(pc[2]) |                     \
+                            (static_cast<uint16_t>(pc[3]) << 8));              \
+  pc += 4;                                                                     \
+  GOTO_BYTECODE_IMPL(Name);                                                    \
+  BYTECODE_WIDE_ENTRY_LABEL(Name)                                              \
+  rX = static_cast<int32_t>(static_cast<uint32_t>(pc[1]) |                     \
+                            (static_cast<uint32_t>(pc[2]) << 8) |              \
+                            (static_cast<uint32_t>(pc[3]) << 16) |             \
+                            (static_cast<uint32_t>(pc[4]) << 24));             \
+  pc += 5;                                                                     \
+  GOTO_BYTECODE_IMPL(Name);                                                    \
+  BYTECODE_ENTRY_LABEL(Name)                                                   \
+  rX = static_cast<int8_t>(pc[1]);                                             \
+  pc += 2;                                                                     \
+  BYTECODE_IMPL_LABEL(Name)
 
-#define DECLARE_X                                                              \
-  int32_t rD;                                                                  \
-  USE(rD)
-#define DECODE_X rD = (static_cast<int32_t>(op) >> KernelBytecode::kDShift);
+#define BYTECODE_HEADER_T_WITH_OLD(Name)                                       \
+  const KBCInstr* rT;                                                          \
+  USE(rT);                                                                     \
+  BYTECODE_OLD_ENTRY_LABEL(Name)                                               \
+  rT = pc + (static_cast<int32_t>((static_cast<uint32_t>(pc[1]) << 8) |        \
+                                  (static_cast<uint32_t>(pc[2]) << 16) |       \
+                                  (static_cast<uint32_t>(pc[3]) << 24)) >>     \
+             (8 - 2));                                                         \
+  pc += 4;                                                                     \
+  GOTO_BYTECODE_IMPL(Name);                                                    \
+  BYTECODE_WIDE_ENTRY_LABEL(Name)                                              \
+  rT = pc + (static_cast<int32_t>((static_cast<uint32_t>(pc[1]) << 8) |        \
+                                  (static_cast<uint32_t>(pc[2]) << 16) |       \
+                                  (static_cast<uint32_t>(pc[3]) << 24)) >>     \
+             8);                                                               \
+  pc += 4;                                                                     \
+  GOTO_BYTECODE_IMPL(Name);                                                    \
+  BYTECODE_ENTRY_LABEL(Name)                                                   \
+  rT = pc + static_cast<int8_t>(pc[1]);                                        \
+  pc += 2;                                                                     \
+  BYTECODE_IMPL_LABEL(Name)
 
-#define DECLARE_A_X DECLARE_X
-#define DECODE_A_X DECODE_X
+#define BYTECODE_HEADER_A_E_WITH_OLD(Name)                                     \
+  uint32_t rA, rE;                                                             \
+  USE(rA);                                                                     \
+  USE(rE);                                                                     \
+  BYTECODE_OLD_ENTRY_LABEL(Name)                                               \
+  rA = pc[1];                                                                  \
+  rE = static_cast<uint32_t>(pc[2]) | (static_cast<uint32_t>(pc[3]) << 8);     \
+  pc += 4;                                                                     \
+  GOTO_BYTECODE_IMPL(Name);                                                    \
+  BYTECODE_WIDE_ENTRY_LABEL(Name)                                              \
+  rA = pc[1];                                                                  \
+  rE = static_cast<uint32_t>(pc[2]) | (static_cast<uint32_t>(pc[3]) << 8) |    \
+       (static_cast<uint32_t>(pc[4]) << 16) |                                  \
+       (static_cast<uint32_t>(pc[5]) << 24);                                   \
+  pc += 6;                                                                     \
+  GOTO_BYTECODE_IMPL(Name);                                                    \
+  BYTECODE_ENTRY_LABEL(Name)                                                   \
+  rA = pc[1];                                                                  \
+  rE = pc[2];                                                                  \
+  pc += 3;                                                                     \
+  BYTECODE_IMPL_LABEL(Name)
+
+#define BYTECODE_HEADER_A_Y_WITH_OLD(Name)                                     \
+  uint32_t rA;                                                                 \
+  int32_t rY;                                                                  \
+  USE(rA);                                                                     \
+  USE(rY);                                                                     \
+  BYTECODE_OLD_ENTRY_LABEL(Name)                                               \
+  rA = pc[1];                                                                  \
+  rY = static_cast<int16_t>(static_cast<uint16_t>(pc[2]) |                     \
+                            (static_cast<uint16_t>(pc[3]) << 8));              \
+  pc += 4;                                                                     \
+  GOTO_BYTECODE_IMPL(Name);                                                    \
+  BYTECODE_WIDE_ENTRY_LABEL(Name)                                              \
+  rA = pc[1];                                                                  \
+  rY = static_cast<int32_t>(static_cast<uint32_t>(pc[2]) |                     \
+                            (static_cast<uint32_t>(pc[3]) << 8) |              \
+                            (static_cast<uint32_t>(pc[4]) << 16) |             \
+                            (static_cast<uint32_t>(pc[5]) << 24));             \
+  pc += 6;                                                                     \
+  GOTO_BYTECODE_IMPL(Name);                                                    \
+  BYTECODE_ENTRY_LABEL(Name)                                                   \
+  rA = pc[1];                                                                  \
+  rY = static_cast<int8_t>(pc[2]);                                             \
+  pc += 3;                                                                     \
+  BYTECODE_IMPL_LABEL(Name)
+
+#define BYTECODE_HEADER_D_F_WITH_OLD(Name)                                     \
+  uint32_t rD, rF;                                                             \
+  USE(rD);                                                                     \
+  USE(rF);                                                                     \
+  BYTECODE_OLD_ENTRY_LABEL(Name)                                               \
+  rF = pc[1];                                                                  \
+  rD = static_cast<uint32_t>(pc[2]) | (static_cast<uint32_t>(pc[3]) << 8);     \
+  pc += 4;                                                                     \
+  GOTO_BYTECODE_IMPL(Name);                                                    \
+  BYTECODE_WIDE_ENTRY_LABEL(Name)                                              \
+  rD = static_cast<uint32_t>(pc[1]) | (static_cast<uint32_t>(pc[2]) << 8) |    \
+       (static_cast<uint32_t>(pc[3]) << 16) |                                  \
+       (static_cast<uint32_t>(pc[4]) << 24);                                   \
+  rF = pc[5];                                                                  \
+  pc += 6;                                                                     \
+  GOTO_BYTECODE_IMPL(Name);                                                    \
+  BYTECODE_ENTRY_LABEL(Name)                                                   \
+  rD = pc[1];                                                                  \
+  rF = pc[2];                                                                  \
+  pc += 3;                                                                     \
+  BYTECODE_IMPL_LABEL(Name)
+
+#define BYTECODE_HEADER_A_B_C_WITH_OLD(Name)                                   \
+  uint32_t rA, rB, rC;                                                         \
+  USE(rA);                                                                     \
+  USE(rB);                                                                     \
+  USE(rC);                                                                     \
+  BYTECODE_OLD_ENTRY_LABEL(Name)                                               \
+  BYTECODE_ENTRY_LABEL(Name)                                                   \
+  rA = pc[1];                                                                  \
+  rB = pc[2];                                                                  \
+  rC = pc[3];                                                                  \
+  pc += 4;
 
 #define HANDLE_EXCEPTION                                                       \
   do {                                                                         \
@@ -1032,7 +1168,7 @@
   }
 
 bool Interpreter::AssertAssignable(Thread* thread,
-                                   uint32_t* pc,
+                                   const KBCInstr* pc,
                                    RawObject** FP,
                                    RawObject** call_top,
                                    RawObject** args,
@@ -1126,7 +1262,7 @@
 // Returns false on exception.
 DART_NOINLINE bool Interpreter::AllocateMint(Thread* thread,
                                              int64_t value,
-                                             uint32_t* pc,
+                                             const KBCInstr* pc,
                                              RawObject** FP,
                                              RawObject** SP) {
   ASSERT(!Smi::IsValid(value));
@@ -1157,7 +1293,7 @@
 // Returns false on exception.
 DART_NOINLINE bool Interpreter::AllocateDouble(Thread* thread,
                                                double value,
-                                               uint32_t* pc,
+                                               const KBCInstr* pc,
                                                RawObject** FP,
                                                RawObject** SP) {
   const intptr_t instance_size = Double::InstanceSize();
@@ -1187,7 +1323,7 @@
 // Returns false on exception.
 DART_NOINLINE bool Interpreter::AllocateFloat32x4(Thread* thread,
                                                   simd128_value_t value,
-                                                  uint32_t* pc,
+                                                  const KBCInstr* pc,
                                                   RawObject** FP,
                                                   RawObject** SP) {
   const intptr_t instance_size = Float32x4::InstanceSize();
@@ -1217,7 +1353,7 @@
 // Returns false on exception.
 DART_NOINLINE bool Interpreter::AllocateFloat64x2(Thread* thread,
                                                   simd128_value_t value,
-                                                  uint32_t* pc,
+                                                  const KBCInstr* pc,
                                                   RawObject** FP,
                                                   RawObject** SP) {
   const intptr_t instance_size = Float64x2::InstanceSize();
@@ -1248,7 +1384,7 @@
 bool Interpreter::AllocateArray(Thread* thread,
                                 RawTypeArguments* type_args,
                                 RawObject* length_object,
-                                uint32_t* pc,
+                                const KBCInstr* pc,
                                 RawObject** FP,
                                 RawObject** SP) {
   if (LIKELY(!length_object->IsHeapObject())) {
@@ -1283,7 +1419,7 @@
 // Returns false on exception.
 bool Interpreter::AllocateContext(Thread* thread,
                                   intptr_t num_context_variables,
-                                  uint32_t* pc,
+                                  const KBCInstr* pc,
                                   RawObject** FP,
                                   RawObject** SP) {
   const intptr_t instance_size = Context::InstanceSize(num_context_variables);
@@ -1314,7 +1450,7 @@
 // Allocate a _Closure and put it into SP[0].
 // Returns false on exception.
 bool Interpreter::AllocateClosure(Thread* thread,
-                                  uint32_t* pc,
+                                  const KBCInstr* pc,
                                   RawObject** FP,
                                   RawObject** SP) {
   const intptr_t instance_size = Closure::InstanceSize();
@@ -1346,12 +1482,11 @@
                              RawObject* const* argv,
                              Thread* thread) {
   // Interpreter state (see constants_kbc.h for high-level overview).
-  uint32_t* pc;    // Program Counter: points to the next op to execute.
+  const KBCInstr* pc;  // Program Counter: points to the next op to execute.
   RawObject** FP;  // Frame Pointer.
   RawObject** SP;  // Stack Pointer.
 
   uint32_t op;  // Currently executing op.
-  uint16_t rA;  // A component of the currently executing op.
 
   bool reentering = fp_ != NULL;
   if (!reentering) {
@@ -1420,7 +1555,7 @@
 
   // Ready to start executing bytecode. Load entry point and corresponding
   // object pool.
-  pc = reinterpret_cast<uint32_t*>(bytecode->ptr()->instructions_);
+  pc = reinterpret_cast<const KBCInstr*>(bytecode->ptr()->instructions_);
   NOT_IN_PRODUCT(pc_ = pc);  // For the profiler.
   NOT_IN_PRODUCT(fp_ = FP);  // For the profiler.
   pp_ = bytecode->ptr()->object_pool_;
@@ -1442,7 +1577,7 @@
 
 #ifdef DART_HAS_COMPUTED_GOTO
   static const void* dispatch[] = {
-#define TARGET(name, fmt, fmta, fmtb, fmtc) &&bc##name,
+#define TARGET(name, fmt, kind, fmta, fmtb, fmtc) &&bc##name,
       KERNEL_BYTECODES_LIST(TARGET)
 #undef TARGET
   };
@@ -1451,7 +1586,7 @@
   DISPATCH();  // Enter the dispatch loop.
 SwitchDispatch:
   switch (op & 0xFF) {
-#define TARGET(name, fmt, fmta, fmtb, fmtc)                                    \
+#define TARGET(name, fmt, kind, fmta, fmtb, fmtc)                              \
   case KernelBytecode::k##name:                                                \
     goto bc##name;
     KERNEL_BYTECODES_LIST(TARGET)
@@ -1464,7 +1599,7 @@
   // KernelBytecode handlers (see constants_kbc.h for bytecode descriptions).
   {
     BYTECODE(Entry, D);
-    const uint16_t num_locals = rD;
+    const intptr_t num_locals = rD;
 
     // Initialize locals with null & set SP.
     for (intptr_t i = 0; i < num_locals; i++) {
@@ -1476,9 +1611,9 @@
   }
 
   {
-    BYTECODE(EntryFixed, A_D);
-    const uint16_t num_fixed_params = rA;
-    const uint16_t num_locals = rD;
+    BYTECODE(EntryFixed, A_E);
+    const intptr_t num_fixed_params = rA;
+    const intptr_t num_locals = rE;
 
     const intptr_t arg_count = InterpreterHelpers::ArgDescArgCount(argdesc_);
     const intptr_t pos_count = InterpreterHelpers::ArgDescPosCount(argdesc_);
@@ -1497,9 +1632,9 @@
 
   {
     BYTECODE(EntryOptional, A_B_C);
-    const uint16_t num_fixed_params = rA;
-    const uint16_t num_opt_pos_params = rB;
-    const uint16_t num_opt_named_params = rC;
+    const intptr_t num_fixed_params = rA;
+    const intptr_t num_opt_pos_params = rB;
+    const intptr_t num_opt_named_params = rC;
     const intptr_t min_num_pos_args = num_fixed_params;
     const intptr_t max_num_pos_args = num_fixed_params + num_opt_pos_params;
 
@@ -1525,60 +1660,55 @@
       // descriptor.
       RawObject** argdesc_data = argdesc_->ptr()->data();
 
-      intptr_t i = named_count - 1;           // argument position
-      intptr_t j = num_opt_named_params - 1;  // parameter position
-      while ((j >= 0) && (i >= 0)) {
+      intptr_t i = 0;  // argument position
+      intptr_t j = 0;  // parameter position
+      while ((j < num_opt_named_params) && (i < named_count)) {
         // Fetch formal parameter information: name, default value, target slot.
-        const uint32_t load_name = pc[2 * j];
-        const uint32_t load_value = pc[2 * j + 1];
-        ASSERT(KernelBytecode::DecodeOpcode(load_name) ==
-               KernelBytecode::kLoadConstant);
-        ASSERT(KernelBytecode::DecodeOpcode(load_value) ==
-               KernelBytecode::kLoadConstant);
+        const KBCInstr* load_name = pc;
+        const KBCInstr* load_value = KernelBytecode::Next(load_name);
+        pc = KernelBytecode::Next(load_value);
+        ASSERT(KernelBytecode::IsLoadConstantOpcode(load_name));
+        ASSERT(KernelBytecode::IsLoadConstantOpcode(load_value));
         const uint8_t reg = KernelBytecode::DecodeA(load_name);
         ASSERT(reg == KernelBytecode::DecodeA(load_value));
 
         RawString* name = static_cast<RawString*>(
-            LOAD_CONSTANT(KernelBytecode::DecodeD(load_name)));
+            LOAD_CONSTANT(KernelBytecode::DecodeE(load_name)));
         if (name == argdesc_data[ArgumentsDescriptor::name_index(i)]) {
           // Parameter was passed. Fetch passed value.
           const intptr_t arg_index = Smi::Value(static_cast<RawSmi*>(
               argdesc_data[ArgumentsDescriptor::position_index(i)]));
           FP[reg] = first_arg[arg_index];
-          i--;  // Consume passed argument.
+          ++i;  // Consume passed argument.
         } else {
           // Parameter was not passed. Fetch default value.
-          FP[reg] = LOAD_CONSTANT(KernelBytecode::DecodeD(load_value));
+          FP[reg] = LOAD_CONSTANT(KernelBytecode::DecodeE(load_value));
         }
-        j--;  // Next formal parameter.
+        ++j;  // Next formal parameter.
       }
 
       // If we have unprocessed formal parameters then initialize them all
       // using default values.
-      while (j >= 0) {
-        const uint32_t load_name = pc[2 * j];
-        const uint32_t load_value = pc[2 * j + 1];
-        ASSERT(KernelBytecode::DecodeOpcode(load_name) ==
-               KernelBytecode::kLoadConstant);
-        ASSERT(KernelBytecode::DecodeOpcode(load_value) ==
-               KernelBytecode::kLoadConstant);
+      while (j < num_opt_named_params) {
+        const KBCInstr* load_name = pc;
+        const KBCInstr* load_value = KernelBytecode::Next(load_name);
+        pc = KernelBytecode::Next(load_value);
+        ASSERT(KernelBytecode::IsLoadConstantOpcode(load_name));
+        ASSERT(KernelBytecode::IsLoadConstantOpcode(load_value));
         const uint8_t reg = KernelBytecode::DecodeA(load_name);
         ASSERT(reg == KernelBytecode::DecodeA(load_value));
 
-        FP[reg] = LOAD_CONSTANT(KernelBytecode::DecodeD(load_value));
-        j--;
+        FP[reg] = LOAD_CONSTANT(KernelBytecode::DecodeE(load_value));
+        ++j;
       }
 
       // If we have unprocessed passed arguments that means we have mismatch
       // between formal parameters and concrete arguments. This can only
       // occur if the current function is a closure.
-      if (i != -1) {
+      if (i < named_count) {
         goto NoSuchMethodFromPrologue;
       }
 
-      // Skip LoadConstant-s encoding information about named parameters.
-      pc += num_opt_named_params * 2;
-
       // SP points past copied arguments.
       SP = FP + num_fixed_params + num_opt_named_params - 1;
     } else {
@@ -1593,22 +1723,17 @@
       // Process the list of default values encoded as a sequence of
       // LoadConstant instructions after EntryOpt bytecode.
       // Execute only those that correspond to parameters that were not passed.
-      for (intptr_t i = pos_count - num_fixed_params; i < num_opt_pos_params;
-           i++) {
-        const uint32_t load_value = pc[i];
-        ASSERT(KernelBytecode::DecodeOpcode(load_value) ==
-               KernelBytecode::kLoadConstant);
-#if defined(DEBUG)
-        const uint8_t reg = KernelBytecode::DecodeA(load_value);
-        ASSERT((num_fixed_params + i) == reg);
-#endif
-        FP[num_fixed_params + i] =
-            LOAD_CONSTANT(KernelBytecode::DecodeD(load_value));
+      for (intptr_t i = num_fixed_params; i < pos_count; ++i) {
+        ASSERT(KernelBytecode::IsLoadConstantOpcode(pc));
+        pc = KernelBytecode::Next(pc);
       }
-
-      // Skip LoadConstant-s encoding default values for optional positional
-      // parameters.
-      pc += num_opt_pos_params;
+      for (intptr_t i = pos_count; i < max_num_pos_args; ++i) {
+        const KBCInstr* load_value = pc;
+        pc = KernelBytecode::Next(load_value);
+        ASSERT(KernelBytecode::IsLoadConstantOpcode(load_value));
+        ASSERT(KernelBytecode::DecodeA(load_value) == i);
+        FP[i] = LOAD_CONSTANT(KernelBytecode::DecodeE(load_value));
+      }
 
       // SP points past the last copied parameter.
       SP = FP + max_num_pos_args - 1;
@@ -1620,7 +1745,7 @@
   {
     BYTECODE(Frame, D);
     // Initialize locals with null and increment SP.
-    const uint16_t num_locals = rD;
+    const intptr_t num_locals = rD;
     for (intptr_t i = 1; i <= num_locals; i++) {
       SP[i] = null_value;
     }
@@ -1662,9 +1787,9 @@
   }
 
   {
-    BYTECODE(CheckFunctionTypeArgs, A_D);
-    const uint16_t declared_type_args_len = rA;
-    const uint16_t first_stack_local_index = rD;
+    BYTECODE(CheckFunctionTypeArgs, A_E);
+    const intptr_t declared_type_args_len = rA;
+    const intptr_t first_stack_local_index = rE;
 
     // Decode arguments descriptor's type args len.
     const intptr_t type_args_len =
@@ -1700,10 +1825,10 @@
   }
 
   {
-    BYTECODE(InstantiateTypeArgumentsTOS, A_D);
+    BYTECODE(InstantiateTypeArgumentsTOS, A_E);
     // Stack: instantiator type args, function type args
     RawTypeArguments* type_arguments =
-        static_cast<RawTypeArguments*>(LOAD_CONSTANT(rD));
+        static_cast<RawTypeArguments*>(LOAD_CONSTANT(rE));
 
     RawObject* instantiator_type_args = SP[-1];
     RawObject* function_type_args = SP[0];
@@ -1763,8 +1888,8 @@
   }
 
   {
-    BYTECODE(LoadConstant, A_D);
-    FP[rA] = LOAD_CONSTANT(rD);
+    BYTECODE(LoadConstant, A_E);
+    FP[rA] = LOAD_CONSTANT(rE);
     DISPATCH();
   }
 
@@ -1794,32 +1919,32 @@
 
   {
     BYTECODE(PushInt, X);
-    *++SP = Smi::New(rD);
+    *++SP = Smi::New(rX);
     DISPATCH();
   }
 
   {
     BYTECODE(Push, X);
-    *++SP = FP[rD];
+    *++SP = FP[rX];
     DISPATCH();
   }
 
   {
     BYTECODE(StoreLocal, X);
-    FP[rD] = *SP;
+    FP[rX] = *SP;
     DISPATCH();
   }
 
   {
     BYTECODE(PopLocal, X);
-    FP[rD] = *SP--;
+    FP[rX] = *SP--;
     DISPATCH();
   }
 
   {
-    BYTECODE(MoveSpecial, A_X);
+    BYTECODE(MoveSpecial, A_Y);
     ASSERT(rA < KernelBytecode::kSpecialIndexCount);
-    FP[rD] = special_[rA];
+    FP[rY] = special_[rA];
     DISPATCH();
   }
 
@@ -1830,7 +1955,7 @@
   }
 
   {
-    BYTECODE(IndirectStaticCall, A_D);
+    BYTECODE(DirectCall, D_F);
 
 #ifndef PRODUCT
     // Check if single stepping.
@@ -1843,40 +1968,8 @@
 
     // Invoke target function.
     {
-      const uint16_t argc = rA;
-      // Look up the function in the ICData.
-      RawObject* ic_data_obj = SP[0];
-      RawICData* ic_data = RAW_CAST(ICData, ic_data_obj);
-      RawObject** data = ic_data->ptr()->entries_->ptr()->data();
-      InterpreterHelpers::IncrementICUsageCount(data, 0, 0);
-      SP[0] = data[ICData::TargetIndexFor(ic_data->ptr()->state_bits_ & 0x3)];
-      RawObject** call_base = SP - argc;
-      RawObject** call_top = SP;  // *SP contains function
-      argdesc_ = static_cast<RawArray*>(LOAD_CONSTANT(rD));
-      if (!Invoke(thread, call_base, call_top, &pc, &FP, &SP)) {
-        HANDLE_EXCEPTION;
-      }
-    }
-
-    DISPATCH();
-  }
-
-  {
-    BYTECODE(DirectCall, A_D);
-
-#ifndef PRODUCT
-    // Check if single stepping.
-    if (thread->isolate()->single_step()) {
-      Exit(thread, FP, SP + 1, pc);
-      NativeArguments args(thread, 0, NULL, NULL);
-      INVOKE_RUNTIME(DRT_SingleStepHandler, args);
-    }
-#endif  // !PRODUCT
-
-    // Invoke target function.
-    {
-      const uint16_t argc = rA;
-      const uint16_t kidx = rD;
+      const uint32_t argc = rF;
+      const uint32_t kidx = rD;
 
       InterpreterHelpers::IncrementUsageCounter(FrameFunction(FP));
       *++SP = LOAD_CONSTANT(kidx);
@@ -1892,7 +1985,7 @@
   }
 
   {
-    BYTECODE(InterfaceCall, A_D);
+    BYTECODE(InterfaceCall, D_F);
 
 #ifndef PRODUCT
     // Check if single stepping.
@@ -1904,8 +1997,8 @@
 #endif  // !PRODUCT
 
     {
-      const uint16_t argc = rA;
-      const uint16_t kidx = rD;
+      const uint32_t argc = rF;
+      const uint32_t kidx = rD;
 
       RawObject** call_base = SP - argc + 1;
       RawObject** call_top = SP + 1;
@@ -1924,7 +2017,7 @@
   }
 
   {
-    BYTECODE(UncheckedInterfaceCall, A_D);
+    BYTECODE(UncheckedInterfaceCall, D_F);
 
 #ifndef PRODUCT
     // Check if single stepping.
@@ -1936,8 +2029,8 @@
 #endif  // !PRODUCT
 
     {
-      const uint16_t argc = rA;
-      const uint16_t kidx = rD;
+      const uint32_t argc = rF;
+      const uint32_t kidx = rD;
 
       RawObject** call_base = SP - argc + 1;
       RawObject** call_top = SP + 1;
@@ -1956,7 +2049,7 @@
   }
 
   {
-    BYTECODE(DynamicCall, A_D);
+    BYTECODE(DynamicCall, D_F);
 
 #ifndef PRODUCT
     // Check if single stepping.
@@ -1968,8 +2061,8 @@
 #endif  // !PRODUCT
 
     {
-      const uint16_t argc = rA;
-      const uint16_t kidx = rD;
+      const uint32_t argc = rF;
+      const uint32_t kidx = rD;
 
       RawObject** call_base = SP - argc + 1;
       RawObject** call_top = SP + 1;
@@ -2064,7 +2157,12 @@
           // Change the ArgumentsDescriptor of the call with a new cached one.
           argdesc_ = ArgumentsDescriptor::New(
               0, KernelBytecode::kNativeCallToGrowableListArgc);
-          // Note the special handling of the return of this call in DecodeArgc.
+          if (!thread->isolate()->is_using_old_bytecode_instructions()) {
+            // Replace PC to the return trampoline so ReturnTOS would see
+            // a call bytecode at return address and will be able to get argc
+            // via DecodeArgc.
+            pc = KernelBytecode::GetNativeCallToGrowableListReturnTrampoline();
+          }
           if (!Invoke(thread, SP - 1, SP + 1, &pc, &FP, &SP)) {
             HANDLE_EXCEPTION;
           }
@@ -2214,7 +2312,9 @@
     }
 
     // Look at the caller to determine how many arguments to pop.
-    const uint8_t argc = KernelBytecode::DecodeArgc(pc[-1]);
+    const uint8_t argc = thread->isolate()->is_using_old_bytecode_instructions()
+                             ? KernelBytecode::DecodeArgc_Old(pc)
+                             : KernelBytecode::DecodeArgc(pc);
 
     // Restore SP, FP and PP. Push result and dispatch.
     SP = FrameArguments(FP, argc);
@@ -2223,6 +2323,14 @@
     NOT_IN_PRODUCT(pc_ = pc);  // For the profiler.
     pp_ = InterpreterHelpers::FrameBytecode(FP)->ptr()->object_pool_;
     *SP = result;
+#if defined(DEBUG)
+    if (IsTracingExecution()) {
+      THR_Print("%" Pu64 " ", icount_);
+      THR_Print("Returning to %s (argc %d)\n",
+                Function::Handle(FrameFunction(FP)).ToFullyQualifiedCString(),
+                static_cast<int>(argc));
+    }
+#endif
     DISPATCH();
   }
 
@@ -2333,13 +2441,13 @@
   }
 
   {
-    BYTECODE(StoreContextVar, A_D);
+    BYTECODE(StoreContextVar, A_E);
     const uword offset_in_words =
-        static_cast<uword>(Context::variable_offset(rD) / kWordSize);
+        static_cast<uword>(Context::variable_offset(rE) / kWordSize);
     RawContext* instance = reinterpret_cast<RawContext*>(SP[-1]);
     RawObject* value = reinterpret_cast<RawContext*>(SP[0]);
     SP -= 2;  // Drop instance and value.
-    ASSERT(rD < static_cast<uint32_t>(instance->ptr()->num_variables_));
+    ASSERT(rE < static_cast<uint32_t>(instance->ptr()->num_variables_));
     instance->StorePointer(
         reinterpret_cast<RawObject**>(instance->ptr()) + offset_in_words, value,
         thread);
@@ -2385,19 +2493,19 @@
   }
 
   {
-    BYTECODE(LoadContextVar, A_D);
+    BYTECODE(LoadContextVar, A_E);
     const uword offset_in_words =
-        static_cast<uword>(Context::variable_offset(rD) / kWordSize);
+        static_cast<uword>(Context::variable_offset(rE) / kWordSize);
     RawContext* instance = static_cast<RawContext*>(SP[0]);
-    ASSERT(rD < static_cast<uint32_t>(instance->ptr()->num_variables_));
+    ASSERT(rE < static_cast<uint32_t>(instance->ptr()->num_variables_));
     SP[0] = reinterpret_cast<RawObject**>(instance->ptr())[offset_in_words];
     DISPATCH();
   }
 
   {
-    BYTECODE(AllocateContext, A_D);
+    BYTECODE(AllocateContext, A_E);
     ++SP;
-    const uint16_t num_context_variables = rD;
+    const uint32_t num_context_variables = rE;
     if (!AllocateContext(thread, num_context_variables, pc, FP, SP)) {
       HANDLE_EXCEPTION;
     }
@@ -2405,7 +2513,7 @@
   }
 
   {
-    BYTECODE(CloneContext, A_D);
+    BYTECODE(CloneContext, A_E);
     {
       SP[1] = SP[0];  // Context to clone.
       Exit(thread, FP, SP + 2, pc);
@@ -2490,7 +2598,7 @@
   }
 
   {
-    BYTECODE(AssertAssignable, A_D);
+    BYTECODE(AssertAssignable, A_E);
     // Stack: instance, type, instantiator type args, function type args, name
     RawObject** args = SP - 4;
     const bool may_be_smi = (rA == 1);
@@ -2499,7 +2607,7 @@
     const bool smi_ok = is_smi && may_be_smi;
     if (!smi_ok && (args[0] != null_value)) {
       RawSubtypeTestCache* cache =
-          static_cast<RawSubtypeTestCache*>(LOAD_CONSTANT(rD));
+          static_cast<RawSubtypeTestCache*>(LOAD_CONSTANT(rE));
 
       if (!AssertAssignable(thread, pc, FP, SP, args, cache)) {
         HANDLE_EXCEPTION;
@@ -2956,12 +3064,50 @@
 
   {
     BYTECODE(Trap, 0);
+    BYTECODE(Unused00, 0);
+    BYTECODE_NEW(Unused01, 0);
+    BYTECODE_NEW(Unused02, 0);
+    BYTECODE_NEW(Unused03, 0);
+    BYTECODE_NEW(Unused04, 0);
+    BYTECODE_NEW(Unused05, 0);
+    BYTECODE_NEW(Unused06, 0);
+    BYTECODE_NEW(Unused07, 0);
+    BYTECODE_NEW(Unused08, 0);
+    BYTECODE_NEW(Unused09, 0);
+    BYTECODE_NEW(Unused10, 0);
+    BYTECODE_NEW(Unused11, 0);
+    BYTECODE_NEW(Unused12, 0);
+    BYTECODE_NEW(Unused13, 0);
+    BYTECODE_NEW(Unused14, 0);
+    BYTECODE_NEW(Unused15, 0);
+    BYTECODE_NEW(Unused16, 0);
+    BYTECODE_NEW(Unused17, 0);
+    BYTECODE_NEW(Unused18, 0);
+    BYTECODE_NEW(Unused19, 0);
+    BYTECODE_NEW(Unused20, 0);
+    BYTECODE_NEW(Unused21, 0);
+    BYTECODE_NEW(Unused22, 0);
+    BYTECODE_NEW(Unused23, 0);
+    BYTECODE_NEW(Unused24, 0);
+    BYTECODE_NEW(Unused25, 0);
+    BYTECODE_NEW(Unused26, 0);
+    BYTECODE_NEW(Unused27, 0);
+    BYTECODE_NEW(Unused28, 0);
+    BYTECODE_NEW(Unused29, 0);
+    BYTECODE_NEW(Unused30, 0);
+    BYTECODE_NEW(Unused31, 0);
+    BYTECODE_NEW(Unused32, 0);
+    BYTECODE_NEW(Unused33, 0);
+    BYTECODE_NEW(Unused34, 0);
+    BYTECODE_NEW(Unused35, 0);
+    BYTECODE_NEW(Unused36, 0);
+    BYTECODE_NEW(Unused37, 0);
     UNIMPLEMENTED();
     DISPATCH();
   }
 
   {
-    BYTECODE(VMInternal_ImplicitGetter, 0);
+    BYTECODE_NEW(VMInternal_ImplicitGetter, 0);
 
     RawFunction* function = FrameFunction(FP);
     ASSERT(Function::kind(function) == RawFunction::kImplicitGetter);
@@ -3010,7 +3156,7 @@
   }
 
   {
-    BYTECODE(VMInternal_ImplicitSetter, 0);
+    BYTECODE_NEW(VMInternal_ImplicitSetter, 0);
 
     RawFunction* function = FrameFunction(FP);
     ASSERT(Function::kind(function) == RawFunction::kImplicitSetter);
@@ -3131,7 +3277,7 @@
   }
 
   {
-    BYTECODE(VMInternal_ImplicitStaticGetter, 0);
+    BYTECODE_NEW(VMInternal_ImplicitStaticGetter, 0);
 
     RawFunction* function = FrameFunction(FP);
     ASSERT(Function::kind(function) == RawFunction::kImplicitStaticGetter);
@@ -3163,7 +3309,7 @@
   }
 
   {
-    BYTECODE(VMInternal_MethodExtractor, 0);
+    BYTECODE_NEW(VMInternal_MethodExtractor, 0);
 
     RawFunction* function = FrameFunction(FP);
     ASSERT(Function::kind(function) == RawFunction::kMethodExtractor);
@@ -3203,7 +3349,7 @@
   }
 
   {
-    BYTECODE(VMInternal_InvokeClosure, 0);
+    BYTECODE_NEW(VMInternal_InvokeClosure, 0);
 
     RawFunction* function = FrameFunction(FP);
     ASSERT(Function::kind(function) == RawFunction::kInvokeFieldDispatcher);
@@ -3225,7 +3371,7 @@
   }
 
   {
-    BYTECODE(VMInternal_InvokeField, 0);
+    BYTECODE_NEW(VMInternal_InvokeField, 0);
 
     RawFunction* function = FrameFunction(FP);
     ASSERT(Function::kind(function) == RawFunction::kInvokeFieldDispatcher);
@@ -3329,7 +3475,7 @@
   }
 
   {
-    BYTECODE(VMInternal_ForwardDynamicInvocation, 0);
+    BYTECODE_NEW(VMInternal_ForwardDynamicInvocation, 0);
     RawFunction* function = FrameFunction(FP);
     ASSERT(Function::kind(function) ==
            RawFunction::kDynamicInvocationForwarder);
@@ -3338,14 +3484,14 @@
   }
 
   {
-    BYTECODE(VMInternal_NoSuchMethodDispatcher, 0);
+    BYTECODE_NEW(VMInternal_NoSuchMethodDispatcher, 0);
     RawFunction* function = FrameFunction(FP);
     ASSERT(Function::kind(function) == RawFunction::kNoSuchMethodDispatcher);
     goto NoSuchMethodFromPrologue;
   }
 
   {
-    BYTECODE(VMInternal_ImplicitStaticClosure, 0);
+    BYTECODE_NEW(VMInternal_ImplicitStaticClosure, 0);
     RawFunction* function = FrameFunction(FP);
     ASSERT(Function::kind(function) == RawFunction::kImplicitClosureFunction);
     UNIMPLEMENTED();
@@ -3353,7 +3499,7 @@
   }
 
   {
-    BYTECODE(VMInternal_ImplicitInstanceClosure, 0);
+    BYTECODE_NEW(VMInternal_ImplicitInstanceClosure, 0);
     RawFunction* function = FrameFunction(FP);
     ASSERT(Function::kind(function) == RawFunction::kImplicitClosureFunction);
     UNIMPLEMENTED();
@@ -3372,7 +3518,7 @@
         FP[kKBCFunctionSlotFromFp] = function;
         FP[kKBCPcMarkerSlotFromFp] = bytecode;
         pp_ = bytecode->ptr()->object_pool_;
-        pc = reinterpret_cast<uint32_t*>(bytecode->ptr()->instructions_);
+        pc = reinterpret_cast<const KBCInstr*>(bytecode->ptr()->instructions_);
         NOT_IN_PRODUCT(pc_ = pc);  // For the profiler.
         DISPATCH();
       }
@@ -3559,9 +3705,9 @@
     thread->set_active_stacktrace(Object::null_object());
     special_[KernelBytecode::kExceptionSpecialIndex] = raw_exception;
     special_[KernelBytecode::kStackTraceSpecialIndex] = raw_stacktrace;
-    pc_ = reinterpret_cast<uint32_t*>(thread->resume_pc());
+    pc_ = reinterpret_cast<const KBCInstr*>(thread->resume_pc());
   } else {
-    pc_ = reinterpret_cast<uint32_t*>(pc);
+    pc_ = reinterpret_cast<const KBCInstr*>(pc);
   }
 
   // Set the tag.
diff --git a/runtime/vm/interpreter.h b/runtime/vm/interpreter.h
index db8d6e7..7001203 100644
--- a/runtime/vm/interpreter.h
+++ b/runtime/vm/interpreter.h
@@ -96,7 +96,7 @@
   }
 
   // Identify an entry frame by looking at its pc marker value.
-  static bool IsEntryFrameMarker(uint32_t* pc) {
+  static bool IsEntryFrameMarker(const KBCInstr* pc) {
     return reinterpret_cast<word>(pc) == kEntryFramePcMarker;
   }
 
@@ -129,7 +129,7 @@
   uword stack_limit_;
 
   RawObject** volatile fp_;
-  uint32_t* volatile pc_;
+  const KBCInstr* volatile pc_;
   DEBUG_ONLY(uint64_t icount_;)
 
   InterpreterSetjmpBuffer* last_setjmp_buffer_;
@@ -144,12 +144,12 @@
   void Exit(Thread* thread,
             RawObject** base,
             RawObject** exit_frame,
-            uint32_t* pc);
+            const KBCInstr* pc);
 
   bool Invoke(Thread* thread,
               RawObject** call_base,
               RawObject** call_top,
-              uint32_t** pc,
+              const KBCInstr** pc,
               RawObject*** FP,
               RawObject*** SP);
 
@@ -157,7 +157,7 @@
                       RawFunction* function,
                       RawObject** call_base,
                       RawObject** call_top,
-                      uint32_t** pc,
+                      const KBCInstr** pc,
                       RawObject*** FP,
                       RawObject*** SP);
 
@@ -165,7 +165,7 @@
                       RawFunction* function,
                       RawObject** call_base,
                       RawObject** call_top,
-                      uint32_t** pc,
+                      const KBCInstr** pc,
                       RawObject*** FP,
                       RawObject*** SP);
 
@@ -174,7 +174,7 @@
                        RawICData* icdata,
                        RawObject** call_base,
                        RawObject** top,
-                       uint32_t* pc,
+                       const KBCInstr* pc,
                        RawObject** FP,
                        RawObject** SP);
 
@@ -182,7 +182,7 @@
                      RawString* target_name,
                      RawObject** call_base,
                      RawObject** call_top,
-                     uint32_t** pc,
+                     const KBCInstr** pc,
                      RawObject*** FP,
                      RawObject*** SP);
 
@@ -190,7 +190,7 @@
                      RawICData* icdata,
                      RawObject** call_base,
                      RawObject** call_top,
-                     uint32_t** pc,
+                     const KBCInstr** pc,
                      RawObject*** FP,
                      RawObject*** SP,
                      bool optimized);
@@ -199,13 +199,13 @@
                      RawICData* icdata,
                      RawObject** call_base,
                      RawObject** call_top,
-                     uint32_t** pc,
+                     const KBCInstr** pc,
                      RawObject*** FP,
                      RawObject*** SP,
                      bool optimized);
 
   bool AssertAssignable(Thread* thread,
-                        uint32_t* pc,
+                        const KBCInstr* pc,
                         RawObject** FP,
                         RawObject** call_top,
                         RawObject** args,
@@ -213,37 +213,37 @@
 
   bool AllocateMint(Thread* thread,
                     int64_t value,
-                    uint32_t* pc,
+                    const KBCInstr* pc,
                     RawObject** FP,
                     RawObject** SP);
   bool AllocateDouble(Thread* thread,
                       double value,
-                      uint32_t* pc,
+                      const KBCInstr* pc,
                       RawObject** FP,
                       RawObject** SP);
   bool AllocateFloat32x4(Thread* thread,
                          simd128_value_t value,
-                         uint32_t* pc,
+                         const KBCInstr* pc,
                          RawObject** FP,
                          RawObject** SP);
   bool AllocateFloat64x2(Thread* thread,
                          simd128_value_t value,
-                         uint32_t* pc,
+                         const KBCInstr* pc,
                          RawObject** FP,
                          RawObject** SP);
   bool AllocateArray(Thread* thread,
                      RawTypeArguments* type_args,
                      RawObject* length,
-                     uint32_t* pc,
+                     const KBCInstr* pc,
                      RawObject** FP,
                      RawObject** SP);
   bool AllocateContext(Thread* thread,
                        intptr_t num_variables,
-                       uint32_t* pc,
+                       const KBCInstr* pc,
                        RawObject** FP,
                        RawObject** SP);
   bool AllocateClosure(Thread* thread,
-                       uint32_t* pc,
+                       const KBCInstr* pc,
                        RawObject** FP,
                        RawObject** SP);
 
@@ -252,11 +252,11 @@
   bool IsTracingExecution() const;
 
   // Prints bytecode instruction at given pc for instruction tracing.
-  void TraceInstruction(uint32_t* pc) const;
+  void TraceInstruction(const KBCInstr* pc) const;
 
   bool IsWritingTraceFile() const;
   void FlushTraceBuffer();
-  void WriteInstructionToTrace(uint32_t* pc);
+  void WriteInstructionToTrace(const KBCInstr* pc);
 
   void* trace_file_;
   uint64_t trace_file_bytes_written_;
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index 49810ef..ba66dcd 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -884,29 +884,28 @@
       thread_registry_(new ThreadRegistry()),
       safepoint_handler_(new SafepointHandler(this)),
       random_(),
-      mutex_(new Mutex(NOT_IN_PRODUCT("Isolate::mutex_"))),
-      symbols_mutex_(new Mutex(NOT_IN_PRODUCT("Isolate::symbols_mutex_"))),
+      mutex_(NOT_IN_PRODUCT("Isolate::mutex_")),
+      symbols_mutex_(NOT_IN_PRODUCT("Isolate::symbols_mutex_")),
       type_canonicalization_mutex_(
-          new Mutex(NOT_IN_PRODUCT("Isolate::type_canonicalization_mutex_"))),
-      constant_canonicalization_mutex_(new Mutex(
-          NOT_IN_PRODUCT("Isolate::constant_canonicalization_mutex_"))),
+          NOT_IN_PRODUCT("Isolate::type_canonicalization_mutex_")),
+      constant_canonicalization_mutex_(
+          NOT_IN_PRODUCT("Isolate::constant_canonicalization_mutex_")),
       megamorphic_lookup_mutex_(
-          new Mutex(NOT_IN_PRODUCT("Isolate::megamorphic_lookup_mutex_"))),
+          NOT_IN_PRODUCT("Isolate::megamorphic_lookup_mutex_")),
       kernel_data_lib_cache_mutex_(
-          new Mutex(NOT_IN_PRODUCT("Isolate::kernel_data_lib_cache_mutex_"))),
+          NOT_IN_PRODUCT("Isolate::kernel_data_lib_cache_mutex_")),
       kernel_data_class_cache_mutex_(
-          new Mutex(NOT_IN_PRODUCT("Isolate::kernel_data_class_cache_mutex_"))),
+          NOT_IN_PRODUCT("Isolate::kernel_data_class_cache_mutex_")),
       kernel_constants_mutex_(
-          new Mutex(NOT_IN_PRODUCT("Isolate::kernel_constants_mutex_"))),
+          NOT_IN_PRODUCT("Isolate::kernel_constants_mutex_")),
       pending_deopts_(new MallocGrowableArray<PendingLazyDeopt>()),
       tag_table_(GrowableObjectArray::null()),
       deoptimized_code_array_(GrowableObjectArray::null()),
       sticky_error_(Error::null()),
       reloaded_kernel_blobs_(GrowableObjectArray::null()),
-      field_list_mutex_(
-          new Mutex(NOT_IN_PRODUCT("Isolate::field_list_mutex_"))),
+      field_list_mutex_(NOT_IN_PRODUCT("Isolate::field_list_mutex_")),
       boxed_field_list_(GrowableObjectArray::null()),
-      spawn_count_monitor_(new Monitor()),
+      spawn_count_monitor_(),
       handler_info_cache_(),
       catch_entry_moves_cache_() {
   FlagsCopyFrom(api_flags);
@@ -971,22 +970,6 @@
 #if defined(USING_SIMULATOR)
   delete simulator_;
 #endif
-  delete mutex_;
-  mutex_ = nullptr;  // Fail fast if interrupts are scheduled on a dead isolate.
-  delete symbols_mutex_;
-  symbols_mutex_ = nullptr;
-  delete type_canonicalization_mutex_;
-  type_canonicalization_mutex_ = nullptr;
-  delete constant_canonicalization_mutex_;
-  constant_canonicalization_mutex_ = nullptr;
-  delete megamorphic_lookup_mutex_;
-  megamorphic_lookup_mutex_ = nullptr;
-  delete kernel_constants_mutex_;
-  kernel_constants_mutex_ = nullptr;
-  delete kernel_data_lib_cache_mutex_;
-  kernel_data_lib_cache_mutex_ = nullptr;
-  delete kernel_data_class_cache_mutex_;
-  kernel_data_class_cache_mutex_ = nullptr;
   delete pending_deopts_;
   pending_deopts_ = nullptr;
   delete message_handler_;
@@ -995,10 +978,7 @@
   ASSERT(deopt_context_ ==
          nullptr);  // No deopt in progress when isolate deleted.
   delete spawn_state_;
-  delete field_list_mutex_;
-  field_list_mutex_ = nullptr;
   ASSERT(spawn_count_ == 0);
-  delete spawn_count_monitor_;
   delete safepoint_handler_;
   delete thread_registry_;
 
@@ -1306,7 +1286,7 @@
 const char* Isolate::MakeRunnable() {
   ASSERT(Isolate::Current() == nullptr);
 
-  MutexLocker ml(mutex_);
+  MutexLocker ml(&mutex_);
   // Check if we are in a valid state to make the isolate runnable.
   if (is_runnable() == true) {
     return "Isolate is already runnable";
@@ -2338,7 +2318,7 @@
   ASSERT(!field.IsOriginal());
   // The enclosed code allocates objects and can potentially trigger a GC,
   // ensure that we account for safepoints when grabbing the lock.
-  SafepointMutexLocker ml(field_list_mutex_);
+  SafepointMutexLocker ml(&field_list_mutex_);
   if (boxed_field_list_ == GrowableObjectArray::null()) {
     boxed_field_list_ = GrowableObjectArray::New(Heap::kOld);
   }
@@ -2349,7 +2329,7 @@
 
 RawField* Isolate::GetDeoptimizingBoxedField() {
   ASSERT(Thread::Current()->IsMutatorThread());
-  SafepointMutexLocker ml(field_list_mutex_);
+  SafepointMutexLocker ml(&field_list_mutex_);
   if (boxed_field_list_ == GrowableObjectArray::null()) {
     return Field::null();
   }
@@ -2792,12 +2772,19 @@
 }
 
 void Isolate::IncrementSpawnCount() {
-  MonitorLocker ml(spawn_count_monitor_);
+  MonitorLocker ml(&spawn_count_monitor_);
   spawn_count_++;
 }
 
+void Isolate::DecrementSpawnCount() {
+  MonitorLocker ml(&spawn_count_monitor_);
+  ASSERT(spawn_count_ > 0);
+  spawn_count_--;
+  ml.Notify();
+}
+
 void Isolate::WaitForOutstandingSpawns() {
-  MonitorLocker ml(spawn_count_monitor_);
+  MonitorLocker ml(&spawn_count_monitor_);
   while (spawn_count_ > 0) {
     ml.Wait();
   }
@@ -2924,13 +2911,9 @@
 
 IsolateSpawnState::IsolateSpawnState(Dart_Port parent_port,
                                      Dart_Port origin_id,
-                                     void* init_data,
                                      const char* script_url,
                                      const Function& func,
                                      SerializedObjectBuffer* message_buffer,
-                                     Monitor* spawn_count_monitor,
-                                     intptr_t* spawn_count,
-                                     const char* package_root,
                                      const char* package_config,
                                      bool paused,
                                      bool errors_are_fatal,
@@ -2940,11 +2923,9 @@
     : isolate_(nullptr),
       parent_port_(parent_port),
       origin_id_(origin_id),
-      init_data_(init_data),
       on_exit_port_(on_exit_port),
       on_error_port_(on_error_port),
       script_url_(script_url),
-      package_root_(package_root),
       package_config_(package_config),
       library_url_(nullptr),
       class_name_(nullptr),
@@ -2952,8 +2933,6 @@
       debug_name_(debug_name),
       serialized_args_(nullptr),
       serialized_message_(message_buffer->StealMessage()),
-      spawn_count_monitor_(spawn_count_monitor),
-      spawn_count_(spawn_count),
       paused_(paused),
       errors_are_fatal_(errors_are_fatal) {
   const Class& cls = Class::Handle(func.Owner());
@@ -2975,14 +2954,10 @@
 }
 
 IsolateSpawnState::IsolateSpawnState(Dart_Port parent_port,
-                                     void* init_data,
                                      const char* script_url,
-                                     const char* package_root,
                                      const char* package_config,
                                      SerializedObjectBuffer* args_buffer,
                                      SerializedObjectBuffer* message_buffer,
-                                     Monitor* spawn_count_monitor,
-                                     intptr_t* spawn_count,
                                      bool paused,
                                      bool errors_are_fatal,
                                      Dart_Port on_exit_port,
@@ -2991,11 +2966,9 @@
     : isolate_(nullptr),
       parent_port_(parent_port),
       origin_id_(ILLEGAL_PORT),
-      init_data_(init_data),
       on_exit_port_(on_exit_port),
       on_error_port_(on_error_port),
       script_url_(script_url),
-      package_root_(package_root),
       package_config_(package_config),
       library_url_(nullptr),
       class_name_(nullptr),
@@ -3003,8 +2976,6 @@
       debug_name_(debug_name),
       serialized_args_(args_buffer->StealMessage()),
       serialized_message_(message_buffer->StealMessage()),
-      spawn_count_monitor_(spawn_count_monitor),
-      spawn_count_(spawn_count),
       isolate_flags_(),
       paused_(paused),
       errors_are_fatal_(errors_are_fatal) {
@@ -3017,7 +2988,6 @@
 
 IsolateSpawnState::~IsolateSpawnState() {
   delete[] script_url_;
-  delete[] package_root_;
   delete[] package_config_;
   delete[] library_url_;
   delete[] class_name_;
@@ -3110,13 +3080,4 @@
   return DeserializeMessage(thread, serialized_message_.get());
 }
 
-void IsolateSpawnState::DecrementSpawnCount() {
-  ASSERT(spawn_count_monitor_ != nullptr);
-  ASSERT(spawn_count_ != nullptr);
-  MonitorLocker ml(spawn_count_monitor_);
-  ASSERT(*spawn_count_ > 0);
-  *spawn_count_ = *spawn_count_ - 1;
-  ml.Notify();
-}
-
 }  // namespace dart
diff --git a/runtime/vm/isolate.h b/runtime/vm/isolate.h
index f0484c9..914a40f 100644
--- a/runtime/vm/isolate.h
+++ b/runtime/vm/isolate.h
@@ -16,6 +16,7 @@
 #include "platform/atomic.h"
 #include "vm/base_isolate.h"
 #include "vm/class_table.h"
+#include "vm/constants_kbc.h"
 #include "vm/exceptions.h"
 #include "vm/fixed_cache.h"
 #include "vm/growable_array.h"
@@ -348,26 +349,22 @@
   IsolateSpawnState* spawn_state() const { return spawn_state_; }
   void set_spawn_state(IsolateSpawnState* value) { spawn_state_ = value; }
 
-  Mutex* mutex() const { return mutex_; }
-  Mutex* symbols_mutex() const { return symbols_mutex_; }
-  Mutex* type_canonicalization_mutex() const {
-    return type_canonicalization_mutex_;
+  Mutex* mutex() { return &mutex_; }
+  Mutex* symbols_mutex() { return &symbols_mutex_; }
+  Mutex* type_canonicalization_mutex() { return &type_canonicalization_mutex_; }
+  Mutex* constant_canonicalization_mutex() {
+    return &constant_canonicalization_mutex_;
   }
-  Mutex* constant_canonicalization_mutex() const {
-    return constant_canonicalization_mutex_;
-  }
-  Mutex* megamorphic_lookup_mutex() const { return megamorphic_lookup_mutex_; }
+  Mutex* megamorphic_lookup_mutex() { return &megamorphic_lookup_mutex_; }
 
-  Mutex* kernel_data_lib_cache_mutex() const {
-    return kernel_data_lib_cache_mutex_;
-  }
-  Mutex* kernel_data_class_cache_mutex() const {
-    return kernel_data_class_cache_mutex_;
+  Mutex* kernel_data_lib_cache_mutex() { return &kernel_data_lib_cache_mutex_; }
+  Mutex* kernel_data_class_cache_mutex() {
+    return &kernel_data_class_cache_mutex_;
   }
 
   // Any access to constants arrays must be locked since mutator and
   // background compiler can access the arrays at the same time.
-  Mutex* kernel_constants_mutex() const { return kernel_constants_mutex_; }
+  Mutex* kernel_constants_mutex() { return &kernel_constants_mutex_; }
 
 #if !defined(PRODUCT)
   Debugger* debugger() const {
@@ -433,10 +430,8 @@
   Simulator* simulator() const { return simulator_; }
   void set_simulator(Simulator* value) { simulator_ = value; }
 
-  Monitor* spawn_count_monitor() const { return spawn_count_monitor_; }
-  intptr_t* spawn_count() { return &spawn_count_; }
-
   void IncrementSpawnCount();
+  void DecrementSpawnCount();
   void WaitForOutstandingSpawns();
 
   static void SetCreateCallback(Dart_IsolateCreateCallback cb) {
@@ -783,6 +778,23 @@
     return !unsafe_trust_strong_mode_types();
   }
 
+  static_assert(KernelBytecode::kMinSupportedBytecodeFormatVersion < 7,
+                "Cleanup support for old bytecode format versions");
+  bool is_using_old_bytecode_instructions() const {
+    return UsingOldBytecodeInstructionsBit::decode(isolate_flags_);
+  }
+  void set_is_using_old_bytecode_instructions(bool value) {
+    isolate_flags_ =
+        UsingOldBytecodeInstructionsBit::update(value, isolate_flags_);
+  }
+  bool is_using_new_bytecode_instructions() const {
+    return UsingNewBytecodeInstructionsBit::decode(isolate_flags_);
+  }
+  void set_is_using_new_bytecode_instructions(bool value) {
+    isolate_flags_ =
+        UsingNewBytecodeInstructionsBit::update(value, isolate_flags_);
+  }
+
   static void KillAllIsolates(LibMsgId msg_id);
   static void KillIfExists(Isolate* isolate, LibMsgId msg_id);
 
@@ -907,7 +919,13 @@
   V(Obfuscate)                                                                 \
   V(CompactionInProgress)                                                      \
   V(ShouldLoadVmService)                                                       \
-  V(UnsafeTrustStrongModeTypes)
+  V(UnsafeTrustStrongModeTypes)                                                \
+  V(UsingOldBytecodeInstructions)                                              \
+  V(UsingNewBytecodeInstructions)
+
+  static_assert(
+      KernelBytecode::kMinSupportedBytecodeFormatVersion < 7,
+      "Cleanup UsingOldBytecodeInstructions and UsingNewBytecodeInstructions");
 
   // Isolate specific flags.
   enum FlagBits {
@@ -997,14 +1015,14 @@
   ApiState* api_state_ = nullptr;
   Random random_;
   Simulator* simulator_ = nullptr;
-  Mutex* mutex_;          // Protects compiler stats.
-  Mutex* symbols_mutex_;  // Protects concurrent access to the symbol table.
-  Mutex* type_canonicalization_mutex_;      // Protects type canonicalization.
-  Mutex* constant_canonicalization_mutex_;  // Protects const canonicalization.
-  Mutex* megamorphic_lookup_mutex_;  // Protects megamorphic table lookup.
-  Mutex* kernel_data_lib_cache_mutex_;
-  Mutex* kernel_data_class_cache_mutex_;
-  Mutex* kernel_constants_mutex_;
+  Mutex mutex_;          // Protects compiler stats.
+  Mutex symbols_mutex_;  // Protects concurrent access to the symbol table.
+  Mutex type_canonicalization_mutex_;      // Protects type canonicalization.
+  Mutex constant_canonicalization_mutex_;  // Protects const canonicalization.
+  Mutex megamorphic_lookup_mutex_;         // Protects megamorphic table lookup.
+  Mutex kernel_data_lib_cache_mutex_;
+  Mutex kernel_data_class_cache_mutex_;
+  Mutex kernel_constants_mutex_;
   MessageHandler* message_handler_ = nullptr;
   IsolateSpawnState* spawn_state_ = nullptr;
   intptr_t defer_finalization_count_ = 0;
@@ -1032,13 +1050,13 @@
   intptr_t loading_invalidation_gen_ = kInvalidGen;
 
   // Protect access to boxed_field_list_.
-  Mutex* field_list_mutex_;
+  Mutex field_list_mutex_;
   // List of fields that became boxed and that trigger deoptimization.
   RawGrowableObjectArray* boxed_field_list_;
 
   // This guards spawn_count_. An isolate cannot complete shutdown and be
   // destroyed while there are child isolates in the midst of a spawn.
-  Monitor* spawn_count_monitor_;
+  Monitor spawn_count_monitor_;
   intptr_t spawn_count_ = 0;
 
   HandlerInfoCache handler_info_cache_;
@@ -1130,13 +1148,9 @@
  public:
   IsolateSpawnState(Dart_Port parent_port,
                     Dart_Port origin_id,
-                    void* init_data,
                     const char* script_url,
                     const Function& func,
                     SerializedObjectBuffer* message_buffer,
-                    Monitor* spawn_count_monitor,
-                    intptr_t* spawn_count,
-                    const char* package_root,
                     const char* package_config,
                     bool paused,
                     bool errorsAreFatal,
@@ -1144,14 +1158,10 @@
                     Dart_Port onError,
                     const char* debug_name);
   IsolateSpawnState(Dart_Port parent_port,
-                    void* init_data,
                     const char* script_url,
-                    const char* package_root,
                     const char* package_config,
                     SerializedObjectBuffer* args_buffer,
                     SerializedObjectBuffer* message_buffer,
-                    Monitor* spawn_count_monitor,
-                    intptr_t* spawn_count,
                     bool paused,
                     bool errorsAreFatal,
                     Dart_Port onExit,
@@ -1164,11 +1174,9 @@
 
   Dart_Port parent_port() const { return parent_port_; }
   Dart_Port origin_id() const { return origin_id_; }
-  void* init_data() const { return init_data_; }
   Dart_Port on_exit_port() const { return on_exit_port_; }
   Dart_Port on_error_port() const { return on_error_port_; }
   const char* script_url() const { return script_url_; }
-  const char* package_root() const { return package_root_; }
   const char* package_config() const { return package_config_; }
   const char* library_url() const { return library_url_; }
   const char* class_name() const { return class_name_; }
@@ -1183,17 +1191,13 @@
   RawInstance* BuildArgs(Thread* thread);
   RawInstance* BuildMessage(Thread* thread);
 
-  void DecrementSpawnCount();
-
  private:
   Isolate* isolate_;
   Dart_Port parent_port_;
   Dart_Port origin_id_;
-  void* init_data_;
   Dart_Port on_exit_port_;
   Dart_Port on_error_port_;
   const char* script_url_;
-  const char* package_root_;
   const char* package_config_;
   const char* library_url_;
   const char* class_name_;
@@ -1202,11 +1206,6 @@
   std::unique_ptr<Message> serialized_args_;
   std::unique_ptr<Message> serialized_message_;
 
-  // This counter tracks the number of outstanding calls to spawn by the parent
-  // isolate.
-  Monitor* spawn_count_monitor_;
-  intptr_t* spawn_count_;
-
   Dart_IsolateFlags isolate_flags_;
   bool paused_;
   bool errors_are_fatal_;
diff --git a/runtime/vm/isolate_reload.cc b/runtime/vm/isolate_reload.cc
index 30bedb0..2cd529b 100644
--- a/runtime/vm/isolate_reload.cc
+++ b/runtime/vm/isolate_reload.cc
@@ -453,6 +453,7 @@
       error_(Error::null()),
       old_classes_set_storage_(Array::null()),
       class_map_storage_(Array::null()),
+      removed_class_set_storage_(Array::null()),
       old_libraries_set_storage_(Array::null()),
       library_map_storage_(Array::null()),
       become_map_storage_(Array::null()),
@@ -699,6 +700,8 @@
   old_classes_set_storage_ =
       HashTables::New<UnorderedHashSet<ClassMapTraits> >(4);
   class_map_storage_ = HashTables::New<UnorderedHashMap<ClassMapTraits> >(4);
+  removed_class_set_storage_ =
+      HashTables::New<UnorderedHashSet<ClassMapTraits> >(4);
   old_libraries_set_storage_ =
       HashTables::New<UnorderedHashSet<LibraryMapTraits> >(4);
   library_map_storage_ =
@@ -841,6 +844,8 @@
     return;
   }
   BuildLibraryMapping();
+  BuildRemovedClassesSet();
+
   TIR_Print("---- LOAD SUCCEEDED\n");
   if (ValidateReload()) {
     Commit();
@@ -1475,6 +1480,18 @@
     }
 
     class_map.Release();
+
+    {
+      UnorderedHashSet<ClassMapTraits> removed_class_set(
+          removed_class_set_storage_);
+      UnorderedHashSet<ClassMapTraits>::Iterator it(&removed_class_set);
+      while (it.MoveNext()) {
+        const intptr_t entry = it.Current();
+        old_cls ^= removed_class_set.GetKey(entry);
+        old_cls.PatchFieldsAndFunctions();
+      }
+      removed_class_set.Release();
+    }
   }
 
   if (FLAG_identity_reload) {
@@ -2158,6 +2175,86 @@
   }
 }
 
+// Find classes that have been removed from the program.
+// Instances of these classes may still be referenced from variables, so the
+// functions of these class may still execute in the future, and they need to
+// be given patch class owners still they correctly reference their (old) kernel
+// data even after the library's kernel data is updated.
+//
+// Note that all such classes must belong to a library that has either been
+// changed or removed.
+void IsolateReloadContext::BuildRemovedClassesSet() {
+  // Find all old classes [mapped_old_classes_set].
+  UnorderedHashMap<ClassMapTraits> class_map(class_map_storage_);
+  UnorderedHashSet<ClassMapTraits> mapped_old_classes_set(
+      HashTables::New<UnorderedHashSet<ClassMapTraits> >(
+          class_map.NumOccupied()));
+  {
+    UnorderedHashMap<ClassMapTraits>::Iterator it(&class_map);
+    Class& cls = Class::Handle();
+    Class& new_cls = Class::Handle();
+    while (it.MoveNext()) {
+      const intptr_t entry = it.Current();
+      new_cls = Class::RawCast(class_map.GetKey(entry));
+      cls = Class::RawCast(class_map.GetPayload(entry, 0));
+      mapped_old_classes_set.InsertOrGet(cls);
+    }
+  }
+  class_map.Release();
+
+  // Find all reloaded libraries [mapped_old_library_set].
+  UnorderedHashMap<LibraryMapTraits> library_map(library_map_storage_);
+  UnorderedHashMap<LibraryMapTraits>::Iterator it_library(&library_map);
+  UnorderedHashSet<LibraryMapTraits> mapped_old_library_set(
+      HashTables::New<UnorderedHashSet<LibraryMapTraits> >(
+          library_map.NumOccupied()));
+  {
+    Library& old_library = Library::Handle();
+    Library& new_library = Library::Handle();
+    while (it_library.MoveNext()) {
+      const intptr_t entry = it_library.Current();
+      new_library ^= library_map.GetKey(entry);
+      old_library ^= library_map.GetPayload(entry, 0);
+      if (new_library.raw() != old_library.raw()) {
+        mapped_old_library_set.InsertOrGet(old_library);
+      }
+    }
+  }
+
+  // For every old class, check if it's library was reloaded and if
+  // the class was mapped. If the class wasn't mapped - add it to
+  // [removed_class_set].
+  UnorderedHashSet<ClassMapTraits> old_classes_set(old_classes_set_storage_);
+  UnorderedHashSet<ClassMapTraits>::Iterator it(&old_classes_set);
+  UnorderedHashSet<ClassMapTraits> removed_class_set(
+      removed_class_set_storage_);
+  Class& old_cls = Class::Handle();
+  Class& new_cls = Class::Handle();
+  Library& old_library = Library::Handle();
+  Library& mapped_old_library = Library::Handle();
+  while (it.MoveNext()) {
+    const intptr_t entry = it.Current();
+    old_cls ^= Class::RawCast(old_classes_set.GetKey(entry));
+    old_library = old_cls.library();
+    if (old_library.IsNull()) {
+      continue;
+    }
+    mapped_old_library ^= mapped_old_library_set.GetOrNull(old_library);
+    if (!mapped_old_library.IsNull()) {
+      new_cls ^= mapped_old_classes_set.GetOrNull(old_cls);
+      if (new_cls.IsNull()) {
+        removed_class_set.InsertOrGet(old_cls);
+      }
+    }
+  }
+  removed_class_set_storage_ = removed_class_set.Release().raw();
+
+  old_classes_set.Release();
+  mapped_old_classes_set.Release();
+  mapped_old_library_set.Release();
+  library_map.Release();
+}
+
 void IsolateReloadContext::AddClassMapping(const Class& replacement_or_new,
                                            const Class& original) {
   UnorderedHashMap<ClassMapTraits> map(class_map_storage_);
diff --git a/runtime/vm/isolate_reload.h b/runtime/vm/isolate_reload.h
index e8dbfe5..f21c539 100644
--- a/runtime/vm/isolate_reload.h
+++ b/runtime/vm/isolate_reload.h
@@ -327,6 +327,7 @@
   RawLibrary* OldLibraryOrNullBaseMoved(const Library& replacement_or_new);
 
   void BuildLibraryMapping();
+  void BuildRemovedClassesSet();
 
   void AddClassMapping(const Class& replacement_or_new, const Class& original);
 
@@ -348,6 +349,7 @@
   RawError* error_;
   RawArray* old_classes_set_storage_;
   RawArray* class_map_storage_;
+  RawArray* removed_class_set_storage_;
   RawArray* old_libraries_set_storage_;
   RawArray* library_map_storage_;
   RawArray* become_map_storage_;
diff --git a/runtime/vm/isolate_reload_test.cc b/runtime/vm/isolate_reload_test.cc
index 8a26648..c331a87 100644
--- a/runtime/vm/isolate_reload_test.cc
+++ b/runtime/vm/isolate_reload_test.cc
@@ -578,6 +578,32 @@
   EXPECT_STREQ("hello from A", SimpleInvokeStr(lib, "main"));
 }
 
+TEST_CASE(IsolateReload_ClassRemoved) {
+  const char* kScript =
+      "class A {\n"
+      "  toString() => 'hello from A';\n"
+      "}\n"
+      "List<dynamic> list = <dynamic>[];"
+      "main() {\n"
+      "  list.add(new A());\n"
+      "  return list[0].toString();\n"
+      "}\n";
+
+  Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
+  EXPECT_VALID(lib);
+  EXPECT_STREQ("hello from A", SimpleInvokeStr(lib, "main"));
+
+  const char* kReloadScript =
+      "List<dynamic> list = <dynamic>[];\n"
+      "main() {\n"
+      "  return list[0].toString();\n"
+      "}\n";
+
+  lib = TestCase::ReloadTestScript(kReloadScript);
+  EXPECT_VALID(lib);
+  EXPECT_STREQ("hello from A", SimpleInvokeStr(lib, "main"));
+}
+
 TEST_CASE(IsolateReload_LibraryImportAdded) {
   const char* kScript =
       "main() {\n"
diff --git a/runtime/vm/kernel_isolate.cc b/runtime/vm/kernel_isolate.cc
index 660934f..ef25d78 100644
--- a/runtime/vm/kernel_isolate.cc
+++ b/runtime/vm/kernel_isolate.cc
@@ -388,7 +388,7 @@
 class KernelCompilationRequest : public ValueObject {
  public:
   KernelCompilationRequest()
-      : monitor_(new Monitor()),
+      : monitor_(),
         port_(Dart_NewNativePort("kernel-compilation-port",
                                  &HandleResponse,
                                  false)),
@@ -405,7 +405,6 @@
   ~KernelCompilationRequest() {
     UnregisterRequest(this);
     Dart_CloseNativePort(port_);
-    delete monitor_;
   }
 
   Dart_KernelCompilationResult SendAndWaitForResponse(
@@ -527,7 +526,7 @@
 
       // Wait for reply to arrive.
       VMTagScope tagScope(thread, VMTag::kLoadWaitTagId);
-      MonitorLocker ml(monitor_);
+      MonitorLocker ml(&monitor_);
       while (result_.status == Dart_KernelCompilationStatus_Unknown) {
         ml.Wait();
       }
@@ -715,7 +714,7 @@
 
     // Wait for reply to arrive.
     VMTagScope tagScope(Thread::Current(), VMTag::kLoadWaitTagId);
-    MonitorLocker ml(monitor_);
+    MonitorLocker ml(&monitor_);
     while (result_.status == Dart_KernelCompilationStatus_Unknown) {
       ml.Wait();
     }
@@ -756,7 +755,7 @@
 
     Dart_CObject** response = message->value.as_array.values;
 
-    MonitorLocker ml(monitor_);
+    MonitorLocker ml(&monitor_);
 
     ASSERT(response[0]->type == Dart_CObject_kInt32);
     result_.status = static_cast<Dart_KernelCompilationStatus>(
@@ -822,7 +821,7 @@
   // Guarded by requests_monitor_ lock.
   static KernelCompilationRequest* requests_;
 
-  Monitor* monitor_;
+  Monitor monitor_;
   Dart_Port port_;
 
   // Linked list of active requests. Guarded by requests_monitor_ lock.
diff --git a/runtime/vm/message.cc b/runtime/vm/message.cc
index 4d08a30..542ccc0 100644
--- a/runtime/vm/message.cc
+++ b/runtime/vm/message.cc
@@ -11,6 +11,8 @@
 
 namespace dart {
 
+const Dart_Port Message::kIllegalPort;
+
 Message::Message(Dart_Port dest_port,
                  uint8_t* snapshot,
                  intptr_t snapshot_length,
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 9e94f0d..73cf977 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -443,6 +443,21 @@
   return '\0';
 }
 
+static RawBytecode* CreateVMInternalBytecode(KernelBytecode::Opcode opcode) {
+  const KBCInstr* instructions = nullptr;
+  intptr_t instructions_size = 0;
+
+  KernelBytecode::GetVMInternalBytecodeInstructions(opcode, &instructions,
+                                                    &instructions_size);
+
+  const auto& bytecode = Bytecode::Handle(
+      Bytecode::New(reinterpret_cast<uword>(instructions), instructions_size,
+                    -1, Object::empty_object_pool()));
+  bytecode.set_pc_descriptors(Object::empty_descriptors());
+  bytecode.set_exception_handlers(Object::empty_exception_handlers());
+  return bytecode.raw();
+}
+
 void Object::InitNull(Isolate* isolate) {
   // Should only be run by the vm isolate.
   ASSERT(isolate == Dart::vm_isolate());
@@ -880,84 +895,26 @@
   // needs to be created earlier as VM isolate snapshot reader references it
   // before Object::FinalizeVMIsolate.
 
-  static const KBCInstr getter_instr[2] = {
-      KernelBytecode::Encode(KernelBytecode::kVMInternal_ImplicitGetter),
-      KernelBytecode::Encode(KernelBytecode::kReturnTOS),
-  };
   *implicit_getter_bytecode_ =
-      Bytecode::New(reinterpret_cast<uword>(getter_instr), sizeof(getter_instr),
-                    -1, Object::empty_object_pool());
-  implicit_getter_bytecode_->set_pc_descriptors(Object::empty_descriptors());
-  implicit_getter_bytecode_->set_exception_handlers(
-      Object::empty_exception_handlers());
+      CreateVMInternalBytecode(KernelBytecode::kVMInternal_ImplicitGetter);
 
-  static const KBCInstr setter_instr[2] = {
-      KernelBytecode::Encode(KernelBytecode::kVMInternal_ImplicitSetter),
-      KernelBytecode::Encode(KernelBytecode::kReturnTOS),
-  };
   *implicit_setter_bytecode_ =
-      Bytecode::New(reinterpret_cast<uword>(setter_instr), sizeof(setter_instr),
-                    -1, Object::empty_object_pool());
-  implicit_setter_bytecode_->set_pc_descriptors(Object::empty_descriptors());
-  implicit_setter_bytecode_->set_exception_handlers(
-      Object::empty_exception_handlers());
+      CreateVMInternalBytecode(KernelBytecode::kVMInternal_ImplicitSetter);
 
-  static const KBCInstr static_getter_instr[2] = {
-      KernelBytecode::Encode(KernelBytecode::kVMInternal_ImplicitStaticGetter),
-      KernelBytecode::Encode(KernelBytecode::kReturnTOS),
-  };
-  *implicit_static_getter_bytecode_ = Bytecode::New(
-      reinterpret_cast<uword>(static_getter_instr), sizeof(static_getter_instr),
-      -1, Object::empty_object_pool());
-  implicit_static_getter_bytecode_->set_pc_descriptors(
-      Object::empty_descriptors());
-  implicit_static_getter_bytecode_->set_exception_handlers(
-      Object::empty_exception_handlers());
+  *implicit_static_getter_bytecode_ = CreateVMInternalBytecode(
+      KernelBytecode::kVMInternal_ImplicitStaticGetter);
 
-  static const KBCInstr method_extractor_instr[2] = {
-      KernelBytecode::Encode(KernelBytecode::kVMInternal_MethodExtractor),
-      KernelBytecode::Encode(KernelBytecode::kReturnTOS),
-  };
-  *method_extractor_bytecode_ = Bytecode::New(
-      reinterpret_cast<uword>(method_extractor_instr),
-      sizeof(method_extractor_instr), -1, Object::empty_object_pool());
-  method_extractor_bytecode_->set_pc_descriptors(Object::empty_descriptors());
-  method_extractor_bytecode_->set_exception_handlers(
-      Object::empty_exception_handlers());
+  *method_extractor_bytecode_ =
+      CreateVMInternalBytecode(KernelBytecode::kVMInternal_MethodExtractor);
 
-  static const KBCInstr invoke_closure_instr[2] = {
-      KernelBytecode::Encode(KernelBytecode::kVMInternal_InvokeClosure),
-      KernelBytecode::Encode(KernelBytecode::kReturnTOS),
-  };
-  *invoke_closure_bytecode_ = Bytecode::New(
-      reinterpret_cast<uword>(invoke_closure_instr),
-      sizeof(invoke_closure_instr), -1, Object::empty_object_pool());
-  invoke_closure_bytecode_->set_pc_descriptors(Object::empty_descriptors());
-  invoke_closure_bytecode_->set_exception_handlers(
-      Object::empty_exception_handlers());
+  *invoke_closure_bytecode_ =
+      CreateVMInternalBytecode(KernelBytecode::kVMInternal_InvokeClosure);
 
-  static const KBCInstr invoke_field_instr[2] = {
-      KernelBytecode::Encode(KernelBytecode::kVMInternal_InvokeField),
-      KernelBytecode::Encode(KernelBytecode::kReturnTOS),
-  };
-  *invoke_field_bytecode_ = Bytecode::New(
-      reinterpret_cast<uword>(invoke_field_instr), sizeof(invoke_field_instr),
-      -1, Object::empty_object_pool());
-  invoke_field_bytecode_->set_pc_descriptors(Object::empty_descriptors());
-  invoke_field_bytecode_->set_exception_handlers(
-      Object::empty_exception_handlers());
+  *invoke_field_bytecode_ =
+      CreateVMInternalBytecode(KernelBytecode::kVMInternal_InvokeField);
 
-  static const KBCInstr nsm_dispatcher_instr[2] = {
-      KernelBytecode::Encode(
-          KernelBytecode::kVMInternal_NoSuchMethodDispatcher),
-      KernelBytecode::Encode(KernelBytecode::kReturnTOS),
-  };
-  *nsm_dispatcher_bytecode_ = Bytecode::New(
-      reinterpret_cast<uword>(nsm_dispatcher_instr),
-      sizeof(nsm_dispatcher_instr), -1, Object::empty_object_pool());
-  nsm_dispatcher_bytecode_->set_pc_descriptors(Object::empty_descriptors());
-  nsm_dispatcher_bytecode_->set_exception_handlers(
-      Object::empty_exception_handlers());
+  *nsm_dispatcher_bytecode_ = CreateVMInternalBytecode(
+      KernelBytecode::kVMInternal_NoSuchMethodDispatcher);
 
   // Some thread fields need to be reinitialized as null constants have not been
   // initialized until now.
@@ -3048,12 +3005,14 @@
 }
 
 bool Library::FindPragma(Thread* T,
+                         bool only_core,
                          const Object& obj,
                          const String& pragma_name,
-                         Object* options) const {
+                         Object* options) {
   auto I = T->isolate();
   auto Z = T->zone();
   auto& lib = Library::Handle(Z);
+
   if (obj.IsClass()) {
     auto& klass = Class::Cast(obj);
     if (!klass.has_pragma()) return false;
@@ -3070,6 +3029,10 @@
     UNREACHABLE();
   }
 
+  if (only_core && !lib.IsAnyCoreLibrary()) {
+    return false;
+  }
+
   Object& metadata_obj = Object::Handle(Z, lib.GetMetadata(obj));
   if (metadata_obj.IsUnwindError()) {
     Report::LongJump(UnwindError::Cast(metadata_obj));
@@ -7314,20 +7277,19 @@
 RawFunction* Function::NewClosureFunctionWithKind(RawFunction::Kind kind,
                                                   const String& name,
                                                   const Function& parent,
-                                                  TokenPosition token_pos) {
+                                                  TokenPosition token_pos,
+                                                  const Object& owner) {
   ASSERT((kind == RawFunction::kClosureFunction) ||
          (kind == RawFunction::kImplicitClosureFunction));
   ASSERT(!parent.IsNull());
-  // Use the owner defining the parent function and not the class containing it.
-  const Object& parent_owner = Object::Handle(parent.raw_ptr()->owner_);
-  ASSERT(!parent_owner.IsNull());
+  ASSERT(!owner.IsNull());
   const Function& result = Function::Handle(
       Function::New(name, kind,
                     /* is_static = */ parent.is_static(),
                     /* is_const = */ false,
                     /* is_abstract = */ false,
                     /* is_external = */ false,
-                    /* is_native = */ false, parent_owner, token_pos));
+                    /* is_native = */ false, owner, token_pos));
   result.set_parent_function(parent);
   return result.raw();
 }
@@ -7335,15 +7297,19 @@
 RawFunction* Function::NewClosureFunction(const String& name,
                                           const Function& parent,
                                           TokenPosition token_pos) {
+  // Use the owner defining the parent function and not the class containing it.
+  const Object& parent_owner = Object::Handle(parent.RawOwner());
   return NewClosureFunctionWithKind(RawFunction::kClosureFunction, name, parent,
-                                    token_pos);
+                                    token_pos, parent_owner);
 }
 
 RawFunction* Function::NewImplicitClosureFunction(const String& name,
                                                   const Function& parent,
                                                   TokenPosition token_pos) {
+  // Use the owner defining the parent function and not the class containing it.
+  const Object& parent_owner = Object::Handle(parent.RawOwner());
   return NewClosureFunctionWithKind(RawFunction::kImplicitClosureFunction, name,
-                                    parent, token_pos);
+                                    parent, token_pos, parent_owner);
 }
 
 RawFunction* Function::NewSignatureFunction(const Object& owner,
@@ -7754,19 +7720,19 @@
       return script.raw();
     }
   }
+  const Object& obj = Object::Handle(raw_ptr()->owner_);
+  if (obj.IsPatchClass()) {
+    return PatchClass::Cast(obj).script();
+  }
   if (IsClosureFunction()) {
     return Function::Handle(parent_function()).script();
   }
-  const Object& obj = Object::Handle(raw_ptr()->owner_);
   if (obj.IsNull()) {
     ASSERT(IsSignatureFunction());
     return Script::null();
   }
-  if (obj.IsClass()) {
-    return Class::Cast(obj).script();
-  }
-  ASSERT(obj.IsPatchClass());
-  return PatchClass::Cast(obj).script();
+  ASSERT(obj.IsClass());
+  return Class::Cast(obj).script();
 }
 
 RawExternalTypedData* Function::KernelData() const {
@@ -11414,6 +11380,15 @@
   return private_name;
 }
 
+bool Library::IsPrivateCoreLibName(const String& name, const String& member) {
+  Zone* zone = Thread::Current()->zone();
+  const auto& core_lib = Library::Handle(zone, Library::CoreLibrary());
+  const auto& private_key = String::Handle(zone, core_lib.private_key());
+
+  ASSERT(core_lib.IsPrivate(member));
+  return name.EqualsConcat(member, private_key);
+}
+
 RawClass* Library::LookupCoreClass(const String& class_name) {
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
@@ -13499,7 +13474,8 @@
   }
   // The final entry is always the sentinel.
   ASSERT(IsSentinelAt(len - 1));
-  if (NumArgsTested() == 0) {
+  const intptr_t num_args_tested = NumArgsTested();
+  if (num_args_tested == 0) {
     // No type feedback is being collected.
     const Array& data = Array::Handle(entries());
     // Static calls with no argument checks hold only one target and the
@@ -13508,11 +13484,11 @@
     // Static calls with no argument checks only need two words.
     ASSERT(TestEntryLength() == 2);
     // Set the target.
-    data.SetAt(0, func);
+    data.SetAt(TargetIndexFor(num_args_tested), func);
     // Set count to 0 as this is called during compilation, before the
     // call has been executed.
     const Smi& value = Smi::Handle(Smi::New(0));
-    data.SetAt(1, value);
+    data.SetAt(CountIndexFor(num_args_tested), value);
   } else {
     // Type feedback on arguments is being collected.
     const Array& data = Array::Handle(entries());
@@ -13526,9 +13502,9 @@
     for (intptr_t i = 0; i < NumArgsTested(); i++) {
       data.SetAt(i, object_cid);
     }
-    data.SetAt(NumArgsTested(), func);
+    data.SetAt(TargetIndexFor(num_args_tested), func);
     const Smi& value = Smi::Handle(Smi::New(0));
-    data.SetAt(NumArgsTested() + 1, value);
+    data.SetAt(CountIndexFor(num_args_tested), value);
   }
 }
 
@@ -13598,11 +13574,11 @@
   WriteSentinel(data, TestEntryLength());
   intptr_t data_pos = old_num * TestEntryLength();
   ASSERT(!target.IsNull());
-  data.SetAt(data_pos++, target);
+  data.SetAt(data_pos + TargetIndexFor(NumArgsTested()), target);
   // Set count to 0 as this is called during compilation, before the
   // call has been executed.
   const Smi& value = Smi::Handle(Smi::New(0));
-  data.SetAt(data_pos, value);
+  data.SetAt(data_pos + CountIndexFor(NumArgsTested()), value);
   // Multithreaded access to ICData requires setting of array to be the last
   // operation.
   set_entries(data);
@@ -13633,7 +13609,8 @@
   ASSERT((target.name() == target_name()) || ValidateInterceptor(target));
   DEBUG_ASSERT(!HasCheck(class_ids));
   ASSERT(NumArgsTested() > 1);  // Otherwise use 'AddReceiverCheck'.
-  ASSERT(class_ids.length() == NumArgsTested());
+  const intptr_t num_args_tested = NumArgsTested();
+  ASSERT(class_ids.length() == num_args_tested);
   const intptr_t old_num = NumberOfChecks();
   Array& data = Array::Handle(entries());
   // ICData of static calls with NumArgsTested() > 0 have initially a
@@ -13641,14 +13618,14 @@
   // overwritten by first real type feedback data.
   if (old_num == 1) {
     bool has_dummy_entry = true;
-    for (intptr_t i = 0; i < NumArgsTested(); i++) {
+    for (intptr_t i = 0; i < num_args_tested; i++) {
       if (Smi::Value(Smi::RawCast(data.At(i))) != kObjectCid) {
         has_dummy_entry = false;
         break;
       }
     }
     if (has_dummy_entry) {
-      ASSERT(target.raw() == data.At(NumArgsTested()));
+      ASSERT(target.raw() == data.At(TargetIndexFor(num_args_tested)));
       // Replace dummy entry.
       Smi& value = Smi::Handle();
       for (intptr_t i = 0; i < NumArgsTested(); i++) {
@@ -13668,12 +13645,12 @@
     // kIllegalCid is used as terminating value, do not add it.
     ASSERT(class_ids[i] != kIllegalCid);
     value = Smi::New(class_ids[i]);
-    data.SetAt(data_pos++, value);
+    data.SetAt(data_pos + i, value);
   }
   ASSERT(!target.IsNull());
-  data.SetAt(data_pos++, target);
+  data.SetAt(data_pos + TargetIndexFor(num_args_tested), target);
   value = Smi::New(count);
-  data.SetAt(data_pos++, value);
+  data.SetAt(data_pos + CountIndexFor(num_args_tested), value);
   // Multithreaded access to ICData requires setting of array to be the last
   // operation.
   set_entries(data);
@@ -13722,7 +13699,8 @@
   ASSERT(!HasCheck(class_ids));
 #endif  // DEBUG
   ASSERT(!target.IsNull());
-  ASSERT(NumArgsTested() == 1);  // Otherwise use 'AddCheck'.
+  const intptr_t kNumArgsTested = 1;
+  ASSERT(NumArgsTested() == kNumArgsTested);  // Otherwise use 'AddCheck'.
   ASSERT(receiver_class_id != kIllegalCid);
 
   intptr_t index = -1;
@@ -13739,10 +13717,12 @@
   }
   data.SetAt(data_pos, Smi::Handle(Smi::New(receiver_class_id)));
   if (Isolate::Current()->compilation_allowed()) {
-    data.SetAt(data_pos + 1, target);
-    data.SetAt(data_pos + 2, Smi::Handle(Smi::New(count)));
+    data.SetAt(data_pos + TargetIndexFor(kNumArgsTested), target);
+    data.SetAt(data_pos + CountIndexFor(kNumArgsTested),
+               Smi::Handle(Smi::New(count)));
     if (is_tracking_exactness()) {
-      data.SetAt(data_pos + 3, Smi::Handle(Smi::New(exactness.Encode())));
+      data.SetAt(data_pos + ExactnessIndexFor(kNumArgsTested),
+                 Smi::Handle(Smi::New(exactness.Encode())));
     }
   } else {
     // Precompilation only, after all functions have been compiled.
@@ -13750,8 +13730,8 @@
     const Code& code = Code::Handle(target.CurrentCode());
     const Smi& entry_point =
         Smi::Handle(Smi::FromAlignedAddress(code.EntryPoint()));
-    data.SetAt(data_pos + 1, code);
-    data.SetAt(data_pos + 2, entry_point);
+    data.SetAt(data_pos + CodeIndexFor(kNumArgsTested), code);
+    data.SetAt(data_pos + EntryPointIndexFor(kNumArgsTested), entry_point);
   }
   // Multithreaded access to ICData requires setting of array to be the last
   // operation.
@@ -13763,9 +13743,10 @@
     return StaticTypeExactnessState::NotTracking();
   }
   const Array& data = Array::Handle(entries());
-  intptr_t data_pos = index * TestEntryLength();
+  intptr_t data_pos =
+      index * TestEntryLength() + ExactnessIndexFor(NumArgsTested());
   return StaticTypeExactnessState::Decode(
-      Smi::Value(Smi::RawCast(data.At(data_pos + NumArgsTested() + 2))));
+      Smi::Value(Smi::RawCast(data.At(data_pos))));
 }
 
 void ICData::GetCheckAt(intptr_t index,
@@ -13778,9 +13759,9 @@
   const Array& data = Array::Handle(entries());
   intptr_t data_pos = index * TestEntryLength();
   for (intptr_t i = 0; i < NumArgsTested(); i++) {
-    class_ids->Add(Smi::Value(Smi::RawCast(data.At(data_pos++))));
+    class_ids->Add(Smi::Value(Smi::RawCast(data.At(data_pos + i))));
   }
-  (*target) ^= data.At(data_pos++);
+  (*target) ^= data.At(data_pos + TargetIndexFor(NumArgsTested()));
 }
 
 bool ICData::IsSentinelAt(intptr_t index) const {
@@ -13819,7 +13800,7 @@
   const Array& data = Array::Handle(entries());
   const intptr_t data_pos = index * TestEntryLength();
   *class_id = Smi::Value(Smi::RawCast(data.At(data_pos)));
-  *target ^= data.At(data_pos + 1);
+  *target ^= data.At(data_pos + TargetIndexFor(NumArgsTested()));
 }
 
 intptr_t ICData::GetCidAt(intptr_t index) const {
@@ -13846,7 +13827,8 @@
 
 RawFunction* ICData::GetTargetAt(intptr_t index) const {
   ASSERT(Isolate::Current()->compilation_allowed());
-  const intptr_t data_pos = index * TestEntryLength() + NumArgsTested();
+  const intptr_t data_pos =
+      index * TestEntryLength() + TargetIndexFor(NumArgsTested());
   ASSERT(Object::Handle(Array::Handle(entries()).At(data_pos)).IsFunction());
 
   NoSafepointScope no_safepoint;
@@ -13855,7 +13837,8 @@
 }
 
 RawObject* ICData::GetTargetOrCodeAt(intptr_t index) const {
-  const intptr_t data_pos = index * TestEntryLength() + NumArgsTested();
+  const intptr_t data_pos =
+      index * TestEntryLength() + TargetIndexFor(NumArgsTested());
 
   NoSafepointScope no_safepoint;
   RawArray* raw_data = entries();
@@ -13919,18 +13902,6 @@
 }
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
-RawFunction* ICData::GetTargetForReceiverClassId(intptr_t class_id,
-                                                 intptr_t* count_return) const {
-  const intptr_t len = NumberOfChecks();
-  for (intptr_t i = 0; i < len; i++) {
-    if (GetReceiverClassIdAt(i) == class_id) {
-      *count_return = GetCountAt(i);
-      return GetTargetAt(i);
-    }
-  }
-  return Function::null();
-}
-
 RawICData* ICData::AsUnaryClassChecksForCid(intptr_t cid,
                                             const Function& target) const {
   ASSERT(!IsNull());
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 8974dd0..725bc63 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -1775,8 +1775,6 @@
   intptr_t GetClassIdAt(intptr_t index, intptr_t arg_nr) const;
 
   RawFunction* GetTargetAt(intptr_t index) const;
-  RawFunction* GetTargetForReceiverClassId(intptr_t class_id,
-                                           intptr_t* count_return) const;
 
   RawObject* GetTargetOrCodeAt(intptr_t index) const;
   void SetCodeAt(intptr_t index, const Code& value) const;
@@ -1829,16 +1827,13 @@
   static intptr_t TestEntryLengthFor(intptr_t num_args,
                                      bool tracking_exactness);
 
-  static intptr_t TargetIndexFor(intptr_t num_args) { return num_args; }
-  static intptr_t CodeIndexFor(intptr_t num_args) { return num_args; }
+  static intptr_t CountIndexFor(intptr_t num_args) { return num_args; }
+  static intptr_t EntryPointIndexFor(intptr_t num_args) { return num_args; }
 
-  static intptr_t CountIndexFor(intptr_t num_args) { return (num_args + 1); }
-  static intptr_t EntryPointIndexFor(intptr_t num_args) {
-    return (num_args + 1);
-  }
-  static intptr_t ExactnessOffsetFor(intptr_t num_args) {
-    return (num_args + 2);
-  }
+  static intptr_t TargetIndexFor(intptr_t num_args) { return num_args + 1; }
+  static intptr_t CodeIndexFor(intptr_t num_args) { return num_args + 1; }
+
+  static intptr_t ExactnessIndexFor(intptr_t num_args) { return num_args + 2; }
 
   bool IsUsedAt(intptr_t i) const;
 
@@ -2762,7 +2757,8 @@
   static RawFunction* NewClosureFunctionWithKind(RawFunction::Kind kind,
                                                  const String& name,
                                                  const Function& parent,
-                                                 TokenPosition token_pos);
+                                                 TokenPosition token_pos,
+                                                 const Object& owner);
 
   // Allocates a new Function object representing a closure function.
   static RawFunction* NewClosureFunction(const String& name,
@@ -3452,7 +3448,18 @@
   // Internally we is_nullable_ field contains either kNullCid (nullable) or
   // 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; }
+  bool is_nullable(bool silence_assert = false) const {
+#if defined(DEBUG)
+    if (!silence_assert) {
+      // Same assert as guarded_cid(), because is_nullable() also needs to be
+      // consistent for the background compiler.
+      Thread* thread = Thread::Current();
+      ASSERT(!IsOriginal() || is_static() || thread->IsMutatorThread() ||
+             thread->IsAtSafepoint());
+    }
+#endif
+    return raw_ptr()->is_nullable_ == kNullCid;
+  }
   void set_is_nullable(bool val) const {
     ASSERT(Thread::Current()->IsMutatorThread());
     StoreNonPointer(&raw_ptr()->is_nullable_, val ? kNullCid : kIllegalCid);
@@ -3905,12 +3912,16 @@
   // If successful returns `true`. If an error happens during constant
   // evaluation, returns `false.
   //
+  // If [only_core] is true, then the annotations on the object will only
+  // be inspected if it is part of a core library.
+  //
   // WARNING: If the isolate received an [UnwindError] this function will not
   // return and rather unwinds until the enclosing setjmp() handler.
-  bool FindPragma(Thread* T,
-                  const Object& object,
-                  const String& pragma_name,
-                  Object* options) const;
+  static bool FindPragma(Thread* T,
+                         bool only_core,
+                         const Object& object,
+                         const String& pragma_name,
+                         Object* options);
 
   RawClass* toplevel_class() const { return raw_ptr()->toplevel_class_; }
   void set_toplevel_class(const Class& value) const;
@@ -4027,8 +4038,13 @@
 #endif  // defined(DART_NO_SNAPSHOT).
 
   static bool IsPrivate(const String& name);
+
   // Construct the full name of a corelib member.
   static const String& PrivateCoreLibName(const String& member);
+
+  // Returns true if [name] matches full name of corelib [member].
+  static bool IsPrivateCoreLibName(const String& name, const String& member);
+
   // Lookup class in the core lib which also contains various VM
   // helper methods and classes. Allow look up of private classes.
   static RawClass* LookupCoreClass(const String& class_name);
@@ -5209,6 +5225,8 @@
     StorePointer(&raw_ptr()->owner_, owner.raw());
   }
 
+  static intptr_t owner_offset() { return OFFSET_OF(RawCode, owner_); }
+
   // We would have a VisitPointers function here to traverse all the
   // embedded objects in the instructions using pointer_offsets.
 
@@ -5495,8 +5513,6 @@
 
  private:
   void set_instructions(uword instructions) const {
-    // The interpreter requires the instructions to be aligned.
-    ASSERT(Utils::IsAligned(instructions, sizeof(uint32_t)));
     StoreNonPointer(&raw_ptr()->instructions_, instructions);
   }
   void set_instructions_size(intptr_t size) const {
diff --git a/runtime/vm/os_fuchsia.cc b/runtime/vm/os_fuchsia.cc
index 58acf87..869c5b2 100644
--- a/runtime/vm/os_fuchsia.cc
+++ b/runtime/vm/os_fuchsia.cc
@@ -89,8 +89,10 @@
 
 int OS::GetLocalTimeZoneAdjustmentInSeconds() {
   int32_t local_offset, dst_offset;
+  zx_time_t now = 0;
+  zx_clock_get_new(ZX_CLOCK_UTC, &now);
   zx_status_t status = GetLocalAndDstOffsetInSeconds(
-      zx_clock_get(ZX_CLOCK_UTC) / ZX_SEC(1), &local_offset, &dst_offset);
+      now / ZX_SEC(1), &local_offset, &dst_offset);
   return status == ZX_OK ? local_offset : 0;
 }
 
@@ -99,11 +101,13 @@
 }
 
 int64_t OS::GetCurrentTimeMicros() {
-  return zx_clock_get(ZX_CLOCK_UTC) / kNanosecondsPerMicrosecond;
+  zx_time_t now = 0;
+  zx_clock_get_new(ZX_CLOCK_UTC, &now);
+  return now / kNanosecondsPerMicrosecond;
 }
 
 int64_t OS::GetCurrentMonotonicTicks() {
-  return zx_clock_get(ZX_CLOCK_MONOTONIC);
+  return zx_clock_get_monotonic();
 }
 
 int64_t OS::GetCurrentMonotonicFrequency() {
@@ -117,7 +121,9 @@
 }
 
 int64_t OS::GetCurrentThreadCPUMicros() {
-  return zx_clock_get(ZX_CLOCK_THREAD) / kNanosecondsPerMicrosecond;
+  zx_time_t now = 0;
+  zx_clock_get_new(ZX_CLOCK_THREAD, &now);
+  return now / kNanosecondsPerMicrosecond;
 }
 
 // TODO(5411554):  May need to hoist these architecture dependent code
diff --git a/runtime/vm/os_thread.cc b/runtime/vm/os_thread.cc
index 2cfe8fb..e3e9ddf 100644
--- a/runtime/vm/os_thread.cc
+++ b/runtime/vm/os_thread.cc
@@ -33,7 +33,7 @@
       trace_id_(OSThread::GetCurrentThreadTraceId()),
 #endif
       name_(NULL),
-      timeline_block_lock_(new Mutex()),
+      timeline_block_lock_(),
       timeline_block_(NULL),
       thread_list_next_(NULL),
       thread_interrupt_disabled_(1),  // Thread interrupts disabled by default.
@@ -85,7 +85,6 @@
   }
 #endif
   timeline_block_ = NULL;
-  delete timeline_block_lock_;
   free(name_);
 }
 
diff --git a/runtime/vm/os_thread.h b/runtime/vm/os_thread.h
index 9a95345..7d27cc8 100644
--- a/runtime/vm/os_thread.h
+++ b/runtime/vm/os_thread.h
@@ -38,6 +38,35 @@
 class ThreadState;
 class TimelineEventBlock;
 
+class Mutex {
+ public:
+  explicit Mutex(NOT_IN_PRODUCT(const char* name = "anonymous mutex"));
+  ~Mutex();
+
+  bool IsOwnedByCurrentThread() const;
+
+ private:
+  void Lock();
+  bool TryLock();  // Returns false if lock is busy and locking failed.
+  void Unlock();
+
+  MutexData data_;
+  NOT_IN_PRODUCT(const char* name_);
+#if defined(DEBUG)
+  ThreadId owner_;
+#endif  // defined(DEBUG)
+
+  friend class MallocLocker;
+  friend class MutexLocker;
+  friend class SafepointMutexLocker;
+  friend class OSThreadIterator;
+  friend class TimelineEventBlockIterator;
+  friend class TimelineEventRecorder;
+  friend class PageSpace;
+  friend void Dart_TestMutex();
+  DISALLOW_COPY_AND_ASSIGN(Mutex);
+};
+
 class BaseThread {
  public:
   bool is_os_thread() const { return is_os_thread_; }
@@ -86,7 +115,7 @@
     name_ = strdup(name);
   }
 
-  Mutex* timeline_block_lock() const { return timeline_block_lock_; }
+  Mutex* timeline_block_lock() const { return &timeline_block_lock_; }
 
   // Only safe to access when holding |timeline_block_lock_|.
   TimelineEventBlock* timeline_block() const { return timeline_block_; }
@@ -259,7 +288,7 @@
 #endif
   char* name_;  // A name for this thread.
 
-  Mutex* timeline_block_lock_;
+  mutable Mutex timeline_block_lock_;
   TimelineEventBlock* timeline_block_;
 
   // All |Thread|s are registered in the thread list.
@@ -308,44 +337,6 @@
   OSThread* next_;
 };
 
-class Mutex {
- public:
-  explicit Mutex(NOT_IN_PRODUCT(const char* name = "anonymous mutex"));
-  ~Mutex();
-
-#if defined(DEBUG)
-  bool IsOwnedByCurrentThread() const {
-    return owner_ == OSThread::GetCurrentThreadId();
-  }
-#else
-  bool IsOwnedByCurrentThread() const {
-    UNREACHABLE();
-    return false;
-  }
-#endif
-
- private:
-  void Lock();
-  bool TryLock();  // Returns false if lock is busy and locking failed.
-  void Unlock();
-
-  MutexData data_;
-  NOT_IN_PRODUCT(const char* name_);
-#if defined(DEBUG)
-  ThreadId owner_;
-#endif  // defined(DEBUG)
-
-  friend class MallocLocker;
-  friend class MutexLocker;
-  friend class SafepointMutexLocker;
-  friend class OSThreadIterator;
-  friend class TimelineEventBlockIterator;
-  friend class TimelineEventRecorder;
-  friend class PageSpace;
-  friend void Dart_TestMutex();
-  DISALLOW_COPY_AND_ASSIGN(Mutex);
-};
-
 class Monitor {
  public:
   enum WaitResult { kNotified, kTimedOut };
@@ -390,6 +381,15 @@
   DISALLOW_COPY_AND_ASSIGN(Monitor);
 };
 
+inline bool Mutex::IsOwnedByCurrentThread() const {
+#if defined(DEBUG)
+  return owner_ == OSThread::GetCurrentThreadId();
+#else
+  UNREACHABLE();
+  return false;
+#endif
+}
+
 }  // namespace dart
 
 #endif  // RUNTIME_VM_OS_THREAD_H_
diff --git a/runtime/vm/os_thread_fuchsia.cc b/runtime/vm/os_thread_fuchsia.cc
index d6fd956..01b2fe7 100644
--- a/runtime/vm/os_thread_fuchsia.cc
+++ b/runtime/vm/os_thread_fuchsia.cc
@@ -55,7 +55,7 @@
 
 static void ComputeTimeSpecMicros(struct timespec* ts, int64_t micros) {
   // time in nanoseconds.
-  zx_time_t now = zx_clock_get(ZX_CLOCK_MONOTONIC);
+  zx_time_t now = zx_clock_get_monotonic();
   zx_time_t target = now + (micros * kNanosecondsPerMicrosecond);
   int64_t secs = target / kNanosecondsPerSecond;
   int64_t nanos = target - (secs * kNanosecondsPerSecond);
diff --git a/runtime/vm/profiler.cc b/runtime/vm/profiler.cc
index ed05a74..52cbcf5 100644
--- a/runtime/vm/profiler.cc
+++ b/runtime/vm/profiler.cc
@@ -166,14 +166,13 @@
 }
 
 AllocationSampleBuffer::AllocationSampleBuffer(intptr_t capacity)
-    : SampleBuffer(capacity), mutex_(new Mutex()), free_sample_list_(NULL) {}
+    : SampleBuffer(capacity), mutex_(), free_sample_list_(NULL) {}
 
 SampleBuffer::~SampleBuffer() {
   delete memory_;
 }
 
 AllocationSampleBuffer::~AllocationSampleBuffer() {
-  delete mutex_;
 }
 
 Sample* SampleBuffer::At(intptr_t idx) const {
@@ -208,7 +207,7 @@
 }
 
 void AllocationSampleBuffer::FreeAllocationSample(Sample* sample) {
-  MutexLocker ml(mutex_);
+  MutexLocker ml(&mutex_);
   while (sample != NULL) {
     intptr_t continuation_index = -1;
     if (sample->is_continuation_sample()) {
@@ -243,7 +242,7 @@
 }
 
 Sample* AllocationSampleBuffer::ReserveSampleAndLink(Sample* previous) {
-  MutexLocker ml(mutex_);
+  MutexLocker ml(&mutex_);
   ASSERT(previous != NULL);
   intptr_t next_index = ReserveSampleSlotLocked();
   if (next_index < 0) {
@@ -262,7 +261,7 @@
 }
 
 Sample* AllocationSampleBuffer::ReserveSample() {
-  MutexLocker ml(mutex_);
+  MutexLocker ml(&mutex_);
   intptr_t index = ReserveSampleSlotLocked();
   if (index < 0) {
     return NULL;
diff --git a/runtime/vm/profiler.h b/runtime/vm/profiler.h
index d5122fc7d..f0280fc 100644
--- a/runtime/vm/profiler.h
+++ b/runtime/vm/profiler.h
@@ -655,7 +655,7 @@
   void FreeAllocationSample(Sample* sample);
 
  private:
-  Mutex* mutex_;
+  Mutex mutex_;
   Sample* free_sample_list_;
 
   DISALLOW_COPY_AND_ASSIGN(AllocationSampleBuffer);
diff --git a/runtime/vm/profiler_service.cc b/runtime/vm/profiler_service.cc
index b06927d..97153de 100644
--- a/runtime/vm/profiler_service.cc
+++ b/runtime/vm/profiler_service.cc
@@ -2486,19 +2486,6 @@
     for (intptr_t sample_index = 0; sample_index < samples_->length();
          sample_index++) {
       ProcessedSample* sample = samples_->At(sample_index);
-      JSONObject event(&events);
-      event.AddProperty("ph", "P");  // kind = sample event
-      // Add a blank name to keep about:tracing happy.
-      event.AddProperty("name", "");
-      event.AddProperty64("pid", pid);
-      event.AddProperty64("tid", OSThread::ThreadIdToIntPtr(sample->tid()));
-      event.AddPropertyTimeMicros("ts", sample->timestamp());
-      event.AddProperty("cat", "Dart");
-      if (!Isolate::IsVMInternalIsolate(isolate_)) {
-        JSONObject args(&event, "args");
-        args.AddProperty("mode", "basic");
-      }
-
       ProfileTrieNode* trie;
       if (code_trie) {
         trie = sample->timeline_code_trie();
@@ -2506,7 +2493,22 @@
         trie = sample->timeline_function_trie();
       }
       ASSERT(trie->frame_id() != -1);
-      event.AddPropertyF("sf", "%" Pd "-%" Pd, isolate_id, trie->frame_id());
+
+      if (trie->frame_id() != kRootFrameId) {
+        JSONObject event(&events);
+        event.AddProperty("ph", "P");  // kind = sample event
+        // Add a blank name to keep about:tracing happy.
+        event.AddProperty("name", "");
+        event.AddProperty64("pid", pid);
+        event.AddProperty64("tid", OSThread::ThreadIdToIntPtr(sample->tid()));
+        event.AddPropertyTimeMicros("ts", sample->timestamp());
+        event.AddProperty("cat", "Dart");
+        if (!Isolate::IsVMInternalIsolate(isolate_)) {
+          JSONObject args(&event, "args");
+          args.AddProperty("mode", "basic");
+        }
+        event.AddPropertyF("sf", "%" Pd "-%" Pd, isolate_id, trie->frame_id());
+      }
     }
   }
 }
diff --git a/runtime/vm/simulator_dbc.cc b/runtime/vm/simulator_dbc.cc
index 52c385d..21c3382 100644
--- a/runtime/vm/simulator_dbc.cc
+++ b/runtime/vm/simulator_dbc.cc
@@ -14,14 +14,20 @@
 
 #include "vm/simulator.h"
 
+#include "lib/ffi.h"
+#include "platform/assert.h"
 #include "vm/compiler/assembler/assembler.h"
 #include "vm/compiler/assembler/disassembler.h"
+#include "vm/compiler/backend/il.h"
 #include "vm/compiler/backend/locations.h"
+#include "vm/compiler/ffi.h"
+#include "vm/compiler/ffi_dbc_trampoline.h"
 #include "vm/compiler/jit/compiler.h"
 #include "vm/constants_dbc.h"
 #include "vm/cpu.h"
 #include "vm/dart_entry.h"
 #include "vm/debugger.h"
+#include "vm/heap/safepoint.h"
 #include "vm/lockers.h"
 #include "vm/native_arguments.h"
 #include "vm/native_entry.h"
@@ -616,6 +622,7 @@
 // Calls to leaf float Dart runtime functions are based on this interface.
 typedef double (*SimulatorLeafFloatRuntimeCall)(double d0, double d1);
 
+// Set up an exit frame for the garbage collector.
 void Simulator::Exit(Thread* thread,
                      RawObject** base,
                      RawObject** frame,
@@ -867,7 +874,7 @@
   intptr_t i;
   for (i = 0; i < (length - (kCheckedArgs + 2)); i += (kCheckedArgs + 2)) {
     if (cache->data()[i + 0] == receiver_cid) {
-      top[0] = cache->data()[i + kCheckedArgs];
+      top[0] = cache->data()[i + ICData::TargetIndexFor(kCheckedArgs)];
       found = true;
       break;
     }
@@ -913,7 +920,7 @@
   for (i = 0; i < (length - (kCheckedArgs + 2)); i += (kCheckedArgs + 2)) {
     if ((cache->data()[i + 0] == receiver_cid) &&
         (cache->data()[i + 1] == arg0_cid)) {
-      top[0] = cache->data()[i + kCheckedArgs];
+      top[0] = cache->data()[i + ICData::TargetIndexFor(kCheckedArgs)];
       found = true;
       break;
     }
@@ -1861,6 +1868,39 @@
   }
 
   {
+    BYTECODE(FfiCall, __D);
+    {
+      const auto& sig_desc = compiler::ffi::FfiSignatureDescriptor(
+          TypedData::Cast(Object::Handle(LOAD_CONSTANT(rD))));
+
+      // The arguments to this ffi call are on the stack at FP.
+      // kFirstLocalSlotFromFp is 0 in DBC, but the const is -1.
+      uint64_t* arg_values = reinterpret_cast<uint64_t*>(FP);
+
+      uint64_t* marshalled_args_data =
+          FfiMarshalledArguments::New(sig_desc, arg_values);
+      const auto& marshalled_args =
+          FfiMarshalledArguments(marshalled_args_data);
+
+      Exit(thread, FP, SP, pc);
+      {
+        TransitionGeneratedToNative transition(thread);
+        FfiTrampolineCall(marshalled_args_data);
+      }
+
+      const Representation result_rep = sig_desc.ResultRepresentation();
+      intptr_t result;
+      if (result_rep == kUnboxedDouble || result_rep == kUnboxedFloat) {
+        result = marshalled_args.DoubleResult();
+      } else {
+        result = marshalled_args.IntResult();
+      }
+      FP[0] = reinterpret_cast<RawObject*>(result);
+    }
+    DISPATCH();
+  }
+
+  {
     BYTECODE(OneByteStringFromCharCode, A_X);
     const intptr_t char_code = Smi::Value(RAW_CAST(Smi, FP[rD]));
     ASSERT(char_code >= 0);
diff --git a/runtime/vm/simulator_dbc.h b/runtime/vm/simulator_dbc.h
index 8b87a7a..7ed6fce 100644
--- a/runtime/vm/simulator_dbc.h
+++ b/runtime/vm/simulator_dbc.h
@@ -108,6 +108,7 @@
 
   static IntrinsicHandler intrinsics_[kIntrinsicCount];
 
+  // Set up an exit frame for the garbage collector.
   void Exit(Thread* thread,
             RawObject** base,
             RawObject** exit_frame,
diff --git a/runtime/vm/stub_code.cc b/runtime/vm/stub_code.cc
index 6c84a32..70d8a43 100644
--- a/runtime/vm/stub_code.cc
+++ b/runtime/vm/stub_code.cc
@@ -112,7 +112,8 @@
   if (FLAG_enable_interpreter) {
     if (is_interpreted_frame) {
       // Recognize special marker set up by interpreter in entry frame.
-      return Interpreter::IsEntryFrameMarker(reinterpret_cast<uint32_t*>(pc));
+      return Interpreter::IsEntryFrameMarker(
+          reinterpret_cast<const KBCInstr*>(pc));
     }
     {
       uword entry = StubCode::InvokeDartCodeFromBytecode().EntryPoint();
diff --git a/runtime/vm/thread.cc b/runtime/vm/thread.cc
index e4b6658..6b48726 100644
--- a/runtime/vm/thread.cc
+++ b/runtime/vm/thread.cc
@@ -44,8 +44,6 @@
     delete api_reusable_scope_;
     api_reusable_scope_ = NULL;
   }
-  delete thread_lock_;
-  thread_lock_ = NULL;
 }
 
 #if defined(DEBUG)
@@ -80,7 +78,7 @@
       safepoint_state_(0),
       task_kind_(kUnknownTask),
       dart_stream_(NULL),
-      thread_lock_(new Monitor()),
+      thread_lock_(),
       api_reusable_scope_(NULL),
       api_top_scope_(NULL),
       no_callback_scope_depth_(0),
@@ -406,7 +404,7 @@
 void Thread::SetStackLimit(uword limit) {
   // The thread setting the stack limit is not necessarily the thread which
   // the stack limit is being set on.
-  MonitorLocker ml(thread_lock_);
+  MonitorLocker ml(&thread_lock_);
   if (!HasScheduledInterrupts()) {
     // No interrupt pending, set stack_limit_ too.
     stack_limit_ = limit;
@@ -419,12 +417,12 @@
 }
 
 void Thread::ScheduleInterrupts(uword interrupt_bits) {
-  MonitorLocker ml(thread_lock_);
+  MonitorLocker ml(&thread_lock_);
   ScheduleInterruptsLocked(interrupt_bits);
 }
 
 void Thread::ScheduleInterruptsLocked(uword interrupt_bits) {
-  ASSERT(thread_lock_->IsOwnedByCurrentThread());
+  ASSERT(thread_lock_.IsOwnedByCurrentThread());
   ASSERT((interrupt_bits & ~kInterruptsMask) == 0);  // Must fit in mask.
 
   // Check to see if any of the requested interrupts should be deferred.
@@ -444,7 +442,7 @@
 }
 
 uword Thread::GetAndClearInterrupts() {
-  MonitorLocker ml(thread_lock_);
+  MonitorLocker ml(&thread_lock_);
   if (stack_limit_ == saved_stack_limit_) {
     return 0;  // No interrupt was requested.
   }
@@ -454,7 +452,7 @@
 }
 
 void Thread::DeferOOBMessageInterrupts() {
-  MonitorLocker ml(thread_lock_);
+  MonitorLocker ml(&thread_lock_);
   defer_oob_messages_count_++;
   if (defer_oob_messages_count_ > 1) {
     // OOB message interrupts are already deferred.
@@ -482,7 +480,7 @@
 }
 
 void Thread::RestoreOOBMessageInterrupts() {
-  MonitorLocker ml(thread_lock_);
+  MonitorLocker ml(&thread_lock_);
   defer_oob_messages_count_--;
   if (defer_oob_messages_count_ > 0) {
     return;
diff --git a/runtime/vm/thread.h b/runtime/vm/thread.h
index f5b7c97..c9d81bb 100644
--- a/runtime/vm/thread.h
+++ b/runtime/vm/thread.h
@@ -114,6 +114,7 @@
   V(RawCode*, monomorphic_miss_stub_, StubCode::MonomorphicMiss().raw(), NULL) \
   V(RawCode*, ic_lookup_through_code_stub_,                                    \
     StubCode::ICCallThroughCode().raw(), NULL)                                 \
+  V(RawCode*, optimize_stub_, StubCode::OptimizeFunction().raw(), NULL)        \
   V(RawCode*, deoptimize_stub_, StubCode::Deoptimize().raw(), NULL)            \
   V(RawCode*, lazy_deopt_from_return_stub_,                                    \
     StubCode::DeoptimizeLazyFromReturn().raw(), NULL)                          \
@@ -166,6 +167,7 @@
     StubCode::MegamorphicCall().EntryPoint(), 0)                               \
   V(uword, monomorphic_miss_entry_, StubCode::MonomorphicMiss().EntryPoint(),  \
     0)                                                                         \
+  V(uword, optimize_entry_, StubCode::OptimizeFunction().EntryPoint(), 0)      \
   V(uword, deoptimize_entry_, StubCode::Deoptimize().EntryPoint(), 0)
 
 #endif
@@ -337,7 +339,7 @@
   }
 
   // Monitor corresponding to this thread.
-  Monitor* thread_lock() const { return thread_lock_; }
+  Monitor* thread_lock() const { return &thread_lock_; }
 
   // The reusable api local scope for this thread.
   ApiLocalScope* api_reusable_scope() const { return api_reusable_scope_; }
@@ -450,12 +452,8 @@
   Heap* heap() const { return heap_; }
   static intptr_t heap_offset() { return OFFSET_OF(Thread, heap_); }
 
-  void set_top(uword value) {
-    top_ = value;
-  }
-  void set_end(uword value) {
-    end_ = value;
-  }
+  void set_top(uword value) { top_ = value; }
+  void set_end(uword value) { end_ = value; }
 
   uword top() { return top_; }
   uword end() { return end_; }
@@ -786,6 +784,17 @@
 
   uint64_t GetRandomUInt64() { return thread_random_.NextUInt64(); }
 
+  uint64_t* GetFfiMarshalledArguments(intptr_t size) {
+    if (ffi_marshalled_arguments_size_ < size) {
+      if (ffi_marshalled_arguments_size_ > 0) {
+        free(ffi_marshalled_arguments_);
+      }
+      ffi_marshalled_arguments_ =
+          reinterpret_cast<uint64_t*>(malloc(size * sizeof(uint64_t)));
+    }
+    return ffi_marshalled_arguments_;
+  }
+
 #ifndef PRODUCT
   void PrintJSON(JSONStream* stream) const;
 #endif
@@ -862,7 +871,7 @@
 
   TaskKind task_kind_;
   TimelineStream* dart_stream_;
-  Monitor* thread_lock_;
+  mutable Monitor thread_lock_;
   ApiLocalScope* api_reusable_scope_;
   ApiLocalScope* api_top_scope_;
   int32_t no_callback_scope_depth_;
@@ -887,6 +896,9 @@
 
   Random thread_random_;
 
+  intptr_t ffi_marshalled_arguments_size_ = 0;
+  uint64_t* ffi_marshalled_arguments_;
+
 // Reusable handles support.
 #define REUSABLE_HANDLE_FIELDS(object) object* object##_handle_;
   REUSABLE_HANDLE_LIST(REUSABLE_HANDLE_FIELDS)
diff --git a/runtime/vm/thread_registry.cc b/runtime/vm/thread_registry.cc
index 2052d4a..2dcabf8 100644
--- a/runtime/vm/thread_registry.cc
+++ b/runtime/vm/thread_registry.cc
@@ -30,9 +30,6 @@
       delete thread;
     }
   }
-
-  // Delete monitor.
-  delete threads_lock_;
 }
 
 // Gets a free Thread structure, we special case the mutator thread
diff --git a/runtime/vm/thread_registry.h b/runtime/vm/thread_registry.h
index fda9474..b6c0ec5 100644
--- a/runtime/vm/thread_registry.h
+++ b/runtime/vm/thread_registry.h
@@ -23,7 +23,7 @@
 class ThreadRegistry {
  public:
   ThreadRegistry()
-      : threads_lock_(new Monitor()),
+      : threads_lock_(),
         active_list_(NULL),
         free_list_(NULL),
         mutator_thread_(NULL) {}
@@ -50,7 +50,7 @@
 
  private:
   Thread* active_list() const { return active_list_; }
-  Monitor* threads_lock() const { return threads_lock_; }
+  Monitor* threads_lock() const { return &threads_lock_; }
 
   Thread* GetFreeThreadLocked(Isolate* isolate, bool is_mutator);
   void ReturnThreadLocked(bool is_mutator, Thread* thread);
@@ -61,7 +61,7 @@
 
   // This monitor protects the threads list for an isolate, it is used whenever
   // we need to iterate over threads (both active and free) in an isolate.
-  Monitor* threads_lock_;
+  mutable Monitor threads_lock_;
   Thread* active_list_;  // List of active threads in the isolate.
   Thread* free_list_;    // Free list of Thread objects that can be reused.
 
diff --git a/runtime/vm/vm_sources.gni b/runtime/vm/vm_sources.gni
index cc283ee..e646a21 100644
--- a/runtime/vm/vm_sources.gni
+++ b/runtime/vm/vm_sources.gni
@@ -50,6 +50,7 @@
   "constants_dbc.h",
   "constants_ia32.cc",
   "constants_ia32.h",
+  "constants_kbc.cc",
   "constants_kbc.h",
   "constants_x64.cc",
   "constants_x64.h",
diff --git a/samples/ffi/sqlite/docs/sqlite-tutorial.md b/samples/ffi/sqlite/docs/sqlite-tutorial.md
index 7f7aa22..c38170c 100644
--- a/samples/ffi/sqlite/docs/sqlite-tutorial.md
+++ b/samples/ffi/sqlite/docs/sqlite-tutorial.md
@@ -71,19 +71,19 @@
 Strings in C are pointers to character arrays.
 
 ```dart
-class CString extends Pointer<Int8> {}
+class CString extends Pointer<Uint8> {}
 ```
 
 Pointers to C integers, floats, an doubles can be read from and written through to `dart:ffi`.
 However, before we can write to C memory from dart, we need to `allocate` some memory.
 
 ```dart
-Pointer<Int8> p = allocate(); // Infers type argument allocate<Int8>(), and allocates 1 byte.
-p.store(123);                 // Stores a Dart int into this C int8.
-int v = p.load();             // Infers type argument p.load<int>(), and loads a value from C memory.
+Pointer<Uint8> p = allocate(); // Infers type argument allocate<Uint8>(), and allocates 1 byte.
+p.store(123);                  // Stores a Dart int into this C int8.
+int v = p.load();              // Infers type argument p.load<int>(), and loads a value from C memory.
 ```
 
-Note that you can only load a Dart `int` from a C `Int8`.
+Note that you can only load a Dart `int` from a C `Uint8`.
 Trying to load a Dart `double` will result in a runtime exception.
 
 We've almost modeled C Strings.
diff --git a/samples/ffi/sqlite/lib/src/ffi/cstring.dart b/samples/ffi/sqlite/lib/src/ffi/cstring.dart
index 5b07085..da095e4 100644
--- a/samples/ffi/sqlite/lib/src/ffi/cstring.dart
+++ b/samples/ffi/sqlite/lib/src/ffi/cstring.dart
@@ -8,7 +8,7 @@
 import "arena.dart";
 
 /// Represents a String in C memory, managed by an [Arena].
-class CString extends Pointer<Int8> {
+class CString extends Pointer<Uint8> {
   /// Allocates a [CString] in the current [Arena] and populates it with
   /// [dartStr].
   factory CString(String dartStr) => CString.inArena(Arena.current(), dartStr);
@@ -23,7 +23,7 @@
   /// memory manually!
   factory CString.allocate(String dartStr) {
     List<int> units = Utf8Encoder().convert(dartStr);
-    Pointer<Int8> str = allocate(count: units.length + 1);
+    Pointer<Uint8> str = allocate(count: units.length + 1);
     for (int i = 0; i < units.length; ++i) {
       str.elementAt(i).store(units[i]);
     }
diff --git a/sdk/api_readme.md b/sdk/api_readme.md
index 3e5990dd..2f51f7e 100644
--- a/sdk/api_readme.md
+++ b/sdk/api_readme.md
@@ -16,15 +16,15 @@
 ```
 
 You can install more libraries using the
-[pub package manager](https://www.dartlang.org/tools/pub).
+[pub package manager](https://dart.dev/guides/packages).
   
 The main site for learning and using Dart is
-[www.dartlang.org](https://www.dartlang.org). Check out these pages:
+[dart.dev](https://dart.dev). Check out these pages:
   
-  * [Get started](https://www.dartlang.org/guides/get-started)
-  * [Language tour](https://www.dartlang.org/guides/language/language-tour)
-  * [Library tour](https://www.dartlang.org/guides/libraries/library-tour)
-  * [Sample code](https://www.dartlang.org/samples)
+  * [Platforms](https://dart.dev/platforms)
+  * [Language tour](https://dart.dev/guides/language/language-tour)
+  * [Library tour](https://dart.dev/guides/libraries/library-tour)
+  * [Sample code](https://dart.dev/samples)
   
 This API reference is automatically generated from source code in the [Dart
 SDK project](https://github.com/dart-lang/sdk).
diff --git a/sdk/lib/_http/http_impl.dart b/sdk/lib/_http/http_impl.dart
index f0e365d..a70ca82 100644
--- a/sdk/lib/_http/http_impl.dart
+++ b/sdk/lib/_http/http_impl.dart
@@ -292,9 +292,13 @@
   // The HttpClientRequest of this response.
   final _HttpClientRequest _httpRequest;
 
+  // Whether this response is configured to auto uncompress.
+  final bool autoUncompress;
+
   _HttpClientResponse(
       _HttpIncoming _incoming, this._httpRequest, this._httpClient)
-      : super(_incoming) {
+      : autoUncompress = _httpClient.autoUncompress,
+        super(_incoming) {
     // Set uri for potential exceptions.
     _incoming.uri = _httpRequest.uri;
   }
@@ -377,7 +381,7 @@
       return new Stream<List<int>>.empty().listen(null, onDone: onDone);
     }
     Stream<List<int>> stream = _incoming;
-    if (_httpClient.autoUncompress &&
+    if (autoUncompress &&
         headers.value(HttpHeaders.contentEncodingHeader) == "gzip") {
       stream = stream.transform(gzip.decoder);
     }
diff --git a/sdk/lib/async/stream.dart b/sdk/lib/async/stream.dart
index c29609d..82b88ee 100644
--- a/sdk/lib/async/stream.dart
+++ b/sdk/lib/async/stream.dart
@@ -410,6 +410,14 @@
    * The [convert] function is called once per data event per listener.
    * If a broadcast stream is listened to more than once, each subscription
    * will individually call [convert] on each data event.
+   *
+   * Unlike [transform], this method does not treat the stream as
+   * chunks of a single value. Instead each event is converted independently
+   * of the previous and following events, which may not always be correct.
+   * For example, UTF-8 encoding, or decoding, will give wrong results
+   * if a surrogate pair, or a multibyte UTF-8 encoding, is split into
+   * separate events, and those events are attempted encoded or decoded
+   * independently.
    */
   Stream<S> map<S>(S convert(T event)) {
     return new _MapStream<T, S>(this, convert);
@@ -633,6 +641,16 @@
    * Whether the returned stream is a broadcast stream or not,
    * and which elements it will contain,
    * is entirely up to the transformation.
+   *
+   * This method should always be used for transformations which treat
+   * the entire stream as representing a single value
+   * which has perhaps been split into several parts for transport,
+   * like a file being read from disk or being fetched over a network.
+   * The transformation will then produce a new stream which
+   * transforms the stream's value incrementally (perhaps using
+   * [Converter.startChunkedConversion]). The resulting stream
+   * may again be chunks of the result, but does not have to
+   * correspond to specific events from the source string.
    */
   Stream<S> transform<S>(StreamTransformer<T, S> streamTransformer) {
     return streamTransformer.bind(this);
@@ -1892,6 +1910,14 @@
    * receives the input stream (the one passed to [bind]) and a
    * boolean flag `cancelOnError` to create a [StreamSubscription].
    *
+   * If the transformed stream is a broadcast stream, so is the stream
+   * returned by the [StreamTransformer.bind] method by this transformer.
+   *
+   * If the transformed stream is listened to multiple times, the [onListen]
+   * callback is called again for each new [Stream.listen] call.
+   * This happens whether the stream is a broadcast stream or not,
+   * but the call will usually fail for non-broadcast streams.
+   *
    * The [onListen] callback does *not* receive the handlers that were passed
    * to [Stream.listen]. These are automatically set after the call to the
    * [onListen] callback (using [StreamSubscription.onData],
diff --git a/sdk/lib/async/stream_transformers.dart b/sdk/lib/async/stream_transformers.dart
index b656dea..9ec13bd 100644
--- a/sdk/lib/async/stream_transformers.dart
+++ b/sdk/lib/async/stream_transformers.dart
@@ -320,6 +320,8 @@
   final _SubscriptionTransformer<S, T> _onListen;
   final Stream<S> _stream;
 
+  bool get isBroadcast => _stream.isBroadcast;
+
   _BoundSubscriptionStream(this._stream, this._onListen);
 
   StreamSubscription<T> listen(void onData(T event),
diff --git a/tests/co19_2/co19_2-kernel.status b/tests/co19_2/co19_2-kernel.status
index b1086d7..48b24cc 100644
--- a/tests/co19_2/co19_2-kernel.status
+++ b/tests/co19_2/co19_2-kernel.status
@@ -1174,7 +1174,7 @@
 LibTest/typed_data/Uint8List/first_A01_t02: RuntimeError
 LibTest/typed_data/Uint8List/last_A01_t02: RuntimeError
 
-[ $strong && ($compiler == dartk || $compiler == dartkb) ]
+[ $compiler == dartk || $compiler == dartkb ]
 Language/Expressions/Additive_Expressions/syntax_t01: RuntimeError
 Language/Expressions/Assignment/null_aware_assignment_static_type_t01: RuntimeError
 Language/Expressions/Function_Invocation/async_generator_invokation_t08: Fail
diff --git a/tests/compiler/dart2js/analyses/dart2js_allowed.json b/tests/compiler/dart2js/analyses/dart2js_allowed.json
index de743f0..0b70e2e 100644
--- a/tests/compiler/dart2js/analyses/dart2js_allowed.json
+++ b/tests/compiler/dart2js/analyses/dart2js_allowed.json
@@ -143,8 +143,8 @@
     "Dynamic invocation of 'toSet'.": 1
   },
   "pkg/compiler/lib/src/helpers/track_map.dart": {
-    "Dynamic invocation of '+'.": 2,
-    "Dynamic invocation of '-'.": 1
+    "Dynamic invocation of '-'.": 1,
+    "Dynamic invocation of '+'.": 1
   },
   "pkg/compiler/lib/src/constants/constant_system.dart": {
     "Dynamic invocation of '&'.": 1,
@@ -250,6 +250,12 @@
     "Dynamic access of 'named'.": 2,
     "Dynamic invocation of '[]'.": 2
   },
+  "pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart": {
+    "Dynamic access of 'keys'.": 1,
+    "Dynamic invocation of 'toSet'.": 1,
+    "Dynamic invocation of '[]='.": 1,
+    "Dynamic invocation of 'add'.": 1
+  },
   "pkg/compiler/lib/src/universe/function_set.dart": {
     "Dynamic access of 'selector'.": 1,
     "Dynamic access of 'receiver'.": 1
@@ -270,16 +276,6 @@
   "pkg/compiler/lib/src/ssa/value_set.dart": {
     "Dynamic invocation of 'add'.": 2
   },
-  "pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart": {
-    "Dynamic access of 'keys'.": 1,
-    "Dynamic invocation of 'toSet'.": 1,
-    "Dynamic invocation of '[]='.": 1,
-    "Dynamic invocation of 'add'.": 1
-  },
-  "pkg/compiler/lib/src/util/features.dart": {
-    "Dynamic invocation of 'sort'.": 1,
-    "Dynamic invocation of 'join'.": 1
-  },
   "pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart": {
     "Dynamic access of 'superclass'.": 1,
     "Dynamic access of 'needsTearOff'.": 1
diff --git a/tests/compiler/dart2js/codegen/is_function_test.dart b/tests/compiler/dart2js/codegen/is_function_test.dart
index e0b3aea..9965040 100644
--- a/tests/compiler/dart2js/codegen/is_function_test.dart
+++ b/tests/compiler/dart2js/codegen/is_function_test.dart
@@ -25,7 +25,7 @@
     Expect.isTrue(result.isSuccess);
     Compiler compiler = result.compiler;
     Program program = compiler.backend.emitterTask.emitter.programForTesting;
-    var name = compiler.backend.namer.operatorIs(
+    var name = compiler.backend.namerForTesting.operatorIs(
         compiler.backendClosedWorldForTesting.commonElements.functionClass);
     for (Fragment fragment in program.fragments) {
       for (Library library in fragment.libraries) {
diff --git a/tests/compiler/dart2js/codegen/jsarray_indexof_test.dart b/tests/compiler/dart2js/codegen/jsarray_indexof_test.dart
index 8b98f7d..d5df20f 100644
--- a/tests/compiler/dart2js/codegen/jsarray_indexof_test.dart
+++ b/tests/compiler/dart2js/codegen/jsarray_indexof_test.dart
@@ -51,7 +51,7 @@
 
   Selector getLengthSelector = new Selector.getter(const PublicName('length'));
   js.Name getLengthName =
-      compiler.backend.namer.invocationName(getLengthSelector);
+      compiler.backend.namerForTesting.invocationName(getLengthSelector);
 
   Method method = programLookup.getMethod(jsArrayIndexOf);
   int lengthCount = 0;
diff --git a/tests/compiler/dart2js/dart2js.status b/tests/compiler/dart2js/dart2js.status
index 3df3488..84af435 100644
--- a/tests/compiler/dart2js/dart2js.status
+++ b/tests/compiler/dart2js/dart2js.status
@@ -30,6 +30,7 @@
 model/native_test: Pass, Slow
 model/no_such_method_enabled_test: Pass, Slow
 model/subtype_test: Pass, Slow
+modular/*: Slow, Pass
 packages/*: Skip # Skip packages folder
 rti/rti_emission_test: Pass, Slow
 rti/rti_need0_test: Pass, Slow
diff --git a/tests/compiler/dart2js/deferred/emit_type_checks_test.dart b/tests/compiler/dart2js/deferred/emit_type_checks_test.dart
index a6cf80c..2aea089 100644
--- a/tests/compiler/dart2js/deferred/emit_type_checks_test.dart
+++ b/tests/compiler/dart2js/deferred/emit_type_checks_test.dart
@@ -22,7 +22,7 @@
     String mainOutput = collector.getOutput('', OutputType.js);
     String deferredOutput = collector.getOutput('out_1', OutputType.jsPart);
     JavaScriptBackend backend = compiler.backend;
-    String isPrefix = backend.namer.operatorIsPrefix;
+    String isPrefix = backend.namerForTesting.fixedNames.operatorIsPrefix;
     Expect.isTrue(
         deferredOutput.contains('${isPrefix}A: 1'),
         "Deferred output doesn't contain '${isPrefix}A: 1':\n"
diff --git a/tests/compiler/dart2js/end_to_end/exit_code_test.dart b/tests/compiler/dart2js/end_to_end/exit_code_test.dart
index fbae05a..e424fad 100644
--- a/tests/compiler/dart2js/end_to_end/exit_code_test.dart
+++ b/tests/compiler/dart2js/end_to_end/exit_code_test.dart
@@ -11,7 +11,7 @@
 
 import 'package:compiler/compiler_new.dart' as api;
 import 'package:compiler/src/commandline_options.dart';
-import 'package:compiler/src/common/codegen.dart';
+import 'package:compiler/src/common/work.dart';
 import 'package:compiler/src/compiler.dart';
 import 'package:compiler/src/dart2js.dart' as entry;
 import 'package:compiler/src/diagnostics/diagnostic_listener.dart';
@@ -20,9 +20,9 @@
 import 'package:compiler/src/diagnostics/spannable.dart';
 import 'package:compiler/src/apiimpl.dart' as apiimpl;
 import 'package:compiler/src/elements/entities.dart';
-import 'package:compiler/src/inferrer/types.dart';
 import 'package:compiler/src/js_backend/js_backend.dart';
 import 'package:compiler/src/null_compiler_output.dart';
+import 'package:compiler/src/serialization/serialization.dart';
 import 'package:compiler/src/options.dart' show CompilerOptions;
 import 'package:compiler/src/universe/world_impact.dart';
 import 'package:compiler/src/world.dart';
@@ -110,10 +110,10 @@
             useNewSourceInfo: compiler.options.useNewSourceInfo);
 
   @override
-  WorldImpact generateCode(CodegenWorkItem work, JClosedWorld closedWorld,
-      GlobalTypeInferenceResults results, CodegenInputs codegen) {
+  WorldImpact generateCode(WorkItem work, JClosedWorld closedWorld,
+      EntityLookup entityLookup, ComponentLookup componentLookup) {
     compiler.test('Compiler.codegen');
-    return super.generateCode(work, closedWorld, results, codegen);
+    return super.generateCode(work, closedWorld, entityLookup, componentLookup);
   }
 }
 
diff --git a/tests/compiler/dart2js/helpers/program_lookup.dart b/tests/compiler/dart2js/helpers/program_lookup.dart
index 6aff382..4f4d052 100644
--- a/tests/compiler/dart2js/helpers/program_lookup.dart
+++ b/tests/compiler/dart2js/helpers/program_lookup.dart
@@ -44,7 +44,7 @@
 
   ProgramLookup(Compiler compiler)
       : this.program = compiler.backend.emitterTask.emitter.programForTesting,
-        this.namer = compiler.backend.namer;
+        this.namer = compiler.backend.namerForTesting;
 
   Fragment getFragment(OutputUnit outputUnit) {
     for (Fragment fragment in program.fragments) {
diff --git a/tests/compiler/dart2js/model/enqueuer_test.dart b/tests/compiler/dart2js/model/enqueuer_test.dart
index 3417206..e792a10 100644
--- a/tests/compiler/dart2js/model/enqueuer_test.dart
+++ b/tests/compiler/dart2js/model/enqueuer_test.dart
@@ -195,8 +195,8 @@
         new Name(methodName, elementEnvironment.mainLibrary),
         CallStructure.NO_ARGS);
     WorldImpact impact = new WorldImpactBuilderImpl()
-      ..registerDynamicUse(new ConstrainedDynamicUse(
-          selector, createConstraint(cls), const <DartType>[]));
+      ..registerDynamicUse(
+          new DynamicUse(selector, createConstraint(cls), const <DartType>[]));
     enqueuer.applyImpact(impact);
   }
 
diff --git a/tests/compiler/dart2js/modular/data/int_js_number/def.dart b/tests/compiler/dart2js/modular/data/int_js_number/def.dart
new file mode 100644
index 0000000..0fd7377
--- /dev/null
+++ b/tests/compiler/dart2js/modular/data/int_js_number/def.dart
@@ -0,0 +1,4 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+const int foo = 331;
diff --git a/tests/compiler/dart2js/modular/data/int_js_number/main.dart b/tests/compiler/dart2js/modular/data/int_js_number/main.dart
new file mode 100644
index 0000000..6352c3d
--- /dev/null
+++ b/tests/compiler/dart2js/modular/data/int_js_number/main.dart
@@ -0,0 +1,8 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+import 'def.dart';
+
+main() {
+  print(const <int>[foo]);
+}
diff --git a/tests/compiler/dart2js/modular/data/int_js_number/modules.yaml b/tests/compiler/dart2js/modular/data/int_js_number/modules.yaml
new file mode 100644
index 0000000..a02b69a
--- /dev/null
+++ b/tests/compiler/dart2js/modular/data/int_js_number/modules.yaml
@@ -0,0 +1,8 @@
+# Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+#
+# Regression test: integral numbers should be treated as int and not double
+# after serialization across modules.
+dependencies:
+  main: def
diff --git a/tests/compiler/dart2js/modular/data/package_imports/.packages b/tests/compiler/dart2js/modular/data/package_imports/.packages
new file mode 100644
index 0000000..3da0bf2
--- /dev/null
+++ b/tests/compiler/dart2js/modular/data/package_imports/.packages
@@ -0,0 +1,6 @@
+# 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.
+f0:.
+f1:.
+a:a
diff --git a/tests/compiler/dart2js/modular/data/package_imports/a/a.dart b/tests/compiler/dart2js/modular/data/package_imports/a/a.dart
new file mode 100644
index 0000000..3a62c13
--- /dev/null
+++ b/tests/compiler/dart2js/modular/data/package_imports/a/a.dart
@@ -0,0 +1,6 @@
+// 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:f1/f1.dart';
+
+int z = y + 100;
diff --git a/tests/compiler/dart2js/modular/data/package_imports/f0.dart b/tests/compiler/dart2js/modular/data/package_imports/f0.dart
new file mode 100644
index 0000000..27b7873
--- /dev/null
+++ b/tests/compiler/dart2js/modular/data/package_imports/f0.dart
@@ -0,0 +1,4 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+int x = 1;
diff --git a/tests/compiler/dart2js/modular/data/package_imports/f1.dart b/tests/compiler/dart2js/modular/data/package_imports/f1.dart
new file mode 100644
index 0000000..0eeb9f8
--- /dev/null
+++ b/tests/compiler/dart2js/modular/data/package_imports/f1.dart
@@ -0,0 +1,6 @@
+// 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:f0/f0.dart';
+
+int y = x + 10;
diff --git a/tests/compiler/dart2js/modular/data/package_imports/f3.dart b/tests/compiler/dart2js/modular/data/package_imports/f3.dart
new file mode 100644
index 0000000..72965f8
--- /dev/null
+++ b/tests/compiler/dart2js/modular/data/package_imports/f3.dart
@@ -0,0 +1,6 @@
+// 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:a/a.dart';
+
+int w = z + 1000;
diff --git a/tests/compiler/dart2js/modular/data/package_imports/main.dart b/tests/compiler/dart2js/modular/data/package_imports/main.dart
new file mode 100644
index 0000000..7dcee7a
--- /dev/null
+++ b/tests/compiler/dart2js/modular/data/package_imports/main.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.
+import 'f3.dart';
+import 'package:expect/expect.dart';
+
+main() {
+  print(w);
+  Expect.isTrue(w == 1111);
+}
diff --git a/tests/compiler/dart2js/modular/data/package_imports/modules.yaml b/tests/compiler/dart2js/modular/data/package_imports/modules.yaml
new file mode 100644
index 0000000..a8731e9
--- /dev/null
+++ b/tests/compiler/dart2js/modular/data/package_imports/modules.yaml
@@ -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.
+#
+# Test ensuring that the modular compiler works properly with `package:`
+# imports. This test also ensures that the dart2js implementation of the modular
+# test pipeline works as intended. The test is not designed to cover any
+# compiler or language feature explicitly.
+dependencies:
+  main: [f3, expect]
+  f3: a
+  a: f1
+  f1: f0
diff --git a/tests/compiler/dart2js/modular/data/subclass/a/a.dart b/tests/compiler/dart2js/modular/data/subclass/a/a.dart
new file mode 100644
index 0000000..e393550
--- /dev/null
+++ b/tests/compiler/dart2js/modular/data/subclass/a/a.dart
@@ -0,0 +1,4 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+const x = 1;
diff --git a/tests/compiler/dart2js/modular/data/subclass/f0.dart b/tests/compiler/dart2js/modular/data/subclass/f0.dart
new file mode 100644
index 0000000..113a6ff
--- /dev/null
+++ b/tests/compiler/dart2js/modular/data/subclass/f0.dart
@@ -0,0 +1,6 @@
+// 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 A0 {
+  StringBuffer buffer = new StringBuffer()..write("hello ");
+}
diff --git a/tests/compiler/dart2js/modular/data/subclass/f1.dart b/tests/compiler/dart2js/modular/data/subclass/f1.dart
new file mode 100644
index 0000000..00f7709
--- /dev/null
+++ b/tests/compiler/dart2js/modular/data/subclass/f1.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.
+import 'f0.dart';
+
+class B1 extends A0 {
+  A0 get foo => null;
+}
+
+A0 createA0() => new A0();
diff --git a/tests/compiler/dart2js/modular/data/subclass/main.dart b/tests/compiler/dart2js/modular/data/subclass/main.dart
new file mode 100644
index 0000000..090de94
--- /dev/null
+++ b/tests/compiler/dart2js/modular/data/subclass/main.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+import 'f1.dart';
+import 'a/a.dart';
+
+class C2 extends B1 {
+  final foo = createA0();
+}
+
+main() {
+  var buffer = new C2().foo.buffer;
+
+  buffer.write('world! $x');
+  print(buffer.toString());
+}
diff --git a/tests/compiler/dart2js/modular/data/subclass/modules.yaml b/tests/compiler/dart2js/modular/data/subclass/modules.yaml
new file mode 100644
index 0000000..70606e9
--- /dev/null
+++ b/tests/compiler/dart2js/modular/data/subclass/modules.yaml
@@ -0,0 +1,9 @@
+# Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+#
+# Test illustrating how the modular pipeline works. This test is not designed to
+# stress any specific feature of the compiler.
+dependencies:
+  f1: f0
+  main: [f1, a]
diff --git a/tests/compiler/dart2js/modular/modular_test.dart b/tests/compiler/dart2js/modular/modular_test.dart
new file mode 100644
index 0000000..80aa857
--- /dev/null
+++ b/tests/compiler/dart2js/modular/modular_test.dart
@@ -0,0 +1,326 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// Test the modular compilation pipeline of dart2js.
+///
+/// This is a shell that runs multiple tests, one per folder under `data/`.
+import 'dart:io';
+
+import 'package:args/args.dart';
+import 'package:async_helper/async_helper.dart';
+import 'package:expect/expect.dart';
+import 'package:front_end/src/compute_platform_binaries_location.dart'
+    show computePlatformBinariesLocation;
+import 'package:modular_test/src/io_pipeline.dart';
+import 'package:modular_test/src/loader.dart';
+import 'package:modular_test/src/pipeline.dart';
+import 'package:modular_test/src/suite.dart';
+
+_Options _options;
+main(List<String> args) {
+  _options = _Options.parse(args);
+  asyncTest(() async {
+    var baseUri = Platform.script.resolve('data/');
+    var baseDir = Directory.fromUri(baseUri);
+    await for (var entry in baseDir.list(recursive: false)) {
+      if (entry is Directory) {
+        await _runTest(entry.uri, baseUri);
+      }
+    }
+  });
+}
+
+Future<void> _runTest(Uri uri, Uri baseDir) async {
+  var dirName = uri.path.substring(baseDir.path.length);
+  if (_options.filter != null && !dirName.contains(_options.filter)) {
+    if (_options.showSkipped) print("skipped: $dirName");
+    return;
+  }
+
+  print("testing: $dirName");
+  ModularTest test = await loadTest(uri);
+  if (_options.verbose) print(test.debugString());
+  var pipeline = new IOPipeline([
+    SourceToDillStep(),
+    GlobalAnalysisStep(),
+    Dart2jsBackendStep(),
+    RunD8(),
+  ]);
+
+  await pipeline.run(test);
+}
+
+const dillId = const DataId("dill");
+const updatedDillId = const DataId("udill");
+const globalDataId = const DataId("gdata");
+const jsId = const DataId("js");
+const txtId = const DataId("txt");
+
+// Step that compiles sources in a module to a .dill file.
+class SourceToDillStep implements IOModularStep {
+  @override
+  List<DataId> get resultData => const [dillId];
+
+  @override
+  bool get needsSources => true;
+
+  @override
+  List<DataId> get dependencyDataNeeded => const [dillId];
+
+  @override
+  List<DataId> get moduleDataNeeded => const [];
+
+  @override
+  bool get onlyOnMain => false;
+
+  @override
+  Future<void> execute(
+      Module module, Uri root, ModuleDataToRelativeUri toUri) async {
+    if (_options.verbose) print("step: source-to-dill on $module");
+    // We use non file-URI schemes for representeing source locations in a
+    // root-agnostic way. This allows us to refer to file across modules and
+    // across steps without exposing the underlying temporary folders that are
+    // created by the framework. In build systems like bazel this is especially
+    // important because each step may be run on a different machine.
+    //
+    // Files in packages are defined in terms of `package:` URIs, while
+    // non-package URIs are defined using the `dart-dev-app` scheme.
+    String rootScheme = 'dev-dart-app';
+    String sourceToImportUri(Uri relativeUri) {
+      if (module.isPackage) {
+        var basePath = module.packageBase.path;
+        var packageRelativePath = basePath == "./"
+            ? relativeUri.path
+            : relativeUri.path.substring(basePath.length);
+        return 'package:${module.name}/$packageRelativePath';
+      } else {
+        return '$rootScheme:/$relativeUri';
+      }
+    }
+
+    // We create a .packages file which defines the location of this module if
+    // it is a package.  The CFE requires that if a `package:` URI of a
+    // dependency is used in an import, then we need that package entry in the
+    // .packages file. However, after it checks that the definition exists, the
+    // CFE will not actually use the resolved URI if a library for the import
+    // URI is already found in one of the provided .dill files of the
+    // dependencies. For that reason, and to ensure that a step only has access
+    // to the files provided in a module, we generate a .packages with invalid
+    // folders for other packages.
+    // TODO(sigmund): follow up with the CFE to see if we can remove the need
+    // for the .packages entry altogether if they won't need to read the
+    // sources.
+    var packagesContents = new StringBuffer();
+    if (module.isPackage) {
+      packagesContents.write('${module.name}:${module.packageBase}\n');
+    }
+    Set<Module> transitiveDependencies = computeTransitiveDependencies(module);
+    for (Module dependency in transitiveDependencies) {
+      if (dependency.isPackage) {
+        packagesContents.write('${dependency.name}:unused\n');
+      }
+    }
+
+    await File.fromUri(root.resolve('.packages'))
+        .writeAsString('$packagesContents');
+
+    var sdkRoot = Platform.script.resolve("../../../../");
+    var platform =
+        computePlatformBinariesLocation().resolve("dart2js_platform.dill");
+
+    List<String> workerArgs = [
+      sdkRoot.resolve("utils/bazel/kernel_worker.dart").toFilePath(),
+      '--no-summary-only',
+      '--target',
+      'dart2js',
+      '--multi-root',
+      '$root',
+      '--multi-root-scheme',
+      rootScheme,
+      '--dart-sdk-summary',
+      '${platform}',
+      '--output',
+      '${toUri(module, dillId)}',
+      '--packages-file',
+      '$rootScheme:/.packages',
+      ...(transitiveDependencies
+          .expand((m) => ['--input-linked', '${toUri(m, dillId)}'])),
+      ...(module.sources.expand((uri) => ['--source', sourceToImportUri(uri)])),
+    ];
+
+    var result = await _runProcess(
+        Platform.resolvedExecutable, workerArgs, root.toFilePath());
+    _checkExitCode(result, this, module);
+  }
+}
+
+// Step that invokes the dart2js global analysis on the main module by providing
+// the .dill files of all transitive modules as inputs.
+class GlobalAnalysisStep implements IOModularStep {
+  @override
+  List<DataId> get resultData => const [globalDataId, updatedDillId];
+
+  @override
+  bool get needsSources => false;
+
+  @override
+  List<DataId> get dependencyDataNeeded => const [dillId];
+
+  @override
+  List<DataId> get moduleDataNeeded => const [dillId];
+
+  @override
+  bool get onlyOnMain => true;
+
+  @override
+  Future<void> execute(
+      Module module, Uri root, ModuleDataToRelativeUri toUri) async {
+    if (_options.verbose) print("step: dart2js global analysis on $module");
+    Set<Module> transitiveDependencies = computeTransitiveDependencies(module);
+    Iterable<String> dillDependencies =
+        transitiveDependencies.map((m) => '${toUri(m, dillId)}');
+    var sdkRoot = Platform.script.resolve("../../../../");
+    List<String> args = [
+      '--packages=${sdkRoot.toFilePath()}/.packages',
+      'package:compiler/src/dart2js.dart',
+      '${toUri(module, dillId)}',
+      '--dill-dependencies=${dillDependencies.join(',')}',
+      '--write-data=${toUri(module, globalDataId)}',
+      '--out=${toUri(module, updatedDillId)}',
+    ];
+    var result =
+        await _runProcess(Platform.resolvedExecutable, args, root.toFilePath());
+
+    _checkExitCode(result, this, module);
+  }
+}
+
+// Step that invokes the dart2js backend on the main module given the results of
+// the global analysis step.
+class Dart2jsBackendStep implements IOModularStep {
+  @override
+  List<DataId> get resultData => const [jsId];
+
+  @override
+  bool get needsSources => false;
+
+  @override
+  List<DataId> get dependencyDataNeeded => const [];
+
+  @override
+  List<DataId> get moduleDataNeeded => const [updatedDillId, globalDataId];
+
+  @override
+  bool get onlyOnMain => true;
+
+  @override
+  Future<void> execute(
+      Module module, Uri root, ModuleDataToRelativeUri toUri) async {
+    if (_options.verbose) print("step: dart2js backend on $module");
+    var sdkRoot = Platform.script.resolve("../../../../");
+    List<String> args = [
+      '--packages=${sdkRoot.toFilePath()}/.packages',
+      'package:compiler/src/dart2js.dart',
+      '${toUri(module, updatedDillId)}',
+      '--read-data=${toUri(module, globalDataId)}',
+      '--out=${toUri(module, jsId)}',
+    ];
+    var result =
+        await _runProcess(Platform.resolvedExecutable, args, root.toFilePath());
+
+    _checkExitCode(result, this, module);
+  }
+}
+
+/// Step that runs the output of dart2js in d8 and saves the output.
+class RunD8 implements IOModularStep {
+  @override
+  List<DataId> get resultData => const [txtId];
+
+  @override
+  bool get needsSources => false;
+
+  @override
+  List<DataId> get dependencyDataNeeded => const [];
+
+  @override
+  List<DataId> get moduleDataNeeded => const [jsId];
+
+  @override
+  bool get onlyOnMain => true;
+
+  @override
+  Future<void> execute(
+      Module module, Uri root, ModuleDataToRelativeUri toUri) async {
+    if (_options.verbose) print("step: d8 on $module");
+    var sdkRoot = Platform.script.resolve("../../../../");
+    List<String> d8Args = [
+      sdkRoot
+          .resolve('sdk/lib/_internal/js_runtime/lib/preambles/d8.js')
+          .toFilePath(),
+      root.resolveUri(toUri(module, jsId)).toFilePath(),
+    ];
+    var result = await _runProcess(
+        sdkRoot.resolve(_d8executable).toFilePath(), d8Args, root.toFilePath());
+
+    _checkExitCode(result, this, module);
+
+    await File.fromUri(root.resolveUri(toUri(module, txtId)))
+        .writeAsString(result.stdout);
+  }
+}
+
+void _checkExitCode(ProcessResult result, IOModularStep step, Module module) {
+  if (result.exitCode != 0 || _options.verbose) {
+    stdout.write(result.stdout);
+    stderr.write(result.stderr);
+  }
+  if (result.exitCode != 0) {
+    exitCode = result.exitCode;
+    Expect.fail("${step.runtimeType} failed on $module");
+  }
+}
+
+Future<ProcessResult> _runProcess(
+    String command, List<String> arguments, String workingDirectory) {
+  if (_options.verbose) {
+    print('command:\n$command ${arguments.join(' ')} from $workingDirectory');
+  }
+  return Process.run(command, arguments, workingDirectory: workingDirectory);
+}
+
+String get _d8executable {
+  if (Platform.isWindows) {
+    return 'third_party/d8/windows/d8.exe';
+  } else if (Platform.isLinux) {
+    return 'third_party/d8/linux/d8';
+  } else if (Platform.isMacOS) {
+    return 'third_party/d8/macos/d8';
+  }
+  throw new UnsupportedError('Unsupported platform.');
+}
+
+class _Options {
+  bool showSkipped = false;
+  bool verbose = false;
+  String filter = null;
+
+  static _Options parse(List<String> args) {
+    var parser = new ArgParser()
+      ..addFlag('verbose',
+          abbr: 'v',
+          defaultsTo: false,
+          help: "print detailed information about the test and modular steps")
+      ..addFlag('show-skipped',
+          defaultsTo: false,
+          help: "print the name of the tests skipped by the filtering option")
+      ..addOption('filter',
+          help: "only run tests containing this filter as a substring");
+    ArgResults argResults = parser.parse(args);
+    return _Options()
+      ..showSkipped = argResults['show-skipped']
+      ..verbose = argResults['verbose']
+      ..filter = argResults['filter'];
+  }
+}
diff --git a/tests/compiler/dart2js/rti/factory_call_test.dart b/tests/compiler/dart2js/rti/factory_call_test.dart
index 5526cc0..392c989 100644
--- a/tests/compiler/dart2js/rti/factory_call_test.dart
+++ b/tests/compiler/dart2js/rti/factory_call_test.dart
@@ -46,7 +46,7 @@
     ProgramLookup programLookup = new ProgramLookup(compiler);
 
     js.Name getName(String name) {
-      return compiler.backend.namer
+      return compiler.backend.namerForTesting
           .globalPropertyNameForMember(lookupMember(elementEnvironment, name));
     }
 
@@ -81,14 +81,17 @@
       js.Name selector = getName(targetName);
       bool callFound = false;
       forEachNode(fun, onCall: (js.Call node) {
-        js.Expression target = node.target;
-        if (target is js.PropertyAccess && target.selector == selector) {
-          callFound = true;
-          Expect.equals(
-              expectedTypeArguments,
-              node.arguments.length,
-              "Unexpected argument count in $function call to $targetName: "
-              "${js.nodeToString(fun)}");
+        js.Expression target = js.undefer(node.target);
+        if (target is js.PropertyAccess) {
+          js.Node targetSelector = js.undefer(target.selector);
+          if (targetSelector is js.Name && targetSelector.key == selector.key) {
+            callFound = true;
+            Expect.equals(
+                expectedTypeArguments,
+                node.arguments.length,
+                "Unexpected argument count in $function call to $targetName: "
+                "${js.nodeToString(fun)}");
+          }
         }
       });
       Expect.isTrue(
diff --git a/tests/compiler/dart2js/rti/instance_call_test.dart b/tests/compiler/dart2js/rti/instance_call_test.dart
index 3b0c102..cdbbf3e 100644
--- a/tests/compiler/dart2js/rti/instance_call_test.dart
+++ b/tests/compiler/dart2js/rti/instance_call_test.dart
@@ -107,7 +107,7 @@
     ProgramLookup programLookup = new ProgramLookup(compiler);
 
     js.Name getName(String name, int typeArguments) {
-      return compiler.backend.namer.invocationName(new Selector.call(
+      return compiler.backend.namerForTesting.invocationName(new Selector.call(
           new PublicName(name),
           new CallStructure(1, const <String>[], typeArguments)));
     }
@@ -151,14 +151,17 @@
       js.Name selector = getName(targetName, expectedTypeArguments);
       bool callFound = false;
       forEachNode(fun, onCall: (js.Call node) {
-        js.Expression target = node.target;
-        if (target is js.PropertyAccess && target.selector == selector) {
-          callFound = true;
-          Expect.equals(
-              1 + expectedTypeArguments,
-              node.arguments.length,
-              "Unexpected argument count in $function call to $targetName: "
-              "${js.nodeToString(fun)}");
+        js.Expression target = js.undefer(node.target);
+        if (target is js.PropertyAccess) {
+          js.Node targetSelector = js.undefer(target.selector);
+          if (targetSelector is js.Name && targetSelector.key == selector.key) {
+            callFound = true;
+            Expect.equals(
+                1 + expectedTypeArguments,
+                node.arguments.length,
+                "Unexpected argument count in $function call to $targetName: "
+                "${js.nodeToString(fun)}");
+          }
         }
       });
       Expect.isTrue(callFound,
diff --git a/tests/compiler/dart2js/rti/type_representation_test.dart b/tests/compiler/dart2js/rti/type_representation_test.dart
index 97bd3d6..0729ef9 100644
--- a/tests/compiler/dart2js/rti/type_representation_test.dart
+++ b/tests/compiler/dart2js/rti/type_representation_test.dart
@@ -14,7 +14,7 @@
 import 'package:compiler/src/elements/entities.dart';
 import 'package:compiler/src/js_backend/backend.dart' show JavaScriptBackend;
 import 'package:compiler/src/js_backend/runtime_types.dart'
-    show TypeRepresentationGenerator;
+    show RuntimeTypeTags, TypeRepresentationGenerator;
 import 'package:compiler/src/world.dart';
 import 'package:expect/expect.dart';
 import '../helpers/element_lookup.dart';
@@ -67,9 +67,10 @@
   Compiler compiler = result.compiler;
   JavaScriptBackend backend = compiler.backend;
 
+  RuntimeTypeTags rtiTags = const RuntimeTypeTags();
   TypeRepresentationGenerator typeRepresentation =
       new TypeRepresentationGenerator(
-          backend.namer, compiler.backendClosedWorldForTesting.nativeData);
+          rtiTags, compiler.backendClosedWorldForTesting.nativeData);
 
   Expression onVariable(TypeVariableType _variable) {
     TypeVariableType variable = _variable;
@@ -111,15 +112,15 @@
 
   JClosedWorld closedWorld = compiler.backendClosedWorldForTesting;
   ElementEnvironment elementEnvironment = closedWorld.elementEnvironment;
-  String func = backend.namer.functionTypeTag;
-  String ret = backend.namer.functionTypeReturnTypeTag;
+  String func = rtiTags.functionTypeTag;
+  String ret = rtiTags.functionTypeReturnTypeTag;
   String retvoid = '$ret: -1';
-  String args = backend.namer.functionTypeRequiredParametersTag;
-  String opt = backend.namer.functionTypeOptionalParametersTag;
-  String named = backend.namer.functionTypeNamedParametersTag;
-  String bounds = backend.namer.functionTypeGenericBoundsTag;
-  String futureOr = backend.namer.futureOrTag;
-  String futureOrType = backend.namer.futureOrTypeTag;
+  String args = rtiTags.functionTypeRequiredParametersTag;
+  String opt = rtiTags.functionTypeOptionalParametersTag;
+  String named = rtiTags.functionTypeNamedParametersTag;
+  String bounds = rtiTags.functionTypeGenericBoundsTag;
+  String futureOr = rtiTags.futureOrTag;
+  String futureOrType = rtiTags.futureOrTypeTag;
 
   ClassEntity List_ = findClass(closedWorld, 'List');
   TypeVariableType List_E =
diff --git a/tests/compiler/dart2js/serialization/serialization_test_helper.dart b/tests/compiler/dart2js/serialization/serialization_test_helper.dart
index 9f48d01..43ee996 100644
--- a/tests/compiler/dart2js/serialization/serialization_test_helper.dart
+++ b/tests/compiler/dart2js/serialization/serialization_test_helper.dart
@@ -60,7 +60,7 @@
 
   Map<OutputType, Map<String, String>> output = collector1.clear();
 
-  compiler.generateJavaScriptCode(newGlobalInferenceResults);
+  compiler.emitJavaScriptCode(newGlobalInferenceResults);
   Map<OutputType, Map<String, String>> newOutput = collector2.clear();
 
   Expect.setEquals(output.keys, newOutput.keys, "Output type mismatch.");
diff --git a/tests/compiler/dart2js/static_type/data/assert.dart b/tests/compiler/dart2js/static_type/data/assert.dart
index 0f0057e..54f2a34 100644
--- a/tests/compiler/dart2js/static_type/data/assert.dart
+++ b/tests/compiler/dart2js/static_type/data/assert.dart
@@ -18,25 +18,25 @@
 }
 
 assert1(Class c) {
-  assert(/*Class*/ c /*invoke: bool*/ != null);
+  assert(/*Class*/ c /*invoke: [Class]->bool*/ != null);
   /*Class*/ c.next;
 }
 
 assert2(Class c) {
-  assert(/*Class*/ c /*invoke: bool*/ == null);
+  assert(/*Class*/ c /*invoke: [Class]->bool*/ == null);
   /*Class*/ c.next;
 }
 
 assert3(Class c) {
   bool b;
-  assert(/*Class*/ c /*invoke: bool*/ != null);
+  assert(/*Class*/ c /*invoke: [Class]->bool*/ != null);
   if (/*bool*/ b) return;
   /*Class*/ c.next;
 }
 
 assert4(Class c) {
   bool b;
-  assert(/*Class*/ c /*invoke: bool*/ == null);
+  assert(/*Class*/ c /*invoke: [Class]->bool*/ == null);
   if (/*bool*/ b) return;
   /*Class*/ c.next;
 }
diff --git a/tests/compiler/dart2js/static_type/data/assert_ea.dart b/tests/compiler/dart2js/static_type/data/assert_ea.dart
index 9e6edbd..c28215d 100644
--- a/tests/compiler/dart2js/static_type/data/assert_ea.dart
+++ b/tests/compiler/dart2js/static_type/data/assert_ea.dart
@@ -18,25 +18,25 @@
 }
 
 assert1(Class c) {
-  assert(/*Class*/ c /*invoke: bool*/ != null);
+  assert(/*Class*/ c /*invoke: [Class]->bool*/ != null);
   /*Class*/ c.next;
 }
 
 assert2(Class c) {
-  assert(/*Class*/ c /*invoke: bool*/ == null);
+  assert(/*Class*/ c /*invoke: [Class]->bool*/ == null);
   /*Null*/ c.next;
 }
 
 assert3(Class c) {
   bool b;
-  assert(/*Class*/ c /*invoke: bool*/ != null);
+  assert(/*Class*/ c /*invoke: [Class]->bool*/ != null);
   if (/*bool*/ b) return;
   /*Class*/ c.next;
 }
 
 assert4(Class c) {
   bool b;
-  assert(/*Class*/ c /*invoke: bool*/ == null);
+  assert(/*Class*/ c /*invoke: [Class]->bool*/ == null);
   if (/*bool*/ b) return;
   /*Null*/ c.next;
 }
diff --git a/tests/compiler/dart2js/static_type/data/cascade.dart b/tests/compiler/dart2js/static_type/data/cascade.dart
new file mode 100644
index 0000000..4f2f6a5
--- /dev/null
+++ b/tests/compiler/dart2js/static_type/data/cascade.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+main() {
+  promotedCascade(null);
+}
+
+promotedCascade(dynamic value) {
+  if (/*dynamic*/ value is List<String>) {
+    value = '[${(
+        /*List<String>*/ value.. /*invoke: [List<String>]->void*/ sort()). /*invoke: [List<String>]->String*/ join(',')}]';
+  }
+  return /*dynamic*/ value;
+}
diff --git a/tests/compiler/dart2js/static_type/data/closure.dart b/tests/compiler/dart2js/static_type/data/closure.dart
index 0878854..f24f209 100644
--- a/tests/compiler/dart2js/static_type/data/closure.dart
+++ b/tests/compiler/dart2js/static_type/data/closure.dart
@@ -29,7 +29,7 @@
     }
 
     /*dynamic*/ c.next;
-    /*invoke: Null*/ local();
+    /*invoke: [Null Function()]->Null*/ local();
     /*dynamic*/ c.next;
   }
 }
@@ -42,7 +42,7 @@
     }
 
     /*Class*/ c.next;
-    /*invoke: Null*/ local();
+    /*invoke: [Null Function()]->Null*/ local();
     /*Class*/ c.next;
   }
 }
@@ -56,7 +56,7 @@
 
     c = 0;
     /*dynamic*/ c.next;
-    /*invoke: Null*/ local();
+    /*invoke: [Null Function()]->Null*/ local();
     /*dynamic*/ c.next;
   }
 }
@@ -69,7 +69,7 @@
     }
 
     /*Class*/ c.next;
-    /*invoke: Null*/ local();
+    /*invoke: [Null Function()]->Null*/ local();
     /*Class*/ c.next;
     c = 0;
     /*dynamic*/ c.next;
@@ -85,7 +85,7 @@
     }
 
     /*dynamic*/ c.next;
-    /*invoke: Null*/ local();
+    /*invoke: [Null Function()]->Null*/ local();
     /*dynamic*/ c.next;
     c = 0;
     /*dynamic*/ c.next;
@@ -101,7 +101,7 @@
   }
 
   /*dynamic*/ c.next;
-  /*invoke: Null*/ local();
+  /*invoke: [Null Function()]->Null*/ local();
   /*dynamic*/ c.next;
   c = 0;
   /*dynamic*/ c.next;
@@ -118,10 +118,11 @@
 closure6(var x) {
   var closure;
   /*dynamic*/ x is B &&
-      _returnTrue(closure = () => /*dynamic*/ x. /*invoke: dynamic*/ f());
+      _returnTrue(
+          closure = () => /*dynamic*/ x. /*invoke: [dynamic]->dynamic*/ f());
   /*dynamic*/ x;
   x = new A();
-  /*dynamic*/ closure. /*invoke: dynamic*/ call();
+  /*dynamic*/ closure. /*invoke: [dynamic]->dynamic*/ call();
   /*dynamic*/ x;
 }
 
@@ -137,20 +138,20 @@
 
 _closure7(C x) {
   /*C*/ x is D && _returnTrue((() => /*C*/ x))
-      ? /*D*/ x. /*invoke: dynamic*/ f()
+      ? /*D*/ x. /*invoke: [D]->dynamic*/ f()
       : x = new C();
   _returnTrue((() => /*C*/ x)) && /*C*/ x is D
-      ? /*D*/ x. /*invoke: dynamic*/ f()
+      ? /*D*/ x. /*invoke: [D]->dynamic*/ f()
       : x = new C();
 
   (/*C*/ x is D && _returnTrue((() => /*C*/ x))) &&
           (/*D*/ x is E && _returnTrue((() => /*C*/ x)))
-      ? /*E*/ x. /*invoke: dynamic*/ g()
+      ? /*E*/ x. /*invoke: [E]->dynamic*/ g()
       : x = new C();
 
   (_returnTrue((() => /*C*/ x)) && /*C*/ x is E) &&
           (_returnTrue((() => /*C*/ x)) && /*E*/ x is D)
-      ? /*E*/ x. /*invoke: dynamic*/ g()
+      ? /*E*/ x. /*invoke: [E]->dynamic*/ g()
       : x = new C();
 }
 
diff --git a/tests/compiler/dart2js/static_type/data/do.dart b/tests/compiler/dart2js/static_type/data/do.dart
index 205480d..0d0952b 100644
--- a/tests/compiler/dart2js/static_type/data/do.dart
+++ b/tests/compiler/dart2js/static_type/data/do.dart
@@ -20,7 +20,7 @@
         /*Class*/ c.next;
       }
       c = 0;
-    } while (/*dynamic*/ c /*invoke: bool*/ != null);
+    } while (/*dynamic*/ c /*invoke: [dynamic]->bool*/ != null);
     /*dynamic*/ c.next;
   }
 }
@@ -30,7 +30,7 @@
     /*Class*/ c.next;
     do {
       /*Class*/ c.next;
-    } while (/*Class*/ c /*invoke: bool*/ != null);
+    } while (/*Class*/ c /*invoke: [Class]->bool*/ != null);
     /*Class*/ c.next;
   }
 }
diff --git a/tests/compiler/dart2js/static_type/data/effectively_final.dart b/tests/compiler/dart2js/static_type/data/effectively_final.dart
index 58bd022..a50cdaf 100644
--- a/tests/compiler/dart2js/static_type/data/effectively_final.dart
+++ b/tests/compiler/dart2js/static_type/data/effectively_final.dart
@@ -11,14 +11,14 @@
 
 effectivelyFinalList() {
   dynamic c = [];
-  /*List<dynamic>*/ c. /*invoke: void*/ add(null);
-  /*List<dynamic>*/ c.length /*invoke: int*/ + 1;
+  /*List<dynamic>*/ c. /*invoke: [List<dynamic>]->void*/ add(null);
+  /*List<dynamic>*/ c.length /*invoke: [int]->int*/ + 1;
 }
 
 notEffectivelyFinalList() {
   dynamic c = [];
-  /*dynamic*/ c. /*invoke: dynamic*/ add(null);
-  /*dynamic*/ c.length /*invoke: dynamic*/ + 1;
+  /*dynamic*/ c. /*invoke: [dynamic]->dynamic*/ add(null);
+  /*dynamic*/ c.length /*invoke: [dynamic]->dynamic*/ + 1;
   c = null;
 }
 
@@ -26,9 +26,9 @@
 
 effectivelyFinalPromoted() {
   dynamic c = _method1();
-  /*num*/ c /*invoke: num*/ + 0;
+  /*num*/ c /*invoke: [num]->num*/ + 0;
   if (/*num*/ c is int) {
-    /*int*/ c /*invoke: int*/ + 1;
+    /*int*/ c /*invoke: [int]->int*/ + 1;
   }
 }
 
@@ -36,8 +36,8 @@
 
 effectivelyFinalPromotedInvalid() {
   dynamic c = _method2();
-  /*String*/ c /*invoke: String*/ + '';
+  /*String*/ c /*invoke: [String]->String*/ + '';
   if (/*String*/ c is int) {
-    /*int*/ c /*invoke: int*/ + 1;
+    /*int*/ c /*invoke: [int]->int*/ + 1;
   }
 }
diff --git a/tests/compiler/dart2js/static_type/data/for.dart b/tests/compiler/dart2js/static_type/data/for.dart
index d755de9..3d4bb82 100644
--- a/tests/compiler/dart2js/static_type/data/for.dart
+++ b/tests/compiler/dart2js/static_type/data/for.dart
@@ -17,7 +17,7 @@
   if (/*dynamic*/ c is Class) {
     /*Class*/ c.next;
     for (/*Class*/ c.next;
-        /*dynamic*/ c /*invoke: bool*/ != null;
+        /*dynamic*/ c /*invoke: [dynamic]->bool*/ != null;
         /*dynamic*/ c.next) {
       /*dynamic*/ c.next;
       if (/*dynamic*/ c is Class) {
@@ -33,7 +33,7 @@
   if (/*dynamic*/ c is Class) {
     /*Class*/ c.next;
     for (/*Class*/ c.next;
-        /*Class*/ c /*invoke: bool*/ != null;
+        /*Class*/ c /*invoke: [Class]->bool*/ != null;
         /*Class*/ c.next) {
       /*Class*/ c.next;
     }
diff --git a/tests/compiler/dart2js/static_type/data/generic_method.dart b/tests/compiler/dart2js/static_type/data/generic_method.dart
index 99a2f17..8026b3c 100644
--- a/tests/compiler/dart2js/static_type/data/generic_method.dart
+++ b/tests/compiler/dart2js/static_type/data/generic_method.dart
@@ -19,16 +19,16 @@
 
 genericMethod1(c) {
   if (/*dynamic*/ c is Class1) {
-    /*Class1*/ c. /*invoke: String*/ method('').length;
+    /*Class1*/ c. /*invoke: [Class1]->String*/ method('').length;
   }
 }
 
 genericMethod2(c) {
   if (/*dynamic*/ c is! Class1) return;
-  /*Class1*/ c. /*invoke: dynamic*/ method('').length;
+  /*Class1*/ c. /*invoke: [Class1]->dynamic*/ method('').length;
 }
 
 genericMethod3() {
   dynamic c = new Class2<int>();
-  /*Class2<int>*/ c. /*invoke: int*/ method();
+  /*Class2<int>*/ c. /*invoke: [Class2<int>]->int*/ method();
 }
diff --git a/tests/compiler/dart2js/static_type/data/null.dart b/tests/compiler/dart2js/static_type/data/null.dart
index c0b9386..dcbe522 100644
--- a/tests/compiler/dart2js/static_type/data/null.dart
+++ b/tests/compiler/dart2js/static_type/data/null.dart
@@ -19,46 +19,46 @@
 
 null1(dynamic c) {
   /*dynamic*/ c.next;
-  /*dynamic*/ c /*invoke: bool*/ != null;
+  /*dynamic*/ c /*invoke: [dynamic]->bool*/ != null;
   /*dynamic*/ c.next;
 }
 
 null2(dynamic c) {
   /*dynamic*/ c.next;
-  /*dynamic*/ c /*invoke: bool*/ == null;
+  /*dynamic*/ c /*invoke: [dynamic]->bool*/ == null;
   /*dynamic*/ c.next;
 }
 
 null3(dynamic c) {
-  if (/*dynamic*/ c /*invoke: bool*/ == null) return;
+  if (/*dynamic*/ c /*invoke: [dynamic]->bool*/ == null) return;
   /*dynamic*/ c.next;
 }
 
 null4(dynamic c) {
-  if (/*dynamic*/ c /*invoke: bool*/ != null) return;
+  if (/*dynamic*/ c /*invoke: [dynamic]->bool*/ != null) return;
   /*Null*/ c.next;
 }
 
 null5(dynamic c) {
-  if (/*dynamic*/ c /*invoke: bool*/ != null) {
+  if (/*dynamic*/ c /*invoke: [dynamic]->bool*/ != null) {
     /*dynamic*/ c.next;
   }
 }
 
 null6(dynamic c) {
-  if (/*dynamic*/ c /*invoke: bool*/ == null) {
+  if (/*dynamic*/ c /*invoke: [dynamic]->bool*/ == null) {
     /*Null*/ c.next;
   }
 }
 
 null7(dynamic c) {
-  while (/*dynamic*/ c /*invoke: bool*/ != null) {
+  while (/*dynamic*/ c /*invoke: [dynamic]->bool*/ != null) {
     /*dynamic*/ c.next;
   }
 }
 
 null8(dynamic c) {
-  while (/*dynamic*/ c /*invoke: bool*/ == null) {
+  while (/*dynamic*/ c /*invoke: [dynamic]->bool*/ == null) {
     /*Null*/ c.next;
   }
 }
diff --git a/tests/compiler/dart2js/static_type/data/null_access.dart b/tests/compiler/dart2js/static_type/data/null_access.dart
index de65e93..4c7735a 100644
--- a/tests/compiler/dart2js/static_type/data/null_access.dart
+++ b/tests/compiler/dart2js/static_type/data/null_access.dart
@@ -16,7 +16,7 @@
 
 test1() {
   const Class1 c = null;
-  return /*Null*/ c. /*invoke: void*/ method1();
+  return /*Null*/ c. /*invoke: [Null]->void*/ method1();
 }
 
 class Class2<T> {
@@ -28,7 +28,7 @@
 test2() {
   const Class2<int> c = null;
   // TODO(johnniwinther): Track the unreachable code properly.
-  return /*Null*/ c. /*invoke: <bottom>*/ method2();
+  return /*Null*/ c. /*invoke: [Null]-><bottom>*/ method2();
 }
 
 class Class3<T> {
@@ -40,5 +40,5 @@
 test3() {
   const Class3<int> c = null;
   // TODO(johnniwinther): Track the unreachable code properly.
-  return /*Null*/ c. /*invoke: Class3<<bottom>>*/ method3();
+  return /*Null*/ c. /*invoke: [Null]->Class3<<bottom>>*/ method3();
 }
diff --git a/tests/compiler/dart2js/static_type/data/while.dart b/tests/compiler/dart2js/static_type/data/while.dart
index e646074..b21dee0 100644
--- a/tests/compiler/dart2js/static_type/data/while.dart
+++ b/tests/compiler/dart2js/static_type/data/while.dart
@@ -16,15 +16,15 @@
   whileNext(null);
   whileNextGeneric(null);
   new Class1<int>()
-    .. /*invoke: dynamic*/ whileNext1()
-    .. /*invoke: dynamic*/ whileNext2()
-    .. /*invoke: dynamic*/ whileNext3();
+    .. /*invoke: [Class1<int>]->dynamic*/ whileNext1()
+    .. /*invoke: [Class1<int>]->dynamic*/ whileNext2()
+    .. /*invoke: [Class1<int>]->dynamic*/ whileNext3();
 }
 
 while1(dynamic c) {
   if (/*dynamic*/ c is Class) {
     /*Class*/ c.next;
-    while (/*dynamic*/ c /*invoke: bool*/ != null) {
+    while (/*dynamic*/ c /*invoke: [dynamic]->bool*/ != null) {
       /*dynamic*/ c.next;
       if (/*dynamic*/ c is Class) {
         /*Class*/ c.next;
@@ -38,7 +38,7 @@
 while2(dynamic c) {
   if (/*dynamic*/ c is Class) {
     /*Class*/ c.next;
-    while (/*Class*/ c /*invoke: bool*/ != null) {
+    while (/*Class*/ c /*invoke: [Class]->bool*/ != null) {
       /*Class*/ c.next;
     }
     /*Class*/ c.next;
@@ -46,14 +46,15 @@
 }
 
 whileNext(Class c) {
-  while (/*Class*/ c /*invoke: bool*/ != null) {
+  while (/*Class*/ c /*invoke: [Class]->bool*/ != null) {
     c = /*Class*/ c.next;
   }
   return /*Class*/ c;
 }
 
 whileNextGeneric(GenericClass<int> c) {
-  while (/*GenericClass<int>*/ c /*invoke: bool*/ != null) {
+  while (
+      /*GenericClass<int>*/ c /*invoke: [GenericClass<int>]->bool*/ != null) {
     c = /*GenericClass<int>*/ c.next;
   }
   return /*GenericClass<int>*/ c;
@@ -77,7 +78,7 @@
   whileNext2() {
     bool b;
     GenericClass<T> c;
-    while (/*GenericClass<T>*/ c /*invoke: bool*/ != null) {
+    while (/*GenericClass<T>*/ c /*invoke: [GenericClass<T>]->bool*/ != null) {
       if (/*bool*/ b) {
         GenericClass<T> next = /*GenericClass<T>*/ c.next;
         c = /*GenericClass<T>*/ next;
@@ -91,7 +92,7 @@
   whileNext3() {
     bool b;
     GenericClass<T> c;
-    while (/*GenericClass<T>*/ c /*invoke: bool*/ == null) {
+    while (/*GenericClass<T>*/ c /*invoke: [GenericClass<T>]->bool*/ == null) {
       if (/*bool*/ b) {
         GenericClass<T> next = /*Null*/ c.next;
         c = /*GenericClass<T>*/ next;
diff --git a/tests/compiler/dart2js/static_type/static_type_test.dart b/tests/compiler/dart2js/static_type/static_type_test.dart
index 58ec517..369d14c 100644
--- a/tests/compiler/dart2js/static_type/static_type_test.dart
+++ b/tests/compiler/dart2js/static_type/static_type_test.dart
@@ -84,8 +84,11 @@
 
   @override
   String computeNodeValue(Id id, ir.TreeNode node) {
-    if (node is ir.VariableGet || node is ir.MethodInvocation) {
+    if (node is ir.VariableGet) {
       return typeToText(node.accept(staticTypeCache));
+    } else if (node is ir.MethodInvocation) {
+      return '[${typeToText(node.receiver.accept(staticTypeCache))}]->'
+          '${typeToText(node.accept(staticTypeCache))}';
     }
     return null;
   }
diff --git a/tests/compiler/dart2js_extra/dart2js_extra.status b/tests/compiler/dart2js_extra/dart2js_extra.status
index 4facaed..b1acb29 100644
--- a/tests/compiler/dart2js_extra/dart2js_extra.status
+++ b/tests/compiler/dart2js_extra/dart2js_extra.status
@@ -4,6 +4,7 @@
 
 [ $compiler == dart2js ]
 23264_test: RuntimeError
+bound_closure_interceptor_type_test: RuntimeError
 bounds_check4a_test: RuntimeError # Issue 32741
 bounds_check4b_test: RuntimeError # Issue 32741
 class_test: Fail
@@ -126,21 +127,6 @@
 type_literal_test: Fail, OK # Tests expected output of Type.toString().
 typevariable_typedef_test: Fail, OK # Tests expected output of Type.toString().
 
-[ $compiler == dart2js && $strong ]
-bound_closure_interceptor_type_test: RuntimeError
-
-[ $compiler == dart2js && !$strong ]
-extract_type_arguments_1_test: RuntimeError # Uses function type variables
-extract_type_arguments_2_test: RuntimeError # Uses function type variables
-extract_type_arguments_3_test: RuntimeError # Uses function type variables
-generic_method_dynamic_is_test: RuntimeError # Test against function type variables is only supported in strong mode.
-generic_method_dynamic_type_test: SkipByDesign # Requires strong mode support for function type variables.
-generic_method_static_is_test: RuntimeError # Test against function type variables is only supported in strong mode.
-int_index_test/01: MissingCompileTimeError
-int_index_test/02: MissingCompileTimeError
-local_signature_test: RuntimeError # Test against function type variables is only supported in strong mode.
-switch_test/00: MissingCompileTimeError
-
 [ $compiler == dart2js && ($runtime == chrome || $runtime == chromeOnAndroid || $runtime == ff || $runtime == safari) ]
 isolate2_test/01: Fail # Issue 14458.
 
diff --git a/tests/corelib_2/corelib_2.status b/tests/corelib_2/corelib_2.status
index 45e2873..b196c6f 100644
--- a/tests/corelib_2/corelib_2.status
+++ b/tests/corelib_2/corelib_2.status
@@ -26,7 +26,9 @@
 double_floor_test/int64: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
 double_round_test/int64: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
 double_truncate_test/int64: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
+error_stack_trace1_test: RuntimeError # Issue 12399
 growable_list_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
+growable_list_test: RuntimeError # Concurrent modifications test always runs
 int_ceil_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
 int_ceil_to_double_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
 int_floor_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
@@ -43,7 +45,12 @@
 int_truncate_to_double_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
 integer_arith_vm_test/modPow: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
 integer_arith_vm_test/none: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
+integer_to_radix_string_test/01: RuntimeError
+integer_to_radix_string_test/02: RuntimeError
+integer_to_radix_string_test/none: RuntimeError
+integer_to_string_test/01: RuntimeError
 integer_to_string_test/01: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
+iterable_return_type_test/02: RuntimeError # Dart2js does not support Uint64*.
 list_unmodifiable_test: Pass, RuntimeError # Issue 28712
 num_parse_test/01: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
 num_parse_test/none: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
@@ -88,12 +95,6 @@
 symbol_reserved_word_test/04: MissingCompileTimeError
 symbol_reserved_word_test/07: MissingCompileTimeError
 
-[ !$strong ]
-cast_test: SkipByDesign # Uses generic method parameters.
-iterable_where_type_test: SkipByDesign
-map_test: SkipByDesign
-regress_33166_test: SkipByDesign # Not a Dart 1 test
-
 [ $arch == simarmv5te && ($runtime == dart_precompiled || $runtime == vm) ]
 int_parse_radix_test/*: Pass, Slow
 integer_parsed_mul_div_vm_test: Pass, Slow
@@ -111,8 +112,9 @@
 error_stack_trace1_test: SkipByDesign # Expects unobfuscated stack trace
 
 # All static_tests have expected compile-time errors.
-[ $compiler != app_jitk && $compiler != dart2analyzer && $compiler != dart2js && $compiler != dartdevc && $compiler != dartdevk && $compiler != dartk && $compiler != dartkb && $compiler != dartkp && $compiler != fasta && $strong ]
+[ $compiler != app_jitk && $compiler != dart2analyzer && $compiler != dart2js && $compiler != dartdevc && $compiler != dartdevk && $compiler != dartk && $compiler != dartkb && $compiler != dartkp && $compiler != fasta ]
 core_runtime_types_static_test: MissingCompileTimeError
+iterable_mapping_test/01: MissingCompileTimeError
 splay_tree_test/01: MissingCompileTimeError
 splay_tree_test/02: MissingCompileTimeError
 string_base_vm_static_test: MissingCompileTimeError
@@ -122,9 +124,6 @@
 [ $compiler != app_jitk && $compiler != dart2js && $compiler != dartdevc && $compiler != dartdevk && $compiler != dartk && $compiler != dartkb && $compiler != dartkp && $compiler != fasta ]
 iterable_element_at_test/static: MissingCompileTimeError
 
-[ $compiler != app_jitk && $compiler != dart2js && $compiler != dartdevc && $compiler != dartdevk && $compiler != dartk && $compiler != dartkb && $compiler != dartkp && $compiler != fasta && ($compiler != dart2analyzer || !$strong) ]
-iterable_mapping_test/01: MissingCompileTimeError
-
 [ $compiler != app_jitk && $compiler != dart2js && $compiler != dartdevc && $compiler != dartdevk && $compiler != dartk && $compiler != dartkb && $compiler != dartkp && $runtime != none ]
 map_keys2_test: RuntimeError # needs Dart 2 is checks
 
@@ -141,22 +140,16 @@
 [ $compiler == dart2js && $runtime != none ]
 regexp/pcre_test: Pass, Slow # Issue 21593
 
-[ $compiler == dart2js && $runtime != none && !$strong ]
-collection_of_test: RuntimeError # Strong mode test
-map_of_test: RuntimeError # Strong mode test
-
 [ $compiler == dart2js && $runtime == safari ]
 regexp/lookahead_test: RuntimeError
 regexp/no-extensions_test: RuntimeError
-regexp/overflow_test: RuntimeError
-
-[ $compiler == dart2js && $runtime == safari && $strong ]
 regexp/no-extensions_test: Pass, RuntimeError
+regexp/overflow_test: RuntimeError
 
 [ $compiler == dart2js && !$browser ]
 package_resource_test: RuntimeError # Issue 26842
 
-[ $compiler == dart2js && $checked && $strong ]
+[ $compiler == dart2js && $checked ]
 apply3_test: RuntimeError
 collection_of_test: RuntimeError
 error_stack_trace1_test: RuntimeError # Issue 12399
@@ -188,7 +181,7 @@
 map_test: Crash # tests/corelib_2/map_test.dart:903:7: Internal problem: Unhandled Null in installDefaultConstructor.
 symbol_reserved_word_test/03: RuntimeError # Issue 19972, new Symbol('void') should be allowed.
 
-[ $compiler == dart2js && $minified && $strong ]
+[ $compiler == dart2js && $minified ]
 dynamic_nosuchmethod_test: RuntimeError
 error_stack_trace1_test: RuntimeError # Issue 12399
 growable_list_test: RuntimeError # Concurrent modifications test always runs
@@ -208,30 +201,10 @@
 symbol_operator_test/none: RuntimeError
 symbol_reserved_word_test/03: RuntimeError # Issue 19972, new Symbol('void') should be allowed.
 
-[ $compiler == dart2js && $strong ]
-error_stack_trace1_test: RuntimeError # Issue 12399
-growable_list_test: RuntimeError # Concurrent modifications test always runs
-integer_to_radix_string_test/01: RuntimeError
-integer_to_radix_string_test/02: RuntimeError
-integer_to_radix_string_test/none: RuntimeError
-integer_to_string_test/01: RuntimeError
-iterable_return_type_test/02: RuntimeError # Dart2js does not support Uint64*.
-
-[ $compiler == dart2js && !$strong ]
-*: SkipByDesign
-
 [ $compiler == dartdevc && $runtime != none ]
 compare_to2_test: CompileTimeError # invalid test
 symbol_operator_test: RuntimeError # Issue 29921
 
-[ $compiler != dartdevc && $compiler != dartdevk && $checked && !$strong ]
-core_runtime_types_static_test: MissingCompileTimeError
-splay_tree_test/01: MissingCompileTimeError
-splay_tree_test/02: MissingCompileTimeError
-string_base_vm_static_test: MissingCompileTimeError
-string_replace_static_test: MissingCompileTimeError
-string_static_test: MissingCompileTimeError
-
 [ $compiler != dartk && $runtime == vm && $checked ]
 apply_test/01: RuntimeError
 
@@ -240,7 +213,7 @@
 symbol_test/02: MissingCompileTimeError
 symbol_test/03: MissingCompileTimeError
 
-[ $compiler == dartkp && $runtime == dart_precompiled && $strong ]
+[ $compiler == dartkp && $runtime == dart_precompiled ]
 iterable_fold_test/02: RuntimeError
 iterable_reduce_test/01: CompileTimeError # Issue 31533
 iterable_reduce_test/none: RuntimeError
@@ -252,9 +225,6 @@
 symbol_test/none: RuntimeError # Issues 11669 and 31936 - throwing const constructors.
 unicode_test: RuntimeError # Issue 18061: German double S.
 
-[ $compiler != fasta && !$strong ]
-core_runtime_types_test: SkipByDesign
-
 [ $compiler == none && $runtime == vm ]
 from_environment_const_type_undefined_test/09: MissingCompileTimeError
 from_environment_const_type_undefined_test/11: MissingCompileTimeError
@@ -290,7 +260,7 @@
 typed_data_with_limited_ints_test: Skip # Requires fixed-size int64 support.
 
 # ===== dartk + vm status lines =====
-[ $runtime == vm && $strong && ($compiler == dartk || $compiler == dartkb) ]
+[ $runtime == vm && ($compiler == dartk || $compiler == dartkb) ]
 iterable_fold_test/02: RuntimeError
 iterable_reduce_test/01: CompileTimeError # Issue 31533
 iterable_reduce_test/none: RuntimeError
@@ -301,71 +271,15 @@
 symbol_test/none: RuntimeError # Issues 11669 and 31936 - throwing const constructors.
 unicode_test: RuntimeError # Issue 18061: German double S.
 
-[ $runtime == vm && !$strong ]
-collection_of_test: RuntimeError
-
-[ !$checked && !$strong ]
-core_runtime_types_static_test: MissingCompileTimeError
-splay_tree_test/01: MissingCompileTimeError
-splay_tree_test/02: MissingCompileTimeError
-string_base_vm_static_test: MissingCompileTimeError
-string_replace_static_test: MissingCompileTimeError
-string_static_test: MissingCompileTimeError
-
 # We no longer expect Dart2 tests to run with the standalone VM without the new
 # common front end, but for now we get better coverage by still running them in
 # checked mode, which is mostly Dart2-compatible.
 [ !$checked && ($compiler == app_jit || $compiler == none || $compiler == precompiler) && ($runtime == dart_precompiled || $runtime == vm) ]
 *: SkipByDesign
 
-[ $fasta && !$strong ]
-bool_from_environment2_test/01: MissingCompileTimeError
-bool_from_environment2_test/02: MissingCompileTimeError
-bool_from_environment2_test/04: MissingCompileTimeError
-bool_from_environment2_test/05: MissingCompileTimeError
-from_environment_const_type_test/02: MissingCompileTimeError
-from_environment_const_type_test/03: MissingCompileTimeError
-from_environment_const_type_test/04: MissingCompileTimeError
-from_environment_const_type_test/06: MissingCompileTimeError
-from_environment_const_type_test/07: MissingCompileTimeError
-from_environment_const_type_test/08: MissingCompileTimeError
-from_environment_const_type_test/09: MissingCompileTimeError
-from_environment_const_type_test/11: MissingCompileTimeError
-from_environment_const_type_test/12: MissingCompileTimeError
-from_environment_const_type_test/13: MissingCompileTimeError
-from_environment_const_type_test/14: MissingCompileTimeError
-from_environment_const_type_test/16: MissingCompileTimeError
-from_environment_const_type_undefined_test/02: MissingCompileTimeError
-from_environment_const_type_undefined_test/03: MissingCompileTimeError
-from_environment_const_type_undefined_test/04: MissingCompileTimeError
-from_environment_const_type_undefined_test/06: MissingCompileTimeError
-from_environment_const_type_undefined_test/07: MissingCompileTimeError
-from_environment_const_type_undefined_test/08: MissingCompileTimeError
-from_environment_const_type_undefined_test/09: MissingCompileTimeError
-from_environment_const_type_undefined_test/11: MissingCompileTimeError
-from_environment_const_type_undefined_test/12: MissingCompileTimeError
-from_environment_const_type_undefined_test/13: MissingCompileTimeError
-from_environment_const_type_undefined_test/14: MissingCompileTimeError
-from_environment_const_type_undefined_test/16: MissingCompileTimeError
-int_parse_radix_bad_handler_test: MissingCompileTimeError
-iterable_element_at_test/static: MissingCompileTimeError
-iterable_mapping_test/01: MissingCompileTimeError
-string_from_environment3_test/01: MissingCompileTimeError
-string_from_environment3_test/02: MissingCompileTimeError
-string_from_environment3_test/04: MissingCompileTimeError
-string_from_environment3_test/05: MissingCompileTimeError
-symbol_reserved_word_test/05: MissingCompileTimeError
-symbol_test/01: MissingCompileTimeError
-
 [ !$preview_dart_2 && ($runtime == dart_precompiled || $runtime == vm) ]
 *: SkipByDesign # Deprecating all Dart1 modes of execution
 
-[ !$strong && ($compiler == dartk || $compiler == dartkb || $compiler == dartkp) ]
-*: SkipByDesign
-
-[ !$strong && ($runtime == dart_precompiled || $runtime == vm) ]
-list_test/*: RuntimeError # VM doesn't implement strong mode covariance checks
-
 [ ($arch == simdbc || $arch == simdbc64) && ($hot_reload || $hot_reload_rollback) ]
 uri_parse_test: SkipSlow
 
@@ -521,12 +435,6 @@
 bigint_test/03: SkipSlow # --no_intrinsify
 bigint_test/15: SkipSlow # --no_intrinsify
 
-[ $compiler == precompiler || $runtime == vm && !$checked && !$strong ]
-int_parse_radix_test/badTypes: RuntimeError # wrong exception returned
-
-[ $compiler == precompiler || $runtime == vm && !$strong ]
-apply3_test: RuntimeError
-
 [ $runtime == dart_precompiled || $runtime == vm ]
 regexp/global_test: Skip # Issue 21709
 regexp/pcre_test: Pass, Slow, Timeout
diff --git a/tests/ffi/ffi.status b/tests/ffi/ffi.status
index 5b0ab46..2b170cf 100644
--- a/tests/ffi/ffi.status
+++ b/tests/ffi/ffi.status
@@ -9,7 +9,7 @@
 data_not_asan_test: SkipByDesign # This test tries to allocate too much memory on purpose.
 
 # dartbug.com/35768: Structs not supported on 32-bit.
-[ $arch == ia32 || $arch == arm ]
+[ $arch == ia32 || $arch == arm || $arch == simdbc ]
 function_structs_test: Skip
 function_callbacks_test: Skip
 structs_test: Skip
@@ -22,14 +22,20 @@
 function_test: Skip
 negative_function_test: Skip
 
-[ $arch == x64 || $arch == arm64 ]
+[ $arch == x64 || $arch == arm64 || $arch == simdbc64 ]
 enable_structs_test: SkipByDesign  # Tests that structs don't work on 32-bit systems.
 
 [ $runtime == dart_precompiled ]
 *: Skip # AOT is not yet supported: dartbug.com/35765
 
-[ $arch == simdbc64 || $arch == simarm || $arch == simarm64 ]
-*: Skip # FFI not yet supported on DBC or other simulated architectures.
+[ $arch == simarm || $arch == simarm64 ]
+*: Skip # FFI not yet supported on the arm simulator.
+
+[ $arch == simdbc ]
+*: Skip # FFI not yet supported on SimDBC32: dartbug.com/36809
+
+[ $arch == simdbc64 && $system != linux && $system != macos ]
+*: Skip # FFI not yet supported outside x64 Linux: dartbug.com/36809
 
 [ $system != android && $system != linux && $system != macos && $system != windows ]
 *: Skip # FFI not yet supported on other OSes.
diff --git a/tests/kernel/kernel.status b/tests/kernel/kernel.status
index 8c659a4..a75323a 100644
--- a/tests/kernel/kernel.status
+++ b/tests/kernel/kernel.status
@@ -23,11 +23,5 @@
 [ $compiler == dart2js && $host_checked ]
 unsorted/super_mixin_test: Crash
 
-[ $compiler == dart2js && !$strong ]
-unsorted/types_test: RuntimeError
-
-[ $compiler != dartk && $compiler != dartkb && $compiler != dartkp && !$strong ]
-unsorted/invocation_errors_test/00: MissingCompileTimeError # This test has been tuned for dart 2.
-
 [ !$preview_dart_2 && ($runtime == dart_precompiled || $runtime == vm) ]
 *: SkipByDesign # Deprecating all Dart1 modes of execution
diff --git a/tests/language_2/assertion_initializer_const_error2_test.dart b/tests/language_2/assertion_initializer_const_error2_test.dart
index dd152a3..02372d5 100644
--- a/tests/language_2/assertion_initializer_const_error2_test.dart
+++ b/tests/language_2/assertion_initializer_const_error2_test.dart
@@ -1,7 +1,7 @@
 // Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-// VMOptions=--assert_initializer
+// VMOptions=--enable-asserts
 // dart2jsOptions=--enable-asserts
 //
 // Test of asserts in initializer lists.
diff --git a/tests/language_2/assertion_test.dart b/tests/language_2/assertion_test.dart
index d14c513..2f1efee 100644
--- a/tests/language_2/assertion_test.dart
+++ b/tests/language_2/assertion_test.dart
@@ -1,7 +1,7 @@
 // Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-// VMOptions=--enable_type_checks --enable_asserts
+// VMOptions=--enable-asserts
 // dart2jsOptions=--enable-asserts
 
 // Dart test program testing assert statements.
diff --git a/tests/language_2/async_star_error_test.dart b/tests/language_2/async_star_error_test.dart
index 4bf2433..dc06e5a 100644
--- a/tests/language_2/async_star_error_test.dart
+++ b/tests/language_2/async_star_error_test.dart
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import "dart:async";
-import "package:expect/async_minitest.dart";
+import "package:async_helper/async_minitest.dart";
 
 /// Tests for exceptions raised in async*
 main() {
diff --git a/tests/language_2/async_star_test.dart b/tests/language_2/async_star_test.dart
index 4828485..72d772e 100644
--- a/tests/language_2/async_star_test.dart
+++ b/tests/language_2/async_star_test.dart
@@ -6,7 +6,7 @@
 
 import "dart:async";
 
-import "package:expect/async_minitest.dart";
+import "package:async_helper/async_minitest.dart";
 
 main() {
   group("basic", () {
diff --git a/tests/language_2/control_flow_collections/if_const_syntax_error_test.dart b/tests/language_2/control_flow_collections/if_const_syntax_error_test.dart
index 917d9f4..a876036 100644
--- a/tests/language_2/control_flow_collections/if_const_syntax_error_test.dart
+++ b/tests/language_2/control_flow_collections/if_const_syntax_error_test.dart
@@ -5,7 +5,7 @@
 // Check that 'if' in const collections is not enabled without the experimental
 // constant-update-2018 flag.
 
-// SharedOptions=--enable-experiment=control-flow-collections
+// SharedOptions=--enable-experiment=control-flow-collections,no-constant-update-2018
 
 void main() {
   // If cannot be used in a const collection.
diff --git a/tests/language_2/initializer_super_last_test.dart b/tests/language_2/initializer_super_last_test.dart
index 73f18d0d..19ad3fa 100644
--- a/tests/language_2/initializer_super_last_test.dart
+++ b/tests/language_2/initializer_super_last_test.dart
@@ -1,7 +1,7 @@
 // Copyright (c) 201, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-// VMOptions=--assert_initializer
+// VMOptions=--enable-asserts
 //
 // Dart test program testing assert statements.
 
diff --git a/tests/language_2/language_2.status b/tests/language_2/language_2.status
index 2f8711e..921c002 100644
--- a/tests/language_2/language_2.status
+++ b/tests/language_2/language_2.status
@@ -67,7 +67,7 @@
 [ $compiler != app_jitk && $compiler != dartk && $compiler != dartkb && $compiler != dartkp && $mode == debug && $runtime == vm ]
 built_in_identifier_type_annotation_test/set: Crash # Not supported by legacy VM front-end.
 
-[ $compiler != compare_analyzer_cfe && $compiler != dart2js && $compiler != spec_parser && !$fasta && $strong ]
+[ $compiler != compare_analyzer_cfe && $compiler != dart2js && $compiler != spec_parser && !$fasta ]
 compile_time_constant_static5_test/11: CompileTimeError # Issue 30546
 compile_time_constant_static5_test/16: CompileTimeError # Issue 30546
 compile_time_constant_static5_test/21: CompileTimeError # Issue 30546
@@ -93,140 +93,6 @@
 [ $compiler != dart2js && $compiler != dartdevc && !$checked ]
 function_type/*: Skip # Needs checked mode.
 
-[ $compiler != dart2js && !$fasta && !$strong ]
-implicit_creation/implicit_new_constructor_generic_test: Fail # No support for implicit creation.
-implicit_creation/implicit_new_constructor_test: Fail # No support for implicit creation.
-implicit_creation/implicit_new_prefix_constructor_generic_test: Fail # No support for implicit creation.
-implicit_creation/implicit_new_prefix_constructor_test: Fail # No support for implicit creation.
-
-[ $compiler != spec_parser && $runtime != none && !$checked && !$strong ]
-closure_type_test: RuntimeError
-map_literal1_test/01: MissingCompileTimeError
-nosuchmethod_forwarding/nosuchmethod_forwarding_test/02: RuntimeError # Requires type check.
-nosuchmethod_forwarding/nosuchmethod_forwarding_test/05: RuntimeError # Issue #31426
-nosuchmethod_forwarding/nosuchmethod_forwarding_test/06: RuntimeError # Issue #31426
-
-[ $compiler != spec_parser && !$strong ]
-class_literal_static_test: MissingCompileTimeError # Requires strong mode
-class_literal_static_test/none: Pass
-class_override_test: MissingCompileTimeError # Requires strong mode
-closure_internals_test/01: MissingCompileTimeError # Requires strong mode
-closure_internals_test/02: MissingCompileTimeError # Requires strong mode
-closure_internals_test/03: MissingCompileTimeError # Requires strong mode
-compile_time_constant_k_test/01: MissingCompileTimeError # Requires strong mode
-compile_time_constant_k_test/02: MissingCompileTimeError # Requires strong mode
-compile_time_constant_k_test/03: MissingCompileTimeError # Requires strong mode
-compile_time_constant_static2_test: Skip # Requires strong mode
-compile_time_constant_static3_test: Skip # Requires strong mode
-compile_time_constant_static4_test: Skip # Requires strong mode
-compile_time_constant_static5_test: Skip # Requires strong mode
-compile_time_constant_static_test: Skip # Requires strong mode
-crash_6725_test/01: MissingCompileTimeError # Requires strong mode
-deferred_super_dependency_test/01: MissingCompileTimeError # Requires strong mode
-double_to_string_as_exponential2_test/*: MissingCompileTimeError
-double_to_string_as_exponential2_test/none: Pass
-double_to_string_as_fixed2_test/*: MissingCompileTimeError
-double_to_string_as_fixed2_test/none: Pass
-double_to_string_as_precision2_test/*: MissingCompileTimeError
-double_to_string_as_precision2_test/none: Pass
-initializing_formal_type_annotation_test/01: MissingCompileTimeError # Requires strong mode
-initializing_formal_type_annotation_test/02: MissingCompileTimeError # Requires strong mode
-is_malformed_type_test/94: MissingCompileTimeError # Requires strong mode
-is_malformed_type_test/95: MissingCompileTimeError # Requires strong mode
-is_malformed_type_test/96: MissingCompileTimeError # Requires strong mode
-is_malformed_type_test/97: MissingCompileTimeError # Requires strong mode
-is_malformed_type_test/98: MissingCompileTimeError # Requires strong mode
-is_malformed_type_test/99: MissingCompileTimeError # Requires strong mode
-is_not_class2_test/01: MissingCompileTimeError # Requires strong mode
-is_not_class2_test/none: Skip # No interesting functionality in this configuration.
-isnot_malformed_type_test/01: MissingCompileTimeError
-issue11724_test/01: MissingCompileTimeError
-issue1363_test/01: MissingCompileTimeError # Requires strong mode
-issue15606_test/01: MissingCompileTimeError # Requires strong mode
-issue18628_1_test/01: MissingCompileTimeError # Requires strong mode
-issue18628_2_test/01: MissingCompileTimeError # Requires strong mode
-known_identifier_prefix_error_test/*: MissingCompileTimeError # Requires strong mode
-known_identifier_prefix_error_test/none: Pass
-map_literal3_test/01: MissingCompileTimeError
-map_literal3_test/02: MissingCompileTimeError
-map_literal3_test/03: MissingCompileTimeError
-map_literal3_test/04: MissingCompileTimeError
-map_literal4_test/01: MissingCompileTimeError
-map_literal4_test/02: MissingCompileTimeError
-map_literal4_test/03: MissingCompileTimeError
-map_literal4_test/04: MissingCompileTimeError
-map_literal4_test/05: MissingCompileTimeError
-map_literal4_test/06: MissingCompileTimeError
-nosuchmethod_forwarding/nosuchmethod_forwarding_test/03: MissingCompileTimeError # Issue #31426
-number_identifier_test/05: MissingCompileTimeError
-number_identifier_test/08: MissingCompileTimeError
-number_identifier_test/09: MissingCompileTimeError
-on_catch_malformed_type_test: MissingCompileTimeError
-operator5_test: MissingCompileTimeError
-operator_equals_test: MissingCompileTimeError
-optimized_constant_array_string_access_test: MissingCompileTimeError
-redirecting_factory_default_values_test/03: MissingCompileTimeError
-redirecting_factory_incompatible_signature_test/01: MissingCompileTimeError
-redirecting_factory_infinite_steps_test/01: MissingCompileTimeError
-redirecting_factory_malbounded_test/01: MissingCompileTimeError
-type_literal_prefix_call_test/00: MissingCompileTimeError
-type_parameter_test/*: MissingCompileTimeError
-type_parameter_test/none: Pass
-type_promotion_assign_test/*: MissingCompileTimeError
-type_promotion_assign_test/none: Pass
-type_promotion_closure_test/*: MissingCompileTimeError
-type_promotion_closure_test/05: Pass
-type_promotion_closure_test/08: Pass
-type_promotion_closure_test/none: Pass
-type_promotion_local_test/*: MissingCompileTimeError
-type_promotion_local_test/none: Pass
-type_promotion_logical_and_test/01: MissingCompileTimeError
-type_promotion_logical_and_test/02: MissingCompileTimeError
-type_promotion_logical_and_test/03: MissingCompileTimeError
-type_promotion_more_specific_test/02: MissingCompileTimeError
-type_promotion_more_specific_test/06: MissingCompileTimeError
-type_promotion_more_specific_test/07: MissingCompileTimeError
-type_promotion_more_specific_test/09: MissingCompileTimeError
-type_promotion_more_specific_test/10: MissingCompileTimeError
-type_promotion_more_specific_test/11: MissingCompileTimeError
-type_promotion_multiple_test/*: MissingCompileTimeError
-type_promotion_multiple_test/none: Pass
-vm/type_vm_test/01: MissingCompileTimeError
-vm/type_vm_test/02: MissingCompileTimeError
-vm/type_vm_test/03: MissingCompileTimeError
-vm/type_vm_test/04: MissingCompileTimeError
-vm/type_vm_test/05: MissingCompileTimeError
-vm/type_vm_test/06: MissingCompileTimeError
-vm/type_vm_test/08: MissingCompileTimeError
-vm/type_vm_test/09: MissingCompileTimeError
-vm/type_vm_test/10: MissingCompileTimeError
-vm/type_vm_test/11: MissingCompileTimeError
-vm/type_vm_test/12: MissingCompileTimeError
-vm/type_vm_test/13: MissingCompileTimeError
-vm/type_vm_test/14: MissingCompileTimeError
-vm/type_vm_test/15: MissingCompileTimeError
-vm/type_vm_test/16: MissingCompileTimeError
-vm/type_vm_test/22: MissingCompileTimeError
-vm/type_vm_test/24: MissingCompileTimeError
-vm/type_vm_test/25: MissingCompileTimeError
-vm/type_vm_test/26: MissingCompileTimeError
-vm/type_vm_test/27: MissingCompileTimeError
-void/return_future_future_or_void_sync_error1_test: MissingCompileTimeError # https://github.com/dart-lang/sdk/issues/33218
-void/void_block_return_test/00: MissingCompileTimeError # Requires strong mode
-void/void_type_callbacks_test: Skip # Requires strong mode
-void/void_type_function_types_test: Skip # Requires strong mode
-void/void_type_override_test: Skip # Requires strong mode
-void/void_type_usage_test: Skip # Requires strong mode
-wrong_number_type_arguments_test/*: MissingCompileTimeError # Requires strong mode
-wrong_number_type_arguments_test/none: Pass
-
-[ $runtime != none && !$strong ]
-map_literal11_test/none: MissingRuntimeError
-map_literal7_test: RuntimeError # Requires strong mode
-
-[ $checked && !$strong ]
-type_parameter_test/05: Pass
-
 [ !$preview_dart_2 && ($runtime == dart_precompiled || $runtime == vm) ]
 *: SkipByDesign # Deprecating all Dart1 modes of execution
 
diff --git a/tests/language_2/language_2_dart2js.status b/tests/language_2/language_2_dart2js.status
index 7f34dad..6c03694 100644
--- a/tests/language_2/language_2_dart2js.status
+++ b/tests/language_2/language_2_dart2js.status
@@ -5,32 +5,91 @@
 
 [ $compiler == dart2js ]
 arithmetic_int64_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
+async_await_test/02: RuntimeError
+async_await_test/03: RuntimeError
+async_await_test/none: RuntimeError
 async_star/async_star_await_for_test: RuntimeError
 async_star/async_star_cancel_test: RuntimeError
 async_star_cancel_while_paused_test: RuntimeError # Issue 22853
+async_star_test/02: RuntimeError
 bit_operations_test: RuntimeError, OK # non JS number semantics
+bit_operations_test: RuntimeError
 bit_operations_test/03: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
 bit_operations_test/04: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
 bit_operations_test/none: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
+branch_canonicalization_test: RuntimeError
 call_method_as_cast_test/06: RuntimeError
 call_method_implicit_tear_off_implements_function_test/05: RuntimeError
 call_method_implicit_tear_off_implements_function_test/06: RuntimeError
 call_method_is_check_test/06: RuntimeError
 call_method_must_not_be_field_test/03: RuntimeError # Issue 32155
 call_method_must_not_be_getter_test/03: RuntimeError # Issue 32155
+canonical_const2_test: RuntimeError, OK # non JS number semantics
+closure_type_arguments_test: Crash # Issue 34272
+compile_time_constant_static5_test/11: CompileTimeError
+compile_time_constant_static5_test/16: CompileTimeError
+compile_time_constant_static5_test/21: CompileTimeError
+compile_time_constant_static5_test/23: CompileTimeError
+conditional_rewrite_test: RuntimeError
 config_import_corelib_test: CompileTimeError # we need a special platform.dill file for categories=all. Once we fix that, all dart:* are supported when using '--categories=all' so this will become a RuntimeError, OK.
 config_import_test: RuntimeError # Test flag is not passed to the compiler.
+const_constructor3_test/04: MissingCompileTimeError # OK - Subtype check uses JS number semantics.
 const_constructor_nonconst_param_test/01: MissingCompileTimeError
 const_dynamic_type_literal_test/03: Pass # but it shouldn't until we fix issue 17207
+const_evaluation_test/01: RuntimeError
+const_list_test: RuntimeError
+const_map2_test/00: MissingCompileTimeError
+const_map3_test/00: MissingCompileTimeError
+const_map4_test: RuntimeError
+const_switch_test/02: RuntimeError, OK # constant identity based on JS constants
+const_switch_test/04: RuntimeError, OK # constant identity based on JS constants
+constructor12_test: RuntimeError
+constructor_named_arguments_test/none: RuntimeError
+covariant_subtyping_test: Crash # Unsupported operation: Unsupported type parameter type node E.
+ct_const_test: RuntimeError
+deferred_load_library_wrong_args_test/01: CompileTimeError
+deferred_not_loaded_check_test: RuntimeError # Test out of date. Issue 31933
+deferred_redirecting_factory_test: RuntimeError
 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.
+double_int_to_string_test: RuntimeError, OK # non JS number semantics
+dynamic_prefix_core_test/none: CompileTimeError
+enum_mirror_test: RuntimeError
+example_constructor_test: RuntimeError
+expect_test: RuntimeError, OK # Issue 13080
 external_test/10: CompileTimeError # External non-js-interop function are treated as compile-time errors.
+external_test/10: MissingRuntimeError
 external_test/13: CompileTimeError # External non-js-interop function are treated as compile-time errors.
+external_test/13: MissingRuntimeError
 external_test/20: CompileTimeError # External non-js-interop function are treated as compile-time errors.
+external_test/20: MissingRuntimeError
+external_test/21: CompileTimeError
+external_test/24: CompileTimeError
+flatten_test/05: MissingRuntimeError
+flatten_test/08: MissingRuntimeError
+flatten_test/09: MissingRuntimeError
+flatten_test/12: MissingRuntimeError
+full_stacktrace1_test: RuntimeError # Issue 12698
+full_stacktrace2_test: RuntimeError # Issue 12698
+full_stacktrace3_test: RuntimeError # Issue 12698
 function_propagation_test: RuntimeError
+function_subtype_inline2_test: RuntimeError
+generic_function_bounds_test: RuntimeError
+generic_function_dcall_test/01: RuntimeError
+generic_instanceof2_test: RuntimeError
+generic_is_check_test: RuntimeError
+generic_methods_bounds_test/02: MissingRuntimeError
+generic_no_such_method_dispatcher_simple_test: CompileTimeError
+generic_no_such_method_dispatcher_test: CompileTimeError
+generic_tearoff_test: CompileTimeError
 guess_cid_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
+identical_closure2_test: RuntimeError # non JS number semantics
 identical_closure2_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
+if_null_precedence_test/none: RuntimeError
+infinity_test: RuntimeError # non JS number semantics - Issue 4984
+instance_creation_in_function_annotation_test: RuntimeError
+instantiate_tearoff_of_call_test: CompileTimeError
 instantiate_tearoff_of_call_test: RuntimeError
 int2_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
 int64_literal_test/01: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
@@ -45,23 +104,105 @@
 int64_literal_test/17: RuntimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
 int64_literal_test/19: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
 int64_literal_test/none: RuntimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
+integer_division_by_zero_test: RuntimeError # Issue 8301
+internal_library_test/02: Crash
+invocation_mirror_invoke_on2_test: RuntimeError
+invocation_mirror_invoke_on_test: RuntimeError
+issue21079_test: RuntimeError
 issue23244_test: RuntimeError # Isolates - enum canonicalization - Issue 23244
+issue31596_super_test/01: CompileTimeError
+issue31596_super_test/03: CompileTimeError
+left_shift_test: RuntimeError # non JS number semantics
 library_env_test/has_io_support: RuntimeError, OK # dart2js doesn't support io when compiling on --categories=Client
 library_env_test/has_mirror_support: Fail # mirrors not supported on web
+library_env_test/has_mirror_support: RuntimeError
 library_env_test/has_no_html_support: RuntimeError, OK
 library_env_test/has_no_mirror_support: Pass # fails for the wrong reason.
 list_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
+local_function2_test/none: RuntimeError
+local_function3_test/none: RuntimeError
+local_function_test/none: RuntimeError
+minify_closure_variable_collision_test: CompileTimeError
 mint_arithmetic_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
+mint_arithmetic_test: RuntimeError # non JS number semantics
 mint_compares_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
 mint_identical_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
+mixin_illegal_super_use_test/01: MissingCompileTimeError
+mixin_illegal_super_use_test/04: MissingCompileTimeError
+mixin_illegal_super_use_test/07: MissingCompileTimeError
+mixin_illegal_super_use_test/10: MissingCompileTimeError
+mixin_illegal_super_use_test/11: MissingCompileTimeError
+mixin_illegal_superclass_test/01: MissingCompileTimeError
+mixin_illegal_superclass_test/02: MissingCompileTimeError
+mixin_illegal_superclass_test/03: MissingCompileTimeError
+mixin_illegal_superclass_test/04: MissingCompileTimeError
+mixin_illegal_superclass_test/05: MissingCompileTimeError
+mixin_illegal_superclass_test/06: MissingCompileTimeError
+mixin_illegal_superclass_test/07: MissingCompileTimeError
+mixin_illegal_superclass_test/08: MissingCompileTimeError
+mixin_illegal_superclass_test/09: MissingCompileTimeError
+mixin_illegal_superclass_test/10: MissingCompileTimeError
+mixin_illegal_superclass_test/11: MissingCompileTimeError
+mixin_illegal_superclass_test/12: MissingCompileTimeError
+mixin_illegal_superclass_test/13: MissingCompileTimeError
+mixin_illegal_superclass_test/14: MissingCompileTimeError
+mixin_illegal_superclass_test/15: MissingCompileTimeError
+mixin_illegal_superclass_test/16: MissingCompileTimeError
+mixin_illegal_superclass_test/17: MissingCompileTimeError
+mixin_illegal_superclass_test/18: MissingCompileTimeError
+mixin_illegal_superclass_test/19: MissingCompileTimeError
+mixin_illegal_superclass_test/20: MissingCompileTimeError
+mixin_illegal_superclass_test/21: MissingCompileTimeError
+mixin_illegal_superclass_test/22: MissingCompileTimeError
+mixin_illegal_superclass_test/23: MissingCompileTimeError
+mixin_illegal_superclass_test/24: MissingCompileTimeError
+mixin_illegal_superclass_test/25: MissingCompileTimeError
+mixin_illegal_superclass_test/26: MissingCompileTimeError
+mixin_illegal_superclass_test/27: MissingCompileTimeError
+mixin_illegal_superclass_test/28: MissingCompileTimeError
+mixin_illegal_superclass_test/29: MissingCompileTimeError
+mixin_illegal_superclass_test/30: MissingCompileTimeError
+mixin_method_override_test/G5: Skip # Issue 34354
+mock_writable_final_field_test: RuntimeError # Issue 30847
+mock_writable_final_private_field_test: RuntimeError # Issue 17526, 30847
+modulo_test: RuntimeError # non JS number semantics
+named_parameters_default_eq_test/none: RuntimeError
+nan_identical_test: RuntimeError # Issue 11551
+nested_generic_closure_test: RuntimeError
+no_main_test/01: CompileTimeError
+no_such_method_mock_test: RuntimeError
+null_no_such_method_test: CompileTimeError
+number_identity2_test: RuntimeError
 number_identity_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
+numbers_test: RuntimeError, OK # non JS number semantics
+parser_quirks_test: CompileTimeError
 partial_instantiation_eager_bounds_check_test: RuntimeError # Issue #34295
 partial_tearoff_instantiation_test/05: Pass # for the wrong reason.
 partial_tearoff_instantiation_test/06: Pass # for the wrong reason.
 partial_tearoff_instantiation_test/07: Pass # for the wrong reason.
 partial_tearoff_instantiation_test/08: Pass # for the wrong reason.
 private_method_tearoff_test: RuntimeError
+redirecting_factory_reflection_test: RuntimeError
+regress_23408_test: CompileTimeError
+regress_24283_test: RuntimeError, OK # non JS number semantics
+regress_28255_test: RuntimeError
+regress_29025_test: CompileTimeError
+regress_29405_test: CompileTimeError
+regress_30339_test: CompileTimeError
+setter_no_getter_test/01: CompileTimeError
+stacktrace_demangle_ctors_test: RuntimeError # Issue 12698
+stacktrace_rethrow_error_test/none: RuntimeError # Issue 12698
+stacktrace_rethrow_error_test/withtraceparameter: RuntimeError # Issue 12698
+stacktrace_rethrow_nonerror_test: RuntimeError # Issue 12698
+super_bound_closure_test/none: CompileTimeError
+super_call4_test/01: MissingCompileTimeError
+super_test: RuntimeError
+tearoff_dynamic_test: RuntimeError
+truncdiv_test: RuntimeError # non JS number semantics - Issue 15246
 type_constants_test/none: RuntimeError # Issue 35052
+type_error_test: RuntimeError
+type_literal_test: RuntimeError
+type_promotion_more_specific_test/04: CompileTimeError
 vm/*: SkipByDesign # Tests for the VM.
 
 [ $compiler != dart2js ]
@@ -72,13 +213,11 @@
 
 [ $compiler == dart2js && $runtime == chrome ]
 field_override_optimization_test: RuntimeError
+stacktrace_test: RuntimeError
 
 [ $compiler == dart2js && $runtime == chrome && $system == macos ]
 await_future_test: Pass, Timeout # Issue 26735
 
-[ $compiler == dart2js && $runtime == chrome && $strong ]
-stacktrace_test: RuntimeError
-
 [ $compiler == dart2js && $runtime == chromeOnAndroid ]
 override_field_test/02: Pass, Slow # TODO(kasperl): Please triage.
 
@@ -86,13 +225,11 @@
 conditional_import_string_test: SkipByDesign # No XHR in d8
 conditional_import_test: SkipByDesign # No XHR in d8
 implicit_creation/implicit_new_constructor_generic_test: Pass
+stacktrace_test: RuntimeError
 
 [ $compiler == dart2js && $runtime == d8 && !$checked ]
 field_override_optimization_test: RuntimeError
 
-[ $compiler == dart2js && $runtime == d8 && $strong ]
-stacktrace_test: RuntimeError
-
 [ $compiler == dart2js && $runtime == ff ]
 field_override_optimization_test: RuntimeError
 round_test: Pass, Fail, OK # Fixed in ff 35. Common JavaScript engine Math.round bug.
@@ -113,24 +250,15 @@
 syncstar_dcall_type_test: RuntimeError # dart2js misplaces check in Iterator, not Iterable.
 
 [ $compiler == dart2js && $runtime == safari ]
+async_throw_in_catch_test/none: Pass, RuntimeError
 field_override_optimization_test: RuntimeError
 round_test: Fail, OK # Common JavaScript engine Math.round bug.
-
-[ $compiler == dart2js && $runtime == safari && $strong ]
-async_throw_in_catch_test/none: Pass, RuntimeError
 stacktrace_test: RuntimeError
 
 [ $compiler == dart2js && $system == windows ]
 string_literals_test: Pass, RuntimeError # Failures on dart2js-win7-chrome-4-4-be and dart2js-win7-ie11ff-4-4-be
 
 [ $compiler == dart2js && $checked ]
-covariant_subtyping_test: CompileTimeError
-
-[ $compiler == dart2js && $checked && $minified && $strong ]
-inline_super_field_test: Crash
-typedef_is_test: Crash
-
-[ $compiler == dart2js && $checked && $strong ]
 assign_instance_method_test: RuntimeError
 async_await_foreign_test: RuntimeError
 async_star_cancel_while_paused_test: RuntimeError
@@ -222,6 +350,7 @@
 constructor_named_arguments_test/01: MissingCompileTimeError
 constructor_named_arguments_test/none: RuntimeError
 covariant_override/runtime_check_test: RuntimeError
+covariant_subtyping_test: CompileTimeError
 covariant_subtyping_test: RuntimeError
 deferred_constraints_type_annotation_test/as_operation: MissingCompileTimeError
 deferred_constraints_type_annotation_test/catch_check: MissingCompileTimeError
@@ -374,12 +503,16 @@
 type_parameter_test/09: Crash # Internal Error: Unexpected type variable in static context.
 type_variable_scope_test/03: Crash # Internal Error: Unexpected type variable in static context.
 
+[ $compiler == dart2js && $checked && $minified ]
+inline_super_field_test: Crash
+typedef_is_test: Crash
+
 [ $compiler == dart2js && !$checked ]
 bool_check_test: RuntimeError
 bool_condition_check_test: RuntimeError
 issue31596_super_test/05: RuntimeError
 
-[ $compiler == dart2js && $host_checked && $strong ]
+[ $compiler == dart2js && $host_checked ]
 async_return_types_test/nestedFuture: Crash # 'file:*/pkg/compiler/lib/src/js_emitter/runtime_type_generator.dart': Failed assertion: line 208 pos 18: '!(_useKernel && _strongMode && !_disableRtiOptimization) ||
 async_star_cancel_while_paused_test: Crash # 'file:*/pkg/compiler/lib/src/js_emitter/runtime_type_generator.dart': Failed assertion: line 208 pos 18: '!(_useKernel && _strongMode && !_disableRtiOptimization) ||
 await_not_started_immediately_test: Crash # Assertion failure: Runtime type information not available for type_variable_local(bindCallback.R) in (local(_RootZone.bindCallback#)) for j:closure_call(_RootZone_bindCallback_closure.call).
@@ -402,22 +535,6 @@
 type_promotion_logical_and_test/01: MissingCompileTimeError
 
 [ $compiler == dart2js && $minified ]
-cyclic_type2_test: RuntimeError # Issue 31054
-cyclic_type_test/0*: RuntimeError # Issue 31054
-f_bounded_quantification4_test: RuntimeError # Issue 31054
-f_bounded_quantification5_test: RuntimeError # Issue 31054
-generic_closure_test/01: RuntimeError # Uses runtimeType.toString()
-mixin_mixin2_test: RuntimeError # Issue 31054
-mixin_mixin3_test: RuntimeError # Issue 31054
-mixin_mixin4_test: RuntimeError # Issue 31054
-mixin_mixin5_test: RuntimeError # Issue 31054
-mixin_mixin6_test: RuntimeError # Issue 31054
-mixin_mixin_bound2_test: RuntimeError # Issue 31054
-mixin_mixin_bound_test: RuntimeError # Issue 31054
-mixin_mixin_type_arguments_test: RuntimeError # Issue 31054
-runtime_type_function_test: RuntimeError # Uses runtimeType.toString()
-
-[ $compiler == dart2js && $minified && $strong ]
 async_return_types_test/nestedFuture: Crash # Interpolated value #1 is not an Expression or List of Expressions: [VariableUse(f), Instance of 'LiteralNull', null]
 async_star_cancel_while_paused_test: Crash # Interpolated value #1 is not an Expression or List of Expressions: [VariableUse(f), Instance of 'LiteralNull', null]
 await_not_started_immediately_test: Crash # Assertion failure: Runtime type information not available for type_variable_local(bindCallback.R) in (local(_RootZone.bindCallback#)) for j:closure_call(_RootZone_bindCallback_closure.call).
@@ -427,6 +544,11 @@
 class_literal_static_test/07: MissingCompileTimeError
 config_import_corelib_test: CompileTimeError
 covariant_subtyping_test: RuntimeError
+cyclic_type2_test: RuntimeError # Issue 31054
+cyclic_type_test/0*: RuntimeError # Issue 31054
+f_bounded_quantification4_test: RuntimeError # Issue 31054
+f_bounded_quantification5_test: RuntimeError # Issue 31054
+generic_closure_test/01: RuntimeError # Uses runtimeType.toString()
 invocation_mirror2_test: RuntimeError # mirrors not supported
 invocation_mirror_test: RuntimeError
 issue23244_test: Crash # Interpolated value #1 is not an Expression or List of Expressions: [VariableUse(f), Instance of 'LiteralNull', null]
@@ -434,7 +556,14 @@
 many_overridden_no_such_method_test: RuntimeError
 map_literal3_test/03: MissingCompileTimeError
 mixin_generic_test: RuntimeError # Issue 12605
-mixin_mixin_type_arguments_test: RuntimeError
+mixin_mixin2_test: RuntimeError # Issue 31054
+mixin_mixin3_test: RuntimeError # Issue 31054
+mixin_mixin4_test: RuntimeError # Issue 31054
+mixin_mixin5_test: RuntimeError # Issue 31054
+mixin_mixin6_test: RuntimeError # Issue 31054
+mixin_mixin_bound2_test: RuntimeError # Issue 31054
+mixin_mixin_bound_test: RuntimeError # Issue 31054
+mixin_mixin_type_arguments_test: RuntimeError # Issue 31054
 no_such_method_native_test: RuntimeError
 no_such_method_test: RuntimeError
 overridden_no_such_method_test: RuntimeError
@@ -442,156 +571,8 @@
 regress_13462_1_test: RuntimeError
 regress_18535_test: RuntimeError
 regress_21795_test: RuntimeError # Issue 12605
+runtime_type_function_test: RuntimeError # Uses runtimeType.toString()
 stack_trace_test: RuntimeError, OK # Stack trace not preserved in minified code.
 symbol_conflict_test: RuntimeError # Issue 23857
 type_literal_prefix_call_test/00: MissingCompileTimeError
 type_promotion_logical_and_test/01: MissingCompileTimeError
-
-[ $compiler == dart2js && $strong ]
-async_await_test/02: RuntimeError
-async_await_test/03: RuntimeError
-async_await_test/none: RuntimeError
-async_star_cancel_while_paused_test: RuntimeError
-async_star_test/02: RuntimeError
-bit_operations_test: RuntimeError
-branch_canonicalization_test: RuntimeError
-canonical_const2_test: RuntimeError, OK # non JS number semantics
-closure_type_arguments_test: Crash # Issue 34272
-compile_time_constant_static5_test/11: CompileTimeError
-compile_time_constant_static5_test/16: CompileTimeError
-compile_time_constant_static5_test/21: CompileTimeError
-compile_time_constant_static5_test/23: CompileTimeError
-conditional_rewrite_test: RuntimeError
-config_import_test: RuntimeError
-const_constructor3_test/04: MissingCompileTimeError # OK - Subtype check uses JS number semantics.
-const_evaluation_test/01: RuntimeError
-const_list_test: RuntimeError
-const_map2_test/00: MissingCompileTimeError
-const_map3_test/00: MissingCompileTimeError
-const_map4_test: RuntimeError
-const_switch_test/02: RuntimeError, OK # constant identity based on JS constants
-const_switch_test/04: RuntimeError, OK # constant identity based on JS constants
-constructor12_test: RuntimeError
-constructor_named_arguments_test/none: RuntimeError
-covariant_subtyping_test: Crash # Unsupported operation: Unsupported type parameter type node E.
-ct_const_test: RuntimeError
-deferred_load_library_wrong_args_test/01: CompileTimeError
-deferred_not_loaded_check_test: RuntimeError # Test out of date. Issue 31933
-deferred_redirecting_factory_test: RuntimeError
-double_int_to_string_test: RuntimeError, OK # non JS number semantics
-dynamic_prefix_core_test/none: CompileTimeError
-enum_mirror_test: RuntimeError
-example_constructor_test: RuntimeError
-expect_test: RuntimeError, OK # Issue 13080
-external_test/10: MissingRuntimeError
-external_test/13: MissingRuntimeError
-external_test/20: MissingRuntimeError
-external_test/21: CompileTimeError
-external_test/24: CompileTimeError
-flatten_test/05: MissingRuntimeError
-flatten_test/08: MissingRuntimeError
-flatten_test/09: MissingRuntimeError
-flatten_test/12: MissingRuntimeError
-full_stacktrace1_test: RuntimeError # Issue 12698
-full_stacktrace2_test: RuntimeError # Issue 12698
-full_stacktrace3_test: RuntimeError # Issue 12698
-function_subtype_inline2_test: RuntimeError
-generic_function_bounds_test: RuntimeError
-generic_function_dcall_test/01: RuntimeError
-generic_instanceof2_test: RuntimeError
-generic_is_check_test: RuntimeError
-generic_methods_bounds_test/02: MissingRuntimeError
-generic_no_such_method_dispatcher_simple_test: CompileTimeError
-generic_no_such_method_dispatcher_test: CompileTimeError
-generic_tearoff_test: CompileTimeError
-identical_closure2_test: RuntimeError # non JS number semantics
-if_null_precedence_test/none: RuntimeError
-infinity_test: RuntimeError # non JS number semantics - Issue 4984
-instance_creation_in_function_annotation_test: RuntimeError
-instantiate_tearoff_of_call_test: CompileTimeError
-integer_division_by_zero_test: RuntimeError # Issue 8301
-internal_library_test/02: Crash
-invocation_mirror_invoke_on2_test: RuntimeError
-invocation_mirror_invoke_on_test: RuntimeError
-issue21079_test: RuntimeError
-issue23244_test: RuntimeError
-issue31596_super_test/01: CompileTimeError
-issue31596_super_test/03: CompileTimeError
-left_shift_test: RuntimeError # non JS number semantics
-library_env_test/has_mirror_support: RuntimeError
-local_function2_test/none: RuntimeError
-local_function3_test/none: RuntimeError
-local_function_test/none: RuntimeError
-minify_closure_variable_collision_test: CompileTimeError
-mint_arithmetic_test: RuntimeError # non JS number semantics
-mixin_illegal_super_use_test/01: MissingCompileTimeError
-mixin_illegal_super_use_test/04: MissingCompileTimeError
-mixin_illegal_super_use_test/07: MissingCompileTimeError
-mixin_illegal_super_use_test/10: MissingCompileTimeError
-mixin_illegal_super_use_test/11: MissingCompileTimeError
-mixin_illegal_superclass_test/01: MissingCompileTimeError
-mixin_illegal_superclass_test/02: MissingCompileTimeError
-mixin_illegal_superclass_test/03: MissingCompileTimeError
-mixin_illegal_superclass_test/04: MissingCompileTimeError
-mixin_illegal_superclass_test/05: MissingCompileTimeError
-mixin_illegal_superclass_test/06: MissingCompileTimeError
-mixin_illegal_superclass_test/07: MissingCompileTimeError
-mixin_illegal_superclass_test/08: MissingCompileTimeError
-mixin_illegal_superclass_test/09: MissingCompileTimeError
-mixin_illegal_superclass_test/10: MissingCompileTimeError
-mixin_illegal_superclass_test/11: MissingCompileTimeError
-mixin_illegal_superclass_test/12: MissingCompileTimeError
-mixin_illegal_superclass_test/13: MissingCompileTimeError
-mixin_illegal_superclass_test/14: MissingCompileTimeError
-mixin_illegal_superclass_test/15: MissingCompileTimeError
-mixin_illegal_superclass_test/16: MissingCompileTimeError
-mixin_illegal_superclass_test/17: MissingCompileTimeError
-mixin_illegal_superclass_test/18: MissingCompileTimeError
-mixin_illegal_superclass_test/19: MissingCompileTimeError
-mixin_illegal_superclass_test/20: MissingCompileTimeError
-mixin_illegal_superclass_test/21: MissingCompileTimeError
-mixin_illegal_superclass_test/22: MissingCompileTimeError
-mixin_illegal_superclass_test/23: MissingCompileTimeError
-mixin_illegal_superclass_test/24: MissingCompileTimeError
-mixin_illegal_superclass_test/25: MissingCompileTimeError
-mixin_illegal_superclass_test/26: MissingCompileTimeError
-mixin_illegal_superclass_test/27: MissingCompileTimeError
-mixin_illegal_superclass_test/28: MissingCompileTimeError
-mixin_illegal_superclass_test/29: MissingCompileTimeError
-mixin_illegal_superclass_test/30: MissingCompileTimeError
-mixin_method_override_test/G5: Skip # Issue 34354
-mock_writable_final_field_test: RuntimeError # Issue 30847
-mock_writable_final_private_field_test: RuntimeError # Issue 17526, 30847
-modulo_test: RuntimeError # non JS number semantics
-named_parameters_default_eq_test/none: RuntimeError
-nan_identical_test: RuntimeError # Issue 11551
-nested_generic_closure_test: RuntimeError
-no_main_test/01: CompileTimeError
-no_such_method_mock_test: RuntimeError
-null_no_such_method_test: CompileTimeError
-number_identity2_test: RuntimeError
-numbers_test: RuntimeError, OK # non JS number semantics
-parser_quirks_test: CompileTimeError
-redirecting_factory_reflection_test: RuntimeError
-regress_23408_test: CompileTimeError
-regress_24283_test: RuntimeError, OK # non JS number semantics
-regress_28255_test: RuntimeError
-regress_29025_test: CompileTimeError
-regress_29405_test: CompileTimeError
-regress_30339_test: CompileTimeError
-setter_no_getter_test/01: CompileTimeError
-stacktrace_demangle_ctors_test: RuntimeError # Issue 12698
-stacktrace_rethrow_error_test/none: RuntimeError # Issue 12698
-stacktrace_rethrow_error_test/withtraceparameter: RuntimeError # Issue 12698
-stacktrace_rethrow_nonerror_test: RuntimeError # Issue 12698
-super_bound_closure_test/none: CompileTimeError
-super_call4_test/01: MissingCompileTimeError
-super_test: RuntimeError
-tearoff_dynamic_test: RuntimeError
-truncdiv_test: RuntimeError # non JS number semantics - Issue 15246
-type_error_test: RuntimeError
-type_literal_test: RuntimeError
-type_promotion_more_specific_test/04: CompileTimeError
-
-[ $compiler == dart2js && !$strong ]
-*: SkipByDesign
diff --git a/tests/language_2/language_2_kernel.status b/tests/language_2/language_2_kernel.status
index f5b2b09..1a54ab1 100644
--- a/tests/language_2/language_2_kernel.status
+++ b/tests/language_2/language_2_kernel.status
@@ -156,10 +156,28 @@
 assertion_initializer_const_error2_test/cc10: MissingCompileTimeError
 async_await_syntax_test/e5: Crash # Assertion error: continuation.dart: Failed assertion: 'node.expression == null || node.expression is NullLiteral': is not true.
 async_await_syntax_test/e6: Crash # Assertion error: continuation.dart: Failed assertion: 'node.expression == null || node.expression is NullLiteral': is not true.
+compile_time_constant_static4_test/02: MissingCompileTimeError
+compile_time_constant_static4_test/03: MissingCompileTimeError
+compile_time_constant_static5_test/11: CompileTimeError
+compile_time_constant_static5_test/16: CompileTimeError
+compile_time_constant_static5_test/21: CompileTimeError
+compile_time_constant_static5_test/23: CompileTimeError
+conditional_import_string_test: CompileTimeError
+conditional_import_test: CompileTimeError
+config_import_corelib_test: CompileTimeError
 const_cast1_test/02: MissingCompileTimeError
+const_constructor3_test/04: MissingCompileTimeError
 const_constructor_nonconst_param_test/01: MissingCompileTimeError
+constants_test/05: MissingCompileTimeError
 constructor5_test: CompileTimeError # Verification error
 constructor6_test: CompileTimeError # Verification error
+deferred_load_library_wrong_args_test/01: CompileTimeError
+dynamic_prefix_core_test/none: CompileTimeError
+external_test/21: CompileTimeError
+external_test/24: CompileTimeError
+generic_no_such_method_dispatcher_simple_test: CompileTimeError
+generic_no_such_method_dispatcher_test: CompileTimeError
+generic_tearoff_test: CompileTimeError
 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
@@ -180,7 +198,61 @@
 implicit_creation/implicit_const_not_default_values_test/e5: MissingCompileTimeError
 implicit_creation/implicit_const_not_default_values_test/e7: MissingCompileTimeError
 implicit_creation/implicit_const_not_default_values_test/e8: MissingCompileTimeError
+instantiate_tearoff_of_call_test: CompileTimeError
+issue31596_super_test/01: CompileTimeError
+issue31596_super_test/03: CompileTimeError
+mixin_illegal_super_use_test/01: MissingCompileTimeError
+mixin_illegal_super_use_test/04: MissingCompileTimeError
+mixin_illegal_super_use_test/07: MissingCompileTimeError
+mixin_illegal_super_use_test/10: MissingCompileTimeError
+mixin_illegal_super_use_test/11: MissingCompileTimeError
+mixin_illegal_superclass_test/01: MissingCompileTimeError
+mixin_illegal_superclass_test/02: MissingCompileTimeError
+mixin_illegal_superclass_test/03: MissingCompileTimeError
+mixin_illegal_superclass_test/04: MissingCompileTimeError
+mixin_illegal_superclass_test/05: MissingCompileTimeError
+mixin_illegal_superclass_test/06: MissingCompileTimeError
+mixin_illegal_superclass_test/07: MissingCompileTimeError
+mixin_illegal_superclass_test/08: MissingCompileTimeError
+mixin_illegal_superclass_test/09: MissingCompileTimeError
+mixin_illegal_superclass_test/10: MissingCompileTimeError
+mixin_illegal_superclass_test/11: MissingCompileTimeError
+mixin_illegal_superclass_test/12: MissingCompileTimeError
+mixin_illegal_superclass_test/13: MissingCompileTimeError
+mixin_illegal_superclass_test/14: MissingCompileTimeError
+mixin_illegal_superclass_test/15: MissingCompileTimeError
+mixin_illegal_superclass_test/16: MissingCompileTimeError
+mixin_illegal_superclass_test/17: MissingCompileTimeError
+mixin_illegal_superclass_test/18: MissingCompileTimeError
+mixin_illegal_superclass_test/19: MissingCompileTimeError
+mixin_illegal_superclass_test/20: MissingCompileTimeError
+mixin_illegal_superclass_test/21: MissingCompileTimeError
+mixin_illegal_superclass_test/22: MissingCompileTimeError
+mixin_illegal_superclass_test/23: MissingCompileTimeError
+mixin_illegal_superclass_test/24: MissingCompileTimeError
+mixin_illegal_superclass_test/25: MissingCompileTimeError
+mixin_illegal_superclass_test/26: MissingCompileTimeError
+mixin_illegal_superclass_test/27: MissingCompileTimeError
+mixin_illegal_superclass_test/28: MissingCompileTimeError
+mixin_illegal_superclass_test/29: MissingCompileTimeError
+mixin_illegal_superclass_test/30: MissingCompileTimeError
 mixin_method_override_test/G4: Crash # Assertion error: mixin_full_resolution.dart': 'src.typeParameters.length == dst.typeParameters.length': is not true.
+multiline_newline_test/04: MissingCompileTimeError
+multiline_newline_test/04r: MissingCompileTimeError
+multiline_newline_test/05: MissingCompileTimeError
+multiline_newline_test/05r: MissingCompileTimeError
+multiline_newline_test/06: MissingCompileTimeError
+multiline_newline_test/06r: MissingCompileTimeError
+null_no_such_method_test: CompileTimeError
+parser_quirks_test: CompileTimeError
+regress_23408_test: CompileTimeError
+regress_29025_test: CompileTimeError
+regress_29405_test: CompileTimeError
+regress_30339_test: CompileTimeError
+setter_no_getter_test/01: CompileTimeError
+super_bound_closure_test/none: CompileTimeError
+try_catch_test/01: MissingCompileTimeError
+type_promotion_more_specific_test/04: CompileTimeError
 vm/regress_33469_test/01: MissingCompileTimeError
 vm/regress_33469_test/02: MissingCompileTimeError
 vm/regress_33469_test/03: MissingCompileTimeError
@@ -387,6 +459,7 @@
 syntax_test/60: MissingCompileTimeError # Issue 30470
 syntax_test/61: MissingCompileTimeError # Issue 30470
 type_constants_test/04: MissingCompileTimeError # Issue 32557
+type_promotion_logical_and_test/01: MissingCompileTimeError
 vm/debug_break_enabled_vm_test/01: CompileTimeError # KernelVM bug: Bad test using extended break syntax.
 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.
@@ -418,11 +491,14 @@
 [ $compiler != app_jitk && $compiler != dart2analyzer && $compiler != dart2js && $compiler != dartk && $compiler != dartkb && $compiler != dartkp && $fasta ]
 const_optional_args_test/01: MissingCompileTimeError
 
-# The precomilation configuration uses a kernel2kernel constants evaluator
+# The precompilation and bytecode configurations use a kernel2kernel constants evaluator
 # which is is more correct than fasta/vm in JIT mode (i.e. it catches more
 # compile-time errors).
 [ $compiler != dart2analyzer && $compiler != dart2js && $compiler != dartkb && $compiler != dartkp && $fasta ]
 compile_time_constant_c_test/02: MissingCompileTimeError
+compile_time_constant_k_test/01: MissingCompileTimeError
+compile_time_constant_k_test/02: MissingCompileTimeError
+compile_time_constant_k_test/03: MissingCompileTimeError
 compile_time_constant_o_test/01: MissingCompileTimeError # Issue 32983
 compile_time_constant_o_test/02: MissingCompileTimeError # Issue 32983
 const_dynamic_type_literal_test/02: MissingCompileTimeError # Issue 32983
@@ -431,37 +507,22 @@
 identical_const_test/02: MissingCompileTimeError # Issue 32983
 identical_const_test/03: MissingCompileTimeError # Issue 32983
 identical_const_test/04: MissingCompileTimeError # Issue 32983
-
-# The precomilation and bytecode configurations use a kernel2kernel constants evaluator
-# which is is more correct than fasta/vm in JIT mode (i.e. it catches more
-# compile-time errors).
-[ $compiler != dart2analyzer && $compiler != dart2js && $compiler != dartkb && $compiler != dartkp && $fasta && $strong ]
-compile_time_constant_k_test/01: MissingCompileTimeError
-compile_time_constant_k_test/02: MissingCompileTimeError
-compile_time_constant_k_test/03: MissingCompileTimeError
 map_literal3_test/01: MissingCompileTimeError
 map_literal3_test/02: MissingCompileTimeError
 
 [ $compiler != dart2analyzer && $compiler != dart2js && $fasta ]
+super_call4_test/01: MissingCompileTimeError
 switch_bad_case_test/01: MissingCompileTimeError # KernelVM bug: Constant evaluation.
 switch_bad_case_test/02: MissingCompileTimeError # KernelVM bug: Constant evaluation.
 switch_case_test/00: MissingCompileTimeError # KernelVM bug: Constant evaluation.
 switch_case_test/01: MissingCompileTimeError # KernelVM bug: Constant evaluation.
 switch_case_test/02: MissingCompileTimeError # KernelVM bug: Constant evaluation.
 
-[ $compiler != dart2analyzer && $compiler != dart2js && $fasta && $strong ]
-super_call4_test/01: MissingCompileTimeError
-
 [ $compiler != dart2analyzer && $fasta ]
 const_map2_test/00: MissingCompileTimeError # KernelVM bug: Constant evaluation.
 const_map3_test/00: MissingCompileTimeError # KernelVM bug: Constant evaluation.
-
-[ $compiler != dart2analyzer && $fasta && $strong ]
 map_literal3_test/03: MissingCompileTimeError
 
-[ $compiler != dart2analyzer && $fasta && !$strong ]
-super_call4_test/01: MissingCompileTimeError
-
 [ $compiler != dart2js && $compiler != dartdevk && $fasta ]
 const_native_factory_test: MissingCompileTimeError # Issue 29763
 
@@ -471,7 +532,7 @@
 [ $compiler == dartk && $mode == debug && ($hot_reload || $hot_reload_rollback) ]
 inference_enum_list_test: Skip # Issue 35885
 
-[ $compiler == dartk && $runtime == vm && !$checked && $strong ]
+[ $compiler == dartk && $runtime == vm && !$checked ]
 assertion_initializer_const_error2_test/cc01: MissingCompileTimeError # Not reporting failed assert() at compile time.
 assertion_initializer_const_error2_test/cc02: MissingCompileTimeError # Not reporting failed assert() at compile time.
 assertion_initializer_const_error2_test/cc03: MissingCompileTimeError # Not reporting failed assert() at compile time.
@@ -483,7 +544,7 @@
 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 == dartkb && $runtime == vm && $strong ]
+[ $compiler == dartkb && $runtime == vm ]
 async_star_test/03: Pass, RuntimeError # Please triage
 async_star_test/04: Pass, RuntimeError # Please triage
 compile_time_constant_o_test/01: Pass
@@ -499,11 +560,11 @@
 vm/symbols_test/01: MissingCompileTimeError
 vm/symbols_test/03: MissingCompileTimeError
 
-[ $compiler == dartkp && $mode == debug && $runtime == dart_precompiled && $strong ]
+[ $compiler == dartkp && $mode == debug && $runtime == dart_precompiled ]
 external_test/13: Crash
 vm/precompiled_static_initializer_test: Pass, Slow
 
-[ $compiler == dartkp && $mode == product && $runtime == dart_precompiled && $strong ]
+[ $compiler == dartkp && $mode == product && $runtime == dart_precompiled ]
 vm/type_vm_test/28: MissingRuntimeError
 vm/type_vm_test/29: MissingRuntimeError
 vm/type_vm_test/30: MissingRuntimeError
@@ -514,106 +575,8 @@
 vm/type_vm_test/35: MissingRuntimeError
 vm/type_vm_test/36: MissingRuntimeError
 
-[ $compiler == dartkp && $runtime == dart_precompiled ]
-type_alias_equality_test/03: RuntimeError # Issue 32783
-type_alias_equality_test/04: RuntimeError # Issue 32783
-vm/bool_check_stack_traces_test/01: RuntimeError # Issue 33584
-vm/bool_check_stack_traces_test/02: RuntimeError # Issue 33584
-
-[ $compiler == dartkp && $runtime == dart_precompiled && $checked && $strong ]
-assert_initializer_test/31: MissingCompileTimeError # KernelVM bug: Constant evaluation.
-assert_initializer_test/32: MissingCompileTimeError # KernelVM bug: Constant evaluation.
-assert_initializer_test/33: MissingCompileTimeError # KernelVM bug: Constant evaluation.
-assert_initializer_test/34: MissingCompileTimeError # KernelVM bug: Constant evaluation.
-assert_initializer_test/35: MissingCompileTimeError # KernelVM bug: Constant evaluation.
-assert_initializer_test/36: MissingCompileTimeError # KernelVM bug: Constant evaluation.
-assert_initializer_test/37: MissingCompileTimeError # KernelVM bug: Constant evaluation.
-assert_initializer_test/38: MissingCompileTimeError # KernelVM bug: Constant evaluation.
-assert_initializer_test/41: MissingCompileTimeError # KernelVM bug: Constant evaluation.
-assert_initializer_test/42: MissingCompileTimeError # KernelVM bug: Constant evaluation.
-assert_initializer_test/43: MissingCompileTimeError # KernelVM bug: Constant evaluation.
-assert_initializer_test/44: MissingCompileTimeError # KernelVM bug: Constant evaluation.
-assert_initializer_test/45: MissingCompileTimeError # KernelVM bug: Constant evaluation.
-assert_initializer_test/46: MissingCompileTimeError # KernelVM bug: Constant evaluation.
-assert_initializer_test/47: MissingCompileTimeError # KernelVM bug: Constant evaluation.
-assert_initializer_test/48: MissingCompileTimeError # KernelVM bug: Constant evaluation.
-assert_initializer_test/none: RuntimeError # KernelVM bug: Constant evaluation.
-assertion_initializer_const_error2_test/cc01: Crash
-assertion_initializer_const_error2_test/cc02: Crash
-assertion_initializer_const_error2_test/cc03: Crash
-assertion_initializer_const_error2_test/cc04: Crash
-assertion_initializer_const_error2_test/cc05: Crash
-assertion_initializer_const_error2_test/cc06: Crash
-assertion_initializer_const_error2_test/cc07: Crash
-assertion_initializer_const_error2_test/cc08: Crash
-assertion_initializer_const_error2_test/cc09: Crash
-assertion_initializer_const_error2_test/cc10: Crash
-assertion_initializer_const_error2_test/cc11: Crash
-async_await_test: RuntimeError
-async_return_types_test/nestedFuture: Fail
-async_star/async_star_cancel_test: DartkCrash
-async_star/async_star_invalid_test/01: DartkCrash
-async_star/async_star_invalid_test/02: DartkCrash
-async_star/async_star_invalid_test/03: DartkCrash
-async_star/async_star_invalid_test/04: DartkCrash
-async_star/async_star_invalid_test/none: DartkCrash
-async_star/async_star_test: DartkCrash
-compile_time_constant_checked_test/02: MissingCompileTimeError
-covariance_type_parameter_test/01: RuntimeError
-covariance_type_parameter_test/02: RuntimeError
-covariance_type_parameter_test/03: RuntimeError
-covariance_type_parameter_test/none: RuntimeError
-default_factory2_test/01: Fail
-function_subtype_checked0_test: Pass
-function_subtype_closure0_test: Pass
-function_subtype_closure1_test: Pass
-function_subtype_factory1_test: Pass
-function_subtype_inline1_test: Pass
-function_subtype_inline2_test: Pass
-generic_functions_test: Pass # Issue 25869
-generic_local_functions_test: Pass # Issue 25869
-generic_methods_function_type_test: Pass # Issue 25869
-generic_methods_generic_function_parameter_test: Pass # Issue 25869
-generic_methods_new_test: Pass # Issue 25869
-generic_methods_test: Pass # Issue 25869
-known_identifier_usage_error_test/none: RuntimeError # Issue 28814
-malbounded_type_test_test/03: Fail
-malbounded_type_test_test/04: Fail
-recursive_inheritance_test: RuntimeError
-redirecting_factory_infinite_steps_test/01: Fail
-redirecting_factory_malbounded_test/01: Fail
-regress_22728_test: Fail # Dartk Issue 28498
-regress_22728_test: RuntimeError
-
-[ $compiler == dartkp && $runtime == dart_precompiled && !$checked && $strong ]
-assertion_initializer_const_error_test/01: MissingCompileTimeError
-assertion_initializer_const_function_error_test/01: MissingCompileTimeError
-conditional_rewrite_test: RuntimeError # Issue 31402 (Not)
-implicit_downcast_during_combiner_test: RuntimeError
-implicit_downcast_during_compound_assignment_test: RuntimeError
-implicit_downcast_during_conditional_expression_test: RuntimeError
-implicit_downcast_during_do_test: RuntimeError
-implicit_downcast_during_for_condition_test: RuntimeError
-implicit_downcast_during_for_initializer_expression_test: RuntimeError
-implicit_downcast_during_for_initializer_var_test: RuntimeError
-implicit_downcast_during_if_null_assignment_test: RuntimeError
-implicit_downcast_during_if_statement_test: RuntimeError
-implicit_downcast_during_list_literal_test: RuntimeError
-implicit_downcast_during_logical_expression_test: RuntimeError
-implicit_downcast_during_map_literal_test: RuntimeError
-implicit_downcast_during_not_test: RuntimeError
-implicit_downcast_during_return_async_test: RuntimeError
-implicit_downcast_during_return_test: RuntimeError
-implicit_downcast_during_variable_declaration_test: RuntimeError
-implicit_downcast_during_while_statement_test: RuntimeError
-implicit_downcast_during_yield_star_test: RuntimeError
-implicit_downcast_during_yield_test: RuntimeError
-regress_30339_test: RuntimeError
-type_error_test: RuntimeError # Issue 31402 (Variable declaration)
-vm/causal_async_exception_stack_test: RuntimeError
-
 # ==== dartkp + dart_precompiled status lines ====
-[ $compiler == dartkp && $runtime == dart_precompiled && $strong ]
+[ $compiler == dartkp && $runtime == dart_precompiled ]
 assert_with_type_test_or_cast_test: Pass, Crash
 assertion_initializer_const_error_test/01: Pass
 async_star_cancel_while_paused_test: RuntimeError
@@ -758,8 +721,12 @@
 super_bound_closure_test/none: CompileTimeError # Issue 31533
 super_test: Fail, OK
 syntax_test/00: MissingCompileTimeError
+type_alias_equality_test/03: RuntimeError # Issue 32783
+type_alias_equality_test/04: RuntimeError # Issue 32783
 type_promotion_logical_and_test/01: MissingCompileTimeError
 type_promotion_more_specific_test/04: CompileTimeError # Issue 31533
+vm/bool_check_stack_traces_test/01: RuntimeError # Issue 33584
+vm/bool_check_stack_traces_test/02: RuntimeError # Issue 33584
 vm/causal_async_exception_stack2_test: SkipByDesign
 vm/causal_async_exception_stack_test: SkipByDesign
 vm/closure_memory_retention_test: Skip # KernelVM bug: Hits OOM
@@ -792,323 +759,102 @@
 vm/type_vm_test/31: MissingRuntimeError
 vm/type_vm_test/32: MissingRuntimeError
 
+[ $compiler == dartkp && $runtime == dart_precompiled && $checked ]
+assert_initializer_test/31: MissingCompileTimeError # KernelVM bug: Constant evaluation.
+assert_initializer_test/32: MissingCompileTimeError # KernelVM bug: Constant evaluation.
+assert_initializer_test/33: MissingCompileTimeError # KernelVM bug: Constant evaluation.
+assert_initializer_test/34: MissingCompileTimeError # KernelVM bug: Constant evaluation.
+assert_initializer_test/35: MissingCompileTimeError # KernelVM bug: Constant evaluation.
+assert_initializer_test/36: MissingCompileTimeError # KernelVM bug: Constant evaluation.
+assert_initializer_test/37: MissingCompileTimeError # KernelVM bug: Constant evaluation.
+assert_initializer_test/38: MissingCompileTimeError # KernelVM bug: Constant evaluation.
+assert_initializer_test/41: MissingCompileTimeError # KernelVM bug: Constant evaluation.
+assert_initializer_test/42: MissingCompileTimeError # KernelVM bug: Constant evaluation.
+assert_initializer_test/43: MissingCompileTimeError # KernelVM bug: Constant evaluation.
+assert_initializer_test/44: MissingCompileTimeError # KernelVM bug: Constant evaluation.
+assert_initializer_test/45: MissingCompileTimeError # KernelVM bug: Constant evaluation.
+assert_initializer_test/46: MissingCompileTimeError # KernelVM bug: Constant evaluation.
+assert_initializer_test/47: MissingCompileTimeError # KernelVM bug: Constant evaluation.
+assert_initializer_test/48: MissingCompileTimeError # KernelVM bug: Constant evaluation.
+assert_initializer_test/none: RuntimeError # KernelVM bug: Constant evaluation.
+assertion_initializer_const_error2_test/cc01: Crash
+assertion_initializer_const_error2_test/cc02: Crash
+assertion_initializer_const_error2_test/cc03: Crash
+assertion_initializer_const_error2_test/cc04: Crash
+assertion_initializer_const_error2_test/cc05: Crash
+assertion_initializer_const_error2_test/cc06: Crash
+assertion_initializer_const_error2_test/cc07: Crash
+assertion_initializer_const_error2_test/cc08: Crash
+assertion_initializer_const_error2_test/cc09: Crash
+assertion_initializer_const_error2_test/cc10: Crash
+assertion_initializer_const_error2_test/cc11: Crash
+async_await_test: RuntimeError
+async_return_types_test/nestedFuture: Fail
+async_star/async_star_cancel_test: DartkCrash
+async_star/async_star_invalid_test/01: DartkCrash
+async_star/async_star_invalid_test/02: DartkCrash
+async_star/async_star_invalid_test/03: DartkCrash
+async_star/async_star_invalid_test/04: DartkCrash
+async_star/async_star_invalid_test/none: DartkCrash
+async_star/async_star_test: DartkCrash
+compile_time_constant_checked_test/02: MissingCompileTimeError
+covariance_type_parameter_test/01: RuntimeError
+covariance_type_parameter_test/02: RuntimeError
+covariance_type_parameter_test/03: RuntimeError
+covariance_type_parameter_test/none: RuntimeError
+default_factory2_test/01: Fail
+function_subtype_checked0_test: Pass
+function_subtype_closure0_test: Pass
+function_subtype_closure1_test: Pass
+function_subtype_factory1_test: Pass
+function_subtype_inline1_test: Pass
+function_subtype_inline2_test: Pass
+generic_functions_test: Pass # Issue 25869
+generic_local_functions_test: Pass # Issue 25869
+generic_methods_function_type_test: Pass # Issue 25869
+generic_methods_generic_function_parameter_test: Pass # Issue 25869
+generic_methods_new_test: Pass # Issue 25869
+generic_methods_test: Pass # Issue 25869
+known_identifier_usage_error_test/none: RuntimeError # Issue 28814
+malbounded_type_test_test/03: Fail
+malbounded_type_test_test/04: Fail
+recursive_inheritance_test: RuntimeError
+redirecting_factory_infinite_steps_test/01: Fail
+redirecting_factory_malbounded_test/01: Fail
+regress_22728_test: Fail # Dartk Issue 28498
+regress_22728_test: RuntimeError
+
+[ $compiler == dartkp && $runtime == dart_precompiled && !$checked ]
+assertion_initializer_const_error_test/01: MissingCompileTimeError
+assertion_initializer_const_function_error_test/01: MissingCompileTimeError
+conditional_rewrite_test: RuntimeError # Issue 31402 (Not)
+implicit_downcast_during_combiner_test: RuntimeError
+implicit_downcast_during_compound_assignment_test: RuntimeError
+implicit_downcast_during_conditional_expression_test: RuntimeError
+implicit_downcast_during_do_test: RuntimeError
+implicit_downcast_during_for_condition_test: RuntimeError
+implicit_downcast_during_for_initializer_expression_test: RuntimeError
+implicit_downcast_during_for_initializer_var_test: RuntimeError
+implicit_downcast_during_if_null_assignment_test: RuntimeError
+implicit_downcast_during_if_statement_test: RuntimeError
+implicit_downcast_during_list_literal_test: RuntimeError
+implicit_downcast_during_logical_expression_test: RuntimeError
+implicit_downcast_during_map_literal_test: RuntimeError
+implicit_downcast_during_not_test: RuntimeError
+implicit_downcast_during_return_async_test: RuntimeError
+implicit_downcast_during_return_test: RuntimeError
+implicit_downcast_during_variable_declaration_test: RuntimeError
+implicit_downcast_during_while_statement_test: RuntimeError
+implicit_downcast_during_yield_star_test: RuntimeError
+implicit_downcast_during_yield_test: RuntimeError
+regress_30339_test: RuntimeError
+type_error_test: RuntimeError # Issue 31402 (Variable declaration)
+vm/causal_async_exception_stack_test: RuntimeError
+
 [ $compiler == dartkp && $system == windows ]
 disassemble_test: Pass, Slow
 
-[ $compiler == fasta && $strong ]
-compile_time_constant_static4_test/02: MissingCompileTimeError
-compile_time_constant_static4_test/03: MissingCompileTimeError
-compile_time_constant_static5_test/11: CompileTimeError
-compile_time_constant_static5_test/16: CompileTimeError
-compile_time_constant_static5_test/21: CompileTimeError
-compile_time_constant_static5_test/23: CompileTimeError
-conditional_import_string_test: CompileTimeError
-conditional_import_test: CompileTimeError
-config_import_corelib_test: CompileTimeError
-const_constructor3_test/04: MissingCompileTimeError
-constants_test/05: MissingCompileTimeError
-deferred_load_library_wrong_args_test/01: CompileTimeError
-dynamic_prefix_core_test/none: CompileTimeError
-external_test/21: CompileTimeError
-external_test/24: CompileTimeError
-generic_no_such_method_dispatcher_simple_test: CompileTimeError
-generic_no_such_method_dispatcher_test: CompileTimeError
-generic_tearoff_test: CompileTimeError
-instantiate_tearoff_of_call_test: CompileTimeError
-issue31596_super_test/01: CompileTimeError
-issue31596_super_test/03: CompileTimeError
-mixin_illegal_super_use_test/01: MissingCompileTimeError
-mixin_illegal_super_use_test/04: MissingCompileTimeError
-mixin_illegal_super_use_test/07: MissingCompileTimeError
-mixin_illegal_super_use_test/10: MissingCompileTimeError
-mixin_illegal_super_use_test/11: MissingCompileTimeError
-mixin_illegal_superclass_test/01: MissingCompileTimeError
-mixin_illegal_superclass_test/02: MissingCompileTimeError
-mixin_illegal_superclass_test/03: MissingCompileTimeError
-mixin_illegal_superclass_test/04: MissingCompileTimeError
-mixin_illegal_superclass_test/05: MissingCompileTimeError
-mixin_illegal_superclass_test/06: MissingCompileTimeError
-mixin_illegal_superclass_test/07: MissingCompileTimeError
-mixin_illegal_superclass_test/08: MissingCompileTimeError
-mixin_illegal_superclass_test/09: MissingCompileTimeError
-mixin_illegal_superclass_test/10: MissingCompileTimeError
-mixin_illegal_superclass_test/11: MissingCompileTimeError
-mixin_illegal_superclass_test/12: MissingCompileTimeError
-mixin_illegal_superclass_test/13: MissingCompileTimeError
-mixin_illegal_superclass_test/14: MissingCompileTimeError
-mixin_illegal_superclass_test/15: MissingCompileTimeError
-mixin_illegal_superclass_test/16: MissingCompileTimeError
-mixin_illegal_superclass_test/17: MissingCompileTimeError
-mixin_illegal_superclass_test/18: MissingCompileTimeError
-mixin_illegal_superclass_test/19: MissingCompileTimeError
-mixin_illegal_superclass_test/20: MissingCompileTimeError
-mixin_illegal_superclass_test/21: MissingCompileTimeError
-mixin_illegal_superclass_test/22: MissingCompileTimeError
-mixin_illegal_superclass_test/23: MissingCompileTimeError
-mixin_illegal_superclass_test/24: MissingCompileTimeError
-mixin_illegal_superclass_test/25: MissingCompileTimeError
-mixin_illegal_superclass_test/26: MissingCompileTimeError
-mixin_illegal_superclass_test/27: MissingCompileTimeError
-mixin_illegal_superclass_test/28: MissingCompileTimeError
-mixin_illegal_superclass_test/29: MissingCompileTimeError
-mixin_illegal_superclass_test/30: MissingCompileTimeError
-multiline_newline_test/04: MissingCompileTimeError
-multiline_newline_test/04r: MissingCompileTimeError
-multiline_newline_test/05: MissingCompileTimeError
-multiline_newline_test/05r: MissingCompileTimeError
-multiline_newline_test/06: MissingCompileTimeError
-multiline_newline_test/06r: MissingCompileTimeError
-null_no_such_method_test: CompileTimeError
-parser_quirks_test: CompileTimeError
-regress_23408_test: CompileTimeError
-regress_29025_test: CompileTimeError
-regress_29405_test: CompileTimeError
-regress_30339_test: CompileTimeError
-setter_no_getter_test/01: CompileTimeError
-super_bound_closure_test/none: CompileTimeError
-try_catch_test/01: MissingCompileTimeError
-type_promotion_more_specific_test/04: CompileTimeError
-
-[ $compiler == fasta && !$strong ]
-abstract_factory_constructor_test/00: MissingCompileTimeError
-abstract_getter_test/01: MissingCompileTimeError
-abstract_syntax_test/00: MissingCompileTimeError
-bad_override_test/04: MissingCompileTimeError
-bad_override_test/05: MissingCompileTimeError
-bug32305_test: MissingCompileTimeError
-call_method_implicit_invoke_local_test/05: MissingCompileTimeError
-closure_invoked_through_interface_target_field_test: MissingCompileTimeError
-closure_invoked_through_interface_target_getter_test: MissingCompileTimeError
-factory2_test/03: MissingCompileTimeError
-field_override4_test/02: MissingCompileTimeError
-field_override_test/00: MissingCompileTimeError # Override checks are performed differently in strong mode.
-field_override_test/01: MissingCompileTimeError # Override checks are performed differently in strong mode.
-generic_methods_overriding_test/01: MissingCompileTimeError # Override checks are performed differently in strong mode.
-getter_override2_test/02: MissingCompileTimeError
-implicit_this_test/01: MissingCompileTimeError
-implicit_this_test/04: MissingCompileTimeError
-invalid_override_in_mixin_test/01: MissingCompileTimeError
-issue31596_override_test/07: MissingCompileTimeError # Override checks are performed differently in strong mode.
-issue31596_override_test/08: MissingCompileTimeError # Override checks are performed differently in strong mode.
-map_literal1_test/01: MissingCompileTimeError
-method_override8_test/00: MissingCompileTimeError
-method_override8_test/01: MissingCompileTimeError
-method_override8_test/03: MissingCompileTimeError
-mixin_of_mixin_test/01: MissingCompileTimeError
-mixin_of_mixin_test/02: MissingCompileTimeError
-mixin_of_mixin_test/03: MissingCompileTimeError
-mixin_of_mixin_test/04: MissingCompileTimeError
-mixin_of_mixin_test/05: MissingCompileTimeError
-mixin_of_mixin_test/06: MissingCompileTimeError
-nsm5_test: MissingCompileTimeError
-override_field_method1_negative_test: Fail
-override_field_method2_negative_test: Fail
-override_field_method4_negative_test: Fail
-override_field_method5_negative_test: Fail
-override_inheritance_field_test/43: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_field_test/44: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_field_test/45: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_field_test/47: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_field_test/48: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_field_test/49: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_field_test/50: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_field_test/53: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_field_test/54: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/012: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/016: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/020: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/024: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/026: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/027: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/030: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/031: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/044: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/048: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/052: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/056: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/058: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/059: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/062: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/063: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/068: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/072: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/076: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/080: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/084: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/088: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/089: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/093: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/097: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/101: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/105: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/109: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/113: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/114: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/118: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/122: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/126: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/130: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/134: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/138: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/139: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/143: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/147: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/151: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/155: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/159: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/163: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/164: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/166: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/167: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/170: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/171: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/173: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/174: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/176: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/177: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/180: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/181: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/184: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/185: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/188: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/189: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/191: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/192: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/194: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/195: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/198: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/199: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/212: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/216: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/220: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/224: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/226: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/227: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/230: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/231: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/238: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/239: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/240: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/241: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/242: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/243: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/247: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/251: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/255: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/259: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/263: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/267: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/268: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/272: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/274: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/275: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/276: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/280: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/283: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/284: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/285: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/286: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/290: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/294: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/298: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/302: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/306: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/310: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/311: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/315: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/317: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/318: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/319: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/323: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/326: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/327: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/331: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/335: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/336: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/338: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/339: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/342: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/343: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/345: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/346: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/348: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/349: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/352: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/353: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/356: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/357: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/360: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/361: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/362: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/363: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/364: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/366: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/367: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/370: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_method2_test/371: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_mixed_test/01: MissingCompileTimeError
-override_inheritance_mixed_test/02: MissingCompileTimeError
-override_inheritance_mixed_test/03: MissingCompileTimeError
-override_inheritance_mixed_test/04: MissingCompileTimeError
-override_inheritance_mixed_test/06: MissingCompileTimeError
-override_inheritance_mixed_test/07: MissingCompileTimeError
-override_inheritance_mixed_test/08: MissingCompileTimeError
-override_inheritance_mixed_test/09: MissingCompileTimeError
-override_inheritance_no_such_method_test/01: MissingCompileTimeError
-override_inheritance_no_such_method_test/05: MissingCompileTimeError
-override_inheritance_no_such_method_test/06: MissingCompileTimeError
-override_inheritance_no_such_method_test/07: MissingCompileTimeError
-override_inheritance_no_such_method_test/09: MissingCompileTimeError
-override_inheritance_no_such_method_test/10: MissingCompileTimeError
-override_inheritance_no_such_method_test/12: MissingCompileTimeError
-override_inheritance_setter_test/001: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_setter_test/002: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_setter_test/004: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_inheritance_setter_test/006: MissingCompileTimeError # Override checks are performed differently in strong mode.
-override_method_with_field_test/01: MissingCompileTimeError
-prefix_import_collision_test/01: MissingCompileTimeError
-prefix_shadow_test/01: MissingCompileTimeError
-prefix_shadow_test/02: MissingCompileTimeError
-prefix_transitive_import_prefix_test/01: MissingCompileTimeError
-prefix_transitive_import_prefix_test/02: MissingCompileTimeError
-prefix_transitive_import_prefix_test/03: MissingCompileTimeError
-prefix_transitive_import_test/01: MissingCompileTimeError
-prefix_transitive_import_test/02: MissingCompileTimeError
-regress_23089_test: MissingCompileTimeError
-regress_33235_05_test/02: MissingCompileTimeError
-regress_33235_05_test/03: MissingCompileTimeError
-regress_33235_06_test/02: MissingCompileTimeError
-regress_33235_06_test/03: MissingCompileTimeError
-regress_33235_07_test/01: MissingCompileTimeError
-regress_33235_07_test/02: MissingCompileTimeError
-regress_33235_07_test/03: MissingCompileTimeError
-regress_33235_08_test/02: MissingCompileTimeError
-regress_33235_08_test/03: MissingCompileTimeError
-regress_33235_09_test/02: MissingCompileTimeError
-regress_33235_09_test/03: MissingCompileTimeError
-regress_33235_10_test/01: MissingCompileTimeError
-regress_33235_10_test/02: MissingCompileTimeError
-regress_33235_10_test/03: MissingCompileTimeError
-regress_33235_12_test/01: MissingCompileTimeError
-regress_33235_12_test/02: MissingCompileTimeError
-regress_33235_12_test/03: MissingCompileTimeError
-regress_33235_13_test/01: MissingCompileTimeError
-regress_33235_13_test/02: MissingCompileTimeError
-regress_33235_13_test/03: MissingCompileTimeError
-regress_33235_14_test/02: MissingCompileTimeError
-regress_33235_14_test/03: MissingCompileTimeError
-regress_33235_15_test/02: MissingCompileTimeError
-regress_33235_15_test/03: MissingCompileTimeError
-regress_33235_16_test/01: MissingCompileTimeError
-regress_33235_16_test/02: MissingCompileTimeError
-regress_33235_16_test/03: MissingCompileTimeError
-setter4_test: MissingCompileTimeError
-setter_override2_test/02: MissingCompileTimeError
-super_no_such_method4_test/01: MissingCompileTimeError # Requires Dart 2 semantics. See http://dartbug.com/33380.
-super_no_such_method5_test/01: MissingCompileTimeError # Requires Dart 2 semantics. See http://dartbug.com/33380.
-variable_shadow_class_test/01: MissingCompileTimeError
-
-[ $mode == debug && $runtime == vm && $strong && ($compiler == app_jitk || $compiler == dartk || $compiler == dartkb) ]
+[ $mode == debug && $runtime == vm && ($compiler == app_jitk || $compiler == dartk || $compiler == dartkb) ]
 deopt_inlined_function_lazy_test: Skip
 
 [ $mode == debug && $hot_reload && ($compiler == dartk || $compiler == dartkb) ]
@@ -1127,7 +873,7 @@
 vm/causal_async_exception_stack_test: SkipByDesign
 vm/type_vm_test/29: MissingRuntimeError
 
-[ $runtime == vm && $checked && $strong && ($compiler == dartk || $compiler == dartkb) ]
+[ $runtime == vm && $checked && ($compiler == dartk || $compiler == dartkb) ]
 assert_initializer_test/31: MissingCompileTimeError # KernelVM bug: Constant evaluation.
 assert_initializer_test/32: MissingCompileTimeError # KernelVM bug: Constant evaluation.
 assert_initializer_test/33: MissingCompileTimeError # KernelVM bug: Constant evaluation.
@@ -1151,12 +897,12 @@
 malbounded_type_test_test/04: Fail
 regress_30339_test: RuntimeError
 
-[ $runtime == vm && !$checked && $strong && ($compiler == dartk || $compiler == dartkb) ]
+[ $runtime == vm && !$checked && ($compiler == dartk || $compiler == dartkb) ]
 conditional_rewrite_test: RuntimeError # Issue 31402 (Not)
 type_error_test: RuntimeError # Issue 31402 (Variable declaration)
 
 # ===== dartk + vm status lines =====
-[ $runtime == vm && $strong && ($compiler == dartk || $compiler == dartkb) ]
+[ $runtime == vm && ($compiler == dartk || $compiler == dartkb) ]
 arithmetic2_test: RuntimeError # Throws CastError instead of TypeError
 async_star_cancel_while_paused_test: RuntimeError
 async_star_pause_test: Fail, OK
@@ -1265,7 +1011,7 @@
 vm/type_cast_vm_test: RuntimeError
 web_int_literals_test/*: SkipByDesign # Test applies only to JavaScript targets
 
-[ $system == windows && $strong && ($compiler == dartk || $compiler == dartkb) ]
+[ $system == windows && ($compiler == dartk || $compiler == dartkb) ]
 ct_const2_test: Fail
 
 [ $checked && ($compiler == dartk || $compiler == dartkb) ]
@@ -1280,807 +1026,15 @@
 assertion_initializer_const_error2_test/cc09: Pass # Works in --checked mode but not in --strong mode.
 assertion_initializer_const_error2_test/cc10: Pass # Works in --checked mode but not in --strong mode.
 
-[ $fasta && $strong ]
-type_promotion_logical_and_test/01: MissingCompileTimeError
-
-[ $fasta && !$strong ]
-abstract_beats_arguments_test: MissingCompileTimeError
-abstract_exact_selector_test/01: MissingCompileTimeError
-abstract_override_adds_optional_args_supercall_test: MissingCompileTimeError
-additional_interface_adds_optional_args_supercall_test: MissingCompileTimeError
-argument_assignability_function_typed_test/01: MissingCompileTimeError
-argument_assignability_function_typed_test/02: MissingCompileTimeError
-assertion_initializer_const_function_test/01: MissingCompileTimeError
-assign_static_type_test/01: MissingCompileTimeError
-assign_static_type_test/02: MissingCompileTimeError
-assign_static_type_test/03: MissingCompileTimeError
-assign_static_type_test/04: MissingCompileTimeError
-assign_static_type_test/05: MissingCompileTimeError
-assign_static_type_test/06: MissingCompileTimeError
-assign_to_type_test/01: MissingCompileTimeError
-assign_to_type_test/02: MissingCompileTimeError
-assign_to_type_test/03: MissingCompileTimeError
-assign_to_type_test/04: MissingCompileTimeError
-assign_top_method_test: MissingCompileTimeError
-async_await_syntax_test/a10a: MissingCompileTimeError
-async_await_syntax_test/b10a: MissingCompileTimeError
-async_await_syntax_test/c10a: MissingCompileTimeError
-async_await_syntax_test/d08b: MissingCompileTimeError
-async_await_syntax_test/d10a: MissingCompileTimeError
-async_congruence_local_test/01: MissingCompileTimeError
-async_congruence_local_test/02: MissingCompileTimeError
-async_congruence_method_test/01: MissingCompileTimeError
-async_congruence_unnamed_test/01: MissingCompileTimeError
-async_congruence_unnamed_test/02: MissingCompileTimeError
-async_or_generator_return_type_stacktrace_test/01: MissingCompileTimeError
-async_return_types_test/tooManyTypeParameters: MissingCompileTimeError
-async_return_types_test/wrongReturnType: MissingCompileTimeError
-async_return_types_test/wrongTypeParameter: MissingCompileTimeError
-bad_named_parameters2_test/01: MissingCompileTimeError
-bad_named_parameters_test/01: MissingCompileTimeError
-bad_named_parameters_test/02: MissingCompileTimeError
-bad_named_parameters_test/03: MissingCompileTimeError
-bad_named_parameters_test/04: MissingCompileTimeError
-bad_named_parameters_test/05: MissingCompileTimeError
-bad_override_test/01: MissingCompileTimeError
-bad_override_test/02: MissingCompileTimeError
-bad_override_test/03: MissingCompileTimeError
-bad_override_test/06: MissingCompileTimeError
-built_in_identifier_type_annotation_test/dynamic-gen: MissingCompileTimeError
-call_constructor_on_unresolvable_class_test/01: MissingCompileTimeError
-call_constructor_on_unresolvable_class_test/02: MissingCompileTimeError
-call_constructor_on_unresolvable_class_test/03: MissingCompileTimeError
-call_method_must_not_be_field_test/01: MissingCompileTimeError
-call_method_must_not_be_field_test/02: MissingCompileTimeError
-call_method_must_not_be_getter_test/01: MissingCompileTimeError
-call_method_must_not_be_getter_test/02: MissingCompileTimeError
-call_method_override_test/01: MissingCompileTimeError
-call_method_override_test/02: MissingCompileTimeError
-call_nonexistent_constructor_test/01: MissingCompileTimeError
-call_nonexistent_constructor_test/02: MissingCompileTimeError
-call_nonexistent_static_test/01: MissingCompileTimeError
-call_nonexistent_static_test/02: MissingCompileTimeError
-call_nonexistent_static_test/03: MissingCompileTimeError
-call_nonexistent_static_test/04: MissingCompileTimeError
-call_nonexistent_static_test/05: MissingCompileTimeError
-call_nonexistent_static_test/06: MissingCompileTimeError
-call_nonexistent_static_test/07: MissingCompileTimeError
-call_nonexistent_static_test/08: MissingCompileTimeError
-call_nonexistent_static_test/09: MissingCompileTimeError
-call_nonexistent_static_test/10: MissingCompileTimeError
-call_through_getter_test/01: MissingCompileTimeError
-call_through_getter_test/02: MissingCompileTimeError
-callable_test/00: MissingCompileTimeError
-callable_test/01: MissingCompileTimeError
-cast_test/04: MissingCompileTimeError
-cast_test/05: MissingCompileTimeError
-check_member_static_test/02: MissingCompileTimeError
-check_method_override_test/01: MissingCompileTimeError
-check_method_override_test/02: MissingCompileTimeError
-checked_null_test/01: MissingCompileTimeError
-class_cycle_test/02: MissingCompileTimeError
-class_cycle_test/03: MissingCompileTimeError
-class_literal_test/02: MissingCompileTimeError
-class_literal_test/04: MissingCompileTimeError
-class_literal_test/05: MissingCompileTimeError
-class_literal_test/06: MissingCompileTimeError
-class_literal_test/08: MissingCompileTimeError
-class_literal_test/09: MissingCompileTimeError
-class_literal_test/10: MissingCompileTimeError
-class_literal_test/11: MissingCompileTimeError
-class_literal_test/12: MissingCompileTimeError
-class_literal_test/13: MissingCompileTimeError
-class_literal_test/14: MissingCompileTimeError
-class_literal_test/15: MissingCompileTimeError
-class_literal_test/16: MissingCompileTimeError
-class_literal_test/17: MissingCompileTimeError
-class_literal_test/18: MissingCompileTimeError
-class_literal_test/19: MissingCompileTimeError
-class_literal_test/20: MissingCompileTimeError
-class_literal_test/21: MissingCompileTimeError
-class_literal_test/22: MissingCompileTimeError
-class_literal_test/23: MissingCompileTimeError
-class_literal_test/24: MissingCompileTimeError
-class_literal_test/25: MissingCompileTimeError
-conditional_method_invocation_test/05: MissingCompileTimeError
-conditional_method_invocation_test/06: MissingCompileTimeError
-conditional_method_invocation_test/07: MissingCompileTimeError
-conditional_method_invocation_test/08: MissingCompileTimeError
-conditional_method_invocation_test/12: MissingCompileTimeError
-conditional_method_invocation_test/13: MissingCompileTimeError
-conditional_method_invocation_test/18: MissingCompileTimeError
-conditional_method_invocation_test/19: MissingCompileTimeError
-conditional_property_access_test/04: MissingCompileTimeError
-conditional_property_access_test/05: MissingCompileTimeError
-conditional_property_access_test/06: MissingCompileTimeError
-conditional_property_access_test/10: MissingCompileTimeError
-conditional_property_access_test/11: MissingCompileTimeError
-conditional_property_access_test/16: MissingCompileTimeError
-conditional_property_access_test/17: MissingCompileTimeError
-conditional_property_assignment_test/04: MissingCompileTimeError
-conditional_property_assignment_test/05: MissingCompileTimeError
-conditional_property_assignment_test/06: MissingCompileTimeError
-conditional_property_assignment_test/10: MissingCompileTimeError
-conditional_property_assignment_test/11: MissingCompileTimeError
-conditional_property_assignment_test/12: MissingCompileTimeError
-conditional_property_assignment_test/13: MissingCompileTimeError
-conditional_property_assignment_test/27: MissingCompileTimeError
-conditional_property_assignment_test/28: MissingCompileTimeError
-conditional_property_assignment_test/32: MissingCompileTimeError
-conditional_property_assignment_test/33: MissingCompileTimeError
-conditional_property_assignment_test/34: MissingCompileTimeError
-conditional_property_assignment_test/35: MissingCompileTimeError
-conditional_property_increment_decrement_test/04: MissingCompileTimeError
-conditional_property_increment_decrement_test/08: MissingCompileTimeError
-conditional_property_increment_decrement_test/12: MissingCompileTimeError
-conditional_property_increment_decrement_test/16: MissingCompileTimeError
-conditional_property_increment_decrement_test/21: MissingCompileTimeError
-conditional_property_increment_decrement_test/22: MissingCompileTimeError
-conditional_property_increment_decrement_test/27: MissingCompileTimeError
-conditional_property_increment_decrement_test/28: MissingCompileTimeError
-conditional_property_increment_decrement_test/33: MissingCompileTimeError
-conditional_property_increment_decrement_test/34: MissingCompileTimeError
-conditional_property_increment_decrement_test/39: MissingCompileTimeError
-conditional_property_increment_decrement_test/40: MissingCompileTimeError
-const_conditional_test/08: MissingCompileTimeError
-const_constructor2_test/05: MissingCompileTimeError
-const_constructor2_test/06: MissingCompileTimeError
-const_constructor2_test/13: MissingCompileTimeError
-const_constructor2_test/14: MissingCompileTimeError
-const_constructor2_test/15: MissingCompileTimeError
-const_constructor2_test/16: MissingCompileTimeError
-const_constructor2_test/17: MissingCompileTimeError
-const_constructor2_test/18: MissingCompileTimeError
-const_constructor2_test/20: MissingCompileTimeError
-const_constructor2_test/22: MissingCompileTimeError
-const_constructor2_test/24: MissingCompileTimeError
-const_constructor3_test/02: MissingCompileTimeError
-const_constructor3_test/04: MissingCompileTimeError
-const_init2_test/02: MissingCompileTimeError
-const_syntax_test/08: MissingCompileTimeError
-const_syntax_test/10: MissingCompileTimeError
-const_types_test/01: MissingCompileTimeError
-const_types_test/02: MissingCompileTimeError
-const_types_test/03: MissingCompileTimeError
-const_types_test/04: MissingCompileTimeError
-const_types_test/05: MissingCompileTimeError
-const_types_test/06: MissingCompileTimeError
-const_types_test/13: MissingCompileTimeError
-const_types_test/35: MissingCompileTimeError
-const_types_test/40: MissingCompileTimeError
-constants_test/05: MissingCompileTimeError
-constructor13_test/01: MissingCompileTimeError
-constructor13_test/02: MissingCompileTimeError
-constructor_call_wrong_argument_count_test/01: MissingCompileTimeError
-constructor_duplicate_final_test/01: MissingCompileTimeError
-constructor_duplicate_final_test/02: MissingCompileTimeError
-constructor_named_arguments_test/01: MissingCompileTimeError
-create_unresolved_type_test/01: MissingCompileTimeError
-cyclic_typedef_test/13: MissingCompileTimeError
-deferred_constraints_type_annotation_test/as_operation: MissingCompileTimeError
-deferred_constraints_type_annotation_test/catch_check: MissingCompileTimeError
-deferred_constraints_type_annotation_test/is_check: MissingCompileTimeError
-deferred_constraints_type_annotation_test/new_before_load: MissingCompileTimeError
-deferred_constraints_type_annotation_test/new_generic2: MissingCompileTimeError
-deferred_constraints_type_annotation_test/new_generic3: MissingCompileTimeError
-deferred_constraints_type_annotation_test/type_annotation1: MissingCompileTimeError
-deferred_constraints_type_annotation_test/type_annotation_generic1: MissingCompileTimeError
-deferred_constraints_type_annotation_test/type_annotation_generic2: MissingCompileTimeError
-deferred_constraints_type_annotation_test/type_annotation_generic3: MissingCompileTimeError
-deferred_constraints_type_annotation_test/type_annotation_generic4: MissingCompileTimeError
-deferred_constraints_type_annotation_test/type_annotation_null: MissingCompileTimeError
-deferred_constraints_type_annotation_test/type_annotation_top_level: MissingCompileTimeError
-duplicate_implements_test/03: MissingCompileTimeError
-duplicate_implements_test/04: MissingCompileTimeError
-dynamic_field_test/01: MissingCompileTimeError
-dynamic_field_test/02: MissingCompileTimeError
-dynamic_prefix_core_test/01: MissingCompileTimeError
-empty_block_case_test: MissingCompileTimeError
-enum_private_test/02: MissingCompileTimeError
-error_stacktrace_test/00: MissingCompileTimeError
-external_test/21: CompileTimeError
-external_test/24: CompileTimeError
-factory1_test/00: MissingCompileTimeError
-factory1_test/01: MissingCompileTimeError
-factory2_test/none: MissingCompileTimeError
-factory3_test/none: MissingCompileTimeError
-factory5_test/00: MissingCompileTimeError
-factory6_test/00: MissingCompileTimeError
-factory_redirection_test/01: MissingCompileTimeError
-factory_redirection_test/02: MissingCompileTimeError
-factory_redirection_test/03: MissingCompileTimeError
-factory_redirection_test/05: MissingCompileTimeError
-factory_redirection_test/06: MissingCompileTimeError
-factory_redirection_test/07: MissingCompileTimeError
-factory_redirection_test/08: MissingCompileTimeError
-factory_redirection_test/09: MissingCompileTimeError
-factory_redirection_test/10: MissingCompileTimeError
-factory_redirection_test/11: MissingCompileTimeError
-factory_redirection_test/12: MissingCompileTimeError
-factory_redirection_test/13: MissingCompileTimeError
-factory_redirection_test/14: MissingCompileTimeError
-factory_redirection_test/none: MissingCompileTimeError
-factory_return_type_checked_test/00: MissingCompileTimeError
-fauxverride_test/03: MissingCompileTimeError
-fauxverride_test/05: MissingCompileTimeError
-field_method4_test: MissingCompileTimeError
-field_override2_test: MissingCompileTimeError
-field_override3_test/00: MissingCompileTimeError
-field_override3_test/01: MissingCompileTimeError
-field_override3_test/02: MissingCompileTimeError
-field_override3_test/03: MissingCompileTimeError
-field_override_test/02: MissingCompileTimeError
-field_override_test/none: MissingCompileTimeError
-field_type_check_test/01: MissingCompileTimeError
-final_attempt_reinitialization_test/01: MissingCompileTimeError
-final_attempt_reinitialization_test/02: MissingCompileTimeError
-final_for_in_variable_test: MissingCompileTimeError
-final_param_test: MissingCompileTimeError
-final_super_field_set_test: MissingCompileTimeError
-final_syntax_test/10: MissingCompileTimeError
-final_variable_assignment_test/01: MissingCompileTimeError
-final_variable_assignment_test/02: MissingCompileTimeError
-final_variable_assignment_test/03: MissingCompileTimeError
-final_variable_assignment_test/04: MissingCompileTimeError
-first_class_types_literals_test/03: MissingCompileTimeError
-first_class_types_literals_test/04: MissingCompileTimeError
-first_class_types_literals_test/05: MissingCompileTimeError
-first_class_types_literals_test/06: MissingCompileTimeError
-first_class_types_literals_test/07: MissingCompileTimeError
-first_class_types_literals_test/08: MissingCompileTimeError
-first_class_types_literals_test/09: MissingCompileTimeError
-first_class_types_literals_test/10: MissingCompileTimeError
-first_class_types_literals_test/11: MissingCompileTimeError
-first_class_types_literals_test/12: MissingCompileTimeError
-for_in3_test: MissingCompileTimeError
-function_malformed_result_type_test/00: MissingCompileTimeError
-function_type_call_getter2_test/00: MissingCompileTimeError
-function_type_call_getter2_test/01: MissingCompileTimeError
-function_type_call_getter2_test/02: MissingCompileTimeError
-function_type_call_getter2_test/03: MissingCompileTimeError
-function_type_call_getter2_test/04: MissingCompileTimeError
-function_type_call_getter2_test/05: MissingCompileTimeError
-fuzzy_arrows_test/01: MissingCompileTimeError
-generic_constructor_mixin2_test/01: MissingCompileTimeError
-generic_constructor_mixin3_test/01: MissingCompileTimeError
-generic_constructor_mixin_test/01: MissingCompileTimeError
-generic_field_mixin6_test/01: MissingCompileTimeError
-generic_function_typedef2_test/04: MissingCompileTimeError
-generic_methods_dynamic_test/01: MissingCompileTimeError
-generic_methods_dynamic_test/03: MissingCompileTimeError
-generic_methods_generic_function_result_test/01: MissingCompileTimeError
-generic_methods_overriding_test/03: MissingCompileTimeError
-getter_no_setter2_test/00: MissingCompileTimeError
-getter_no_setter2_test/01: MissingCompileTimeError
-getter_no_setter2_test/03: MissingCompileTimeError
-getter_no_setter_test/00: MissingCompileTimeError
-getter_no_setter_test/01: MissingCompileTimeError
-getter_no_setter_test/03: MissingCompileTimeError
-getter_override_test/00: MissingCompileTimeError
-getter_override_test/01: MissingCompileTimeError
-getter_override_test/02: MissingCompileTimeError
-getter_override_test/03: MissingCompileTimeError
-getters_setters2_test/02: MissingCompileTimeError
-if_null_assignment_behavior_test/03: MissingCompileTimeError
-if_null_assignment_behavior_test/13: MissingCompileTimeError
-if_null_assignment_behavior_test/15: MissingCompileTimeError
-if_null_assignment_static_test/02: MissingCompileTimeError
-if_null_assignment_static_test/04: MissingCompileTimeError
-if_null_assignment_static_test/06: MissingCompileTimeError
-if_null_assignment_static_test/07: MissingCompileTimeError
-if_null_assignment_static_test/09: MissingCompileTimeError
-if_null_assignment_static_test/11: MissingCompileTimeError
-if_null_assignment_static_test/13: MissingCompileTimeError
-if_null_assignment_static_test/14: MissingCompileTimeError
-if_null_assignment_static_test/16: MissingCompileTimeError
-if_null_assignment_static_test/18: MissingCompileTimeError
-if_null_assignment_static_test/20: MissingCompileTimeError
-if_null_assignment_static_test/21: MissingCompileTimeError
-if_null_assignment_static_test/23: MissingCompileTimeError
-if_null_assignment_static_test/25: MissingCompileTimeError
-if_null_assignment_static_test/27: MissingCompileTimeError
-if_null_assignment_static_test/28: MissingCompileTimeError
-if_null_assignment_static_test/30: MissingCompileTimeError
-if_null_assignment_static_test/32: MissingCompileTimeError
-if_null_assignment_static_test/34: MissingCompileTimeError
-if_null_assignment_static_test/35: MissingCompileTimeError
-if_null_assignment_static_test/37: MissingCompileTimeError
-if_null_assignment_static_test/39: MissingCompileTimeError
-if_null_assignment_static_test/41: MissingCompileTimeError
-if_null_assignment_static_test/42: MissingCompileTimeError
-if_null_precedence_test/06: MissingCompileTimeError
-if_null_precedence_test/07: MissingCompileTimeError
-implicit_this_test/02: MissingCompileTimeError
-import_combinators2_test/00: MissingCompileTimeError
-import_self_test/01: MissingCompileTimeError
-inferrer_constructor5_test/01: MissingCompileTimeError
-initializing_formal_final_test: MissingCompileTimeError
-initializing_formal_type_test: MissingCompileTimeError
-instance_call_wrong_argument_count_negative_test: Fail
-instance_method2_negative_test: Fail
-instance_method_negative_test: Fail
-instantiate_type_variable_test/01: MissingCompileTimeError
-interface_static_non_final_fields_negative_test: Fail
-interface_test/00: MissingCompileTimeError
-invalid_cast_test/01: MissingCompileTimeError
-invalid_cast_test/02: MissingCompileTimeError
-invalid_cast_test/03: MissingCompileTimeError
-invalid_cast_test/04: MissingCompileTimeError
-invalid_cast_test/07: MissingCompileTimeError
-invalid_cast_test/08: MissingCompileTimeError
-invalid_cast_test/09: MissingCompileTimeError
-invalid_cast_test/10: MissingCompileTimeError
-invalid_cast_test/11: MissingCompileTimeError
-invalid_type_argument_count_test/01: MissingCompileTimeError
-invalid_type_argument_count_test/02: MissingCompileTimeError
-invalid_type_argument_count_test/03: MissingCompileTimeError
-invalid_type_argument_count_test/04: MissingCompileTimeError
-issue31596_override_test/05: MissingCompileTimeError
-issue31596_override_test/06: MissingCompileTimeError
-least_upper_bound_expansive_test/01: MissingCompileTimeError
-least_upper_bound_expansive_test/02: MissingCompileTimeError
-least_upper_bound_expansive_test/03: MissingCompileTimeError
-least_upper_bound_expansive_test/04: MissingCompileTimeError
-least_upper_bound_expansive_test/05: MissingCompileTimeError
-least_upper_bound_expansive_test/06: MissingCompileTimeError
-least_upper_bound_expansive_test/07: MissingCompileTimeError
-least_upper_bound_expansive_test/08: MissingCompileTimeError
-least_upper_bound_expansive_test/09: MissingCompileTimeError
-least_upper_bound_expansive_test/10: MissingCompileTimeError
-least_upper_bound_expansive_test/11: MissingCompileTimeError
-least_upper_bound_expansive_test/12: MissingCompileTimeError
-least_upper_bound_test/03: MissingCompileTimeError
-least_upper_bound_test/04: MissingCompileTimeError
-least_upper_bound_test/10: MissingCompileTimeError
-least_upper_bound_test/19: MissingCompileTimeError
-least_upper_bound_test/20: MissingCompileTimeError
-least_upper_bound_test/23: MissingCompileTimeError
-least_upper_bound_test/24: MissingCompileTimeError
-least_upper_bound_test/29: MissingCompileTimeError
-least_upper_bound_test/30: MissingCompileTimeError
-least_upper_bound_test/32: MissingCompileTimeError
-library_ambiguous_test/00: MissingCompileTimeError
-library_ambiguous_test/01: MissingCompileTimeError
-library_ambiguous_test/02: MissingCompileTimeError
-library_ambiguous_test/03: MissingCompileTimeError
-library_ambiguous_test/04: MissingCompileTimeError
-list_literal1_test/01: MissingCompileTimeError
-list_literal4_test/00: MissingCompileTimeError
-list_literal4_test/01: MissingCompileTimeError
-list_literal4_test/03: MissingCompileTimeError
-list_literal4_test/04: MissingCompileTimeError
-list_literal4_test/05: MissingCompileTimeError
-list_literal_syntax_test/01: MissingCompileTimeError
-list_literal_syntax_test/02: MissingCompileTimeError
-list_literal_syntax_test/03: MissingCompileTimeError
-local_function2_test/01: MissingCompileTimeError
-local_function2_test/02: MissingCompileTimeError
-local_function3_test/01: MissingCompileTimeError
-local_function_test/01: MissingCompileTimeError
-local_function_test/02: MissingCompileTimeError
-local_function_test/03: MissingCompileTimeError
-local_function_test/04: MissingCompileTimeError
-logical_expression3_test: MissingCompileTimeError
-malformed2_test/00: MissingCompileTimeError
-malformed2_test/01: MissingCompileTimeError
-malformed2_test/02: MissingCompileTimeError
-malformed2_test/03: MissingCompileTimeError
-malformed2_test/04: MissingCompileTimeError
-malformed2_test/05: MissingCompileTimeError
-malformed2_test/06: MissingCompileTimeError
-malformed2_test/07: MissingCompileTimeError
-malformed2_test/08: MissingCompileTimeError
-malformed2_test/09: MissingCompileTimeError
-malformed2_test/10: MissingCompileTimeError
-malformed2_test/11: MissingCompileTimeError
-malformed2_test/12: MissingCompileTimeError
-malformed2_test/13: MissingCompileTimeError
-malformed_bound_test/00: MissingCompileTimeError
-malformed_bound_test/01: MissingCompileTimeError
-malformed_inheritance_test/01: MissingCompileTimeError
-malformed_inheritance_test/03: MissingCompileTimeError
-malformed_inheritance_test/05: MissingCompileTimeError
-malformed_test/00: MissingCompileTimeError
-malformed_test/01: MissingCompileTimeError
-malformed_test/02: MissingCompileTimeError
-malformed_test/03: MissingCompileTimeError
-malformed_test/04: MissingCompileTimeError
-malformed_test/05: MissingCompileTimeError
-malformed_test/06: MissingCompileTimeError
-malformed_test/07: MissingCompileTimeError
-malformed_test/08: MissingCompileTimeError
-malformed_test/09: MissingCompileTimeError
-malformed_test/10: MissingCompileTimeError
-malformed_test/11: MissingCompileTimeError
-malformed_test/12: MissingCompileTimeError
-malformed_test/13: MissingCompileTimeError
-malformed_test/14: MissingCompileTimeError
-malformed_test/15: MissingCompileTimeError
-malformed_test/16: MissingCompileTimeError
-malformed_test/17: MissingCompileTimeError
-malformed_test/18: MissingCompileTimeError
-malformed_test/19: MissingCompileTimeError
-malformed_test/20: MissingCompileTimeError
-malformed_test/21: MissingCompileTimeError
-malformed_test/22: MissingCompileTimeError
-malformed_test/23: MissingCompileTimeError
-malformed_test/24: MissingCompileTimeError
-malformed_type_test: MissingCompileTimeError
-method_override2_test/00: MissingCompileTimeError
-method_override2_test/01: MissingCompileTimeError
-method_override2_test/02: MissingCompileTimeError
-method_override2_test/03: MissingCompileTimeError
-method_override3_test/00: MissingCompileTimeError
-method_override3_test/01: MissingCompileTimeError
-method_override3_test/02: MissingCompileTimeError
-method_override7_test/00: MissingCompileTimeError
-method_override7_test/01: MissingCompileTimeError
-method_override7_test/02: MissingCompileTimeError
-method_override7_test/03: MissingCompileTimeError
-mixin_illegal_constructor_test/13: MissingCompileTimeError
-mixin_illegal_constructor_test/14: MissingCompileTimeError
-mixin_illegal_constructor_test/15: MissingCompileTimeError
-mixin_illegal_constructor_test/16: MissingCompileTimeError
-mixin_illegal_static_access_test/01: MissingCompileTimeError
-mixin_illegal_static_access_test/02: MissingCompileTimeError
-mixin_illegal_super_use_test/01: MissingCompileTimeError
-mixin_illegal_super_use_test/02: MissingCompileTimeError
-mixin_illegal_super_use_test/03: MissingCompileTimeError
-mixin_illegal_super_use_test/04: MissingCompileTimeError
-mixin_illegal_super_use_test/05: MissingCompileTimeError
-mixin_illegal_super_use_test/06: MissingCompileTimeError
-mixin_illegal_super_use_test/07: MissingCompileTimeError
-mixin_illegal_super_use_test/08: MissingCompileTimeError
-mixin_illegal_super_use_test/09: MissingCompileTimeError
-mixin_illegal_super_use_test/10: MissingCompileTimeError
-mixin_illegal_super_use_test/11: MissingCompileTimeError
-mixin_illegal_superclass_test/01: MissingCompileTimeError
-mixin_illegal_superclass_test/02: MissingCompileTimeError
-mixin_illegal_superclass_test/03: MissingCompileTimeError
-mixin_illegal_superclass_test/04: MissingCompileTimeError
-mixin_illegal_superclass_test/05: MissingCompileTimeError
-mixin_illegal_superclass_test/06: MissingCompileTimeError
-mixin_illegal_superclass_test/07: MissingCompileTimeError
-mixin_illegal_superclass_test/08: MissingCompileTimeError
-mixin_illegal_superclass_test/09: MissingCompileTimeError
-mixin_illegal_superclass_test/10: MissingCompileTimeError
-mixin_illegal_superclass_test/11: MissingCompileTimeError
-mixin_illegal_superclass_test/12: MissingCompileTimeError
-mixin_illegal_superclass_test/13: MissingCompileTimeError
-mixin_illegal_superclass_test/14: MissingCompileTimeError
-mixin_illegal_superclass_test/15: MissingCompileTimeError
-mixin_illegal_superclass_test/16: MissingCompileTimeError
-mixin_illegal_superclass_test/17: MissingCompileTimeError
-mixin_illegal_superclass_test/18: MissingCompileTimeError
-mixin_illegal_superclass_test/19: MissingCompileTimeError
-mixin_illegal_superclass_test/20: MissingCompileTimeError
-mixin_illegal_superclass_test/21: MissingCompileTimeError
-mixin_illegal_superclass_test/22: MissingCompileTimeError
-mixin_illegal_superclass_test/23: MissingCompileTimeError
-mixin_illegal_superclass_test/24: MissingCompileTimeError
-mixin_illegal_superclass_test/25: MissingCompileTimeError
-mixin_illegal_superclass_test/26: MissingCompileTimeError
-mixin_illegal_superclass_test/27: MissingCompileTimeError
-mixin_illegal_superclass_test/28: MissingCompileTimeError
-mixin_illegal_superclass_test/29: MissingCompileTimeError
-mixin_illegal_superclass_test/30: MissingCompileTimeError
-mixin_illegal_syntax_test/13: MissingCompileTimeError
-mixin_type_parameter_inference_error_test/01: MissingCompileTimeError
-mixin_type_parameter_inference_error_test/02: MissingCompileTimeError
-mixin_type_parameter_inference_previous_mixin_test/03: MissingCompileTimeError
-mixin_type_parameter_inference_previous_mixin_test/04: MissingCompileTimeError
-mixin_type_parameter_inference_test/04: MissingCompileTimeError
-mixin_type_parameter_inference_test/05: MissingCompileTimeError
-mixin_type_parameter_inference_test/06: MissingCompileTimeError
-mixin_type_parameter_inference_test/07: MissingCompileTimeError
-mixin_type_parameter_inference_test/11: MissingCompileTimeError
-mixin_type_parameter_inference_test/14: MissingCompileTimeError
-mixin_type_parameter_inference_test/15: MissingCompileTimeError
-mixin_type_parameters_errors_test/01: MissingCompileTimeError
-mixin_type_parameters_errors_test/02: MissingCompileTimeError
-mixin_type_parameters_errors_test/05: MissingCompileTimeError
-mixin_with_two_implicit_constructors_test: MissingCompileTimeError
-multiline_newline_test/04: MissingCompileTimeError
-multiline_newline_test/04r: MissingCompileTimeError
-multiline_newline_test/05: MissingCompileTimeError
-multiline_newline_test/05r: MissingCompileTimeError
-multiline_newline_test/06: MissingCompileTimeError
-multiline_newline_test/06r: MissingCompileTimeError
-named_constructor_test/03: MissingCompileTimeError
-named_parameters2_test: MissingCompileTimeError
-named_parameters3_test: MissingCompileTimeError
-named_parameters4_test: MissingCompileTimeError
-named_parameters_aggregated_test/05: MissingCompileTimeError
-named_parameters_test/01: MissingCompileTimeError
-named_parameters_test/02: MissingCompileTimeError
-named_parameters_test/03: MissingCompileTimeError
-named_parameters_test/04: MissingCompileTimeError
-named_parameters_test/05: MissingCompileTimeError
-named_parameters_test/06: MissingCompileTimeError
-named_parameters_test/07: MissingCompileTimeError
-named_parameters_test/08: MissingCompileTimeError
-named_parameters_test/09: MissingCompileTimeError
-named_parameters_test/10: MissingCompileTimeError
-named_parameters_type_test/01: MissingCompileTimeError
-named_parameters_type_test/02: MissingCompileTimeError
-named_parameters_type_test/03: MissingCompileTimeError
-new_expression_type_args_test/00: MissingCompileTimeError
-new_expression_type_args_test/01: MissingCompileTimeError
-new_expression_type_args_test/02: MissingCompileTimeError
-new_prefix_test/01: MissingCompileTimeError
-no_such_constructor_test/01: MissingCompileTimeError
-no_such_method_negative_test: Fail
-not_enough_positional_arguments_test/00: MissingCompileTimeError
-not_enough_positional_arguments_test/01: MissingCompileTimeError
-not_enough_positional_arguments_test/02: MissingCompileTimeError
-not_enough_positional_arguments_test/03: MissingCompileTimeError
-not_enough_positional_arguments_test/05: MissingCompileTimeError
-not_enough_positional_arguments_test/06: MissingCompileTimeError
-not_enough_positional_arguments_test/07: MissingCompileTimeError
-object_has_no_call_method_test/02: MissingCompileTimeError
-object_has_no_call_method_test/05: MissingCompileTimeError
-object_has_no_call_method_test/08: MissingCompileTimeError
-optional_named_parameters_test/01: MissingCompileTimeError
-optional_named_parameters_test/02: MissingCompileTimeError
-optional_named_parameters_test/03: MissingCompileTimeError
-optional_named_parameters_test/04: MissingCompileTimeError
-optional_named_parameters_test/05: MissingCompileTimeError
-optional_named_parameters_test/06: MissingCompileTimeError
-optional_named_parameters_test/07: MissingCompileTimeError
-optional_named_parameters_test/08: MissingCompileTimeError
-optional_named_parameters_test/09: MissingCompileTimeError
-override_field_test/01: MissingCompileTimeError
-override_inheritance_abstract_test/*: Skip # Tests Dart 2 semantics
-override_inheritance_field_test/04: MissingCompileTimeError
-override_inheritance_field_test/05: MissingCompileTimeError
-override_inheritance_field_test/06: MissingCompileTimeError
-override_inheritance_field_test/07: MissingCompileTimeError
-override_inheritance_field_test/08: MissingCompileTimeError
-override_inheritance_field_test/09: MissingCompileTimeError
-override_inheritance_field_test/10: MissingCompileTimeError
-override_inheritance_field_test/11: MissingCompileTimeError
-override_inheritance_field_test/26: MissingCompileTimeError
-override_inheritance_field_test/28: MissingCompileTimeError
-override_inheritance_field_test/29: MissingCompileTimeError
-override_inheritance_field_test/30: MissingCompileTimeError
-override_inheritance_field_test/31: MissingCompileTimeError
-override_inheritance_field_test/32: MissingCompileTimeError
-override_inheritance_field_test/33: MissingCompileTimeError
-override_inheritance_field_test/33a: MissingCompileTimeError
-override_inheritance_field_test/34: MissingCompileTimeError
-override_inheritance_generic_test/02: MissingCompileTimeError
-override_inheritance_generic_test/04: MissingCompileTimeError
-override_inheritance_generic_test/06: MissingCompileTimeError
-override_inheritance_generic_test/07: MissingCompileTimeError
-override_inheritance_generic_test/08: MissingCompileTimeError
-override_inheritance_generic_test/09: MissingCompileTimeError
-override_inheritance_generic_test/10: MissingCompileTimeError
-override_inheritance_method_test/04: MissingCompileTimeError
-override_inheritance_method_test/05: MissingCompileTimeError
-override_inheritance_method_test/06: MissingCompileTimeError
-override_inheritance_method_test/11: MissingCompileTimeError
-override_inheritance_method_test/12: MissingCompileTimeError
-override_inheritance_method_test/13: MissingCompileTimeError
-override_inheritance_method_test/14: MissingCompileTimeError
-override_inheritance_method_test/19: MissingCompileTimeError
-override_inheritance_method_test/20: MissingCompileTimeError
-override_inheritance_method_test/21: MissingCompileTimeError
-override_inheritance_method_test/27: MissingCompileTimeError
-override_inheritance_method_test/28: MissingCompileTimeError
-override_inheritance_method_test/29: MissingCompileTimeError
-override_inheritance_method_test/30: MissingCompileTimeError
-override_inheritance_method_test/31: MissingCompileTimeError
-override_inheritance_method_test/32: MissingCompileTimeError
-override_inheritance_method_test/33: MissingCompileTimeError
-override_inheritance_method_test/36: MissingCompileTimeError
-override_inheritance_method_test/39: MissingCompileTimeError
-override_method_with_field_test/02: MissingCompileTimeError
-part2_test/01: MissingCompileTimeError
-partial_tearoff_instantiation_test/01: MissingCompileTimeError
-partial_tearoff_instantiation_test/03: MissingCompileTimeError
-positional_parameters_type_test/01: MissingCompileTimeError
-positional_parameters_type_test/02: MissingCompileTimeError
-prefix16_test/00: MissingCompileTimeError
-prefix16_test/01: MissingCompileTimeError
-prefix22_test/00: MissingCompileTimeError
-prefix23_test/00: MissingCompileTimeError
-private_access_test/01: MissingCompileTimeError
-private_access_test/02: MissingCompileTimeError
-private_access_test/03: MissingCompileTimeError
-private_access_test/04: MissingCompileTimeError
-private_access_test/05: MissingCompileTimeError
-private_access_test/06: MissingCompileTimeError
-private_member1_negative_test: Fail
-private_member2_negative_test: Fail
-private_member3_negative_test: Fail
-private_super_constructor_test/01: MissingCompileTimeError
-regress_12561_test: MissingCompileTimeError
-regress_13494_test: MissingCompileTimeError
-regress_17382_test: MissingCompileTimeError
-regress_19413_test: MissingCompileTimeError
-regress_19728_test: MissingCompileTimeError
-regress_20394_test/01: MissingCompileTimeError
-regress_21793_test/01: MissingCompileTimeError
-regress_21912_test/01: MissingCompileTimeError
-regress_21912_test/02: MissingCompileTimeError
-regress_22438_test: MissingCompileTimeError
-regress_22936_test: MissingCompileTimeError
-regress_26133_test: MissingCompileTimeError
-regress_27572_test: MissingCompileTimeError
-regress_28217_test/01: MissingCompileTimeError
-regress_28217_test/none: MissingCompileTimeError
-return_type_test: MissingCompileTimeError
-rewrite_implicit_this_test/01: MissingCompileTimeError
-setter_no_getter_call_test/01: MissingCompileTimeError
-setter_override2_test/02: MissingCompileTimeError
-setter_override_test/00: MissingCompileTimeError
-setter_override_test/01: MissingCompileTimeError
-setter_override_test/02: MissingCompileTimeError
-setter_override_test/03: MissingCompileTimeError
-static_call_wrong_argument_count_negative_test: Fail
-static_field1_test/01: MissingCompileTimeError
-static_field1a_test/01: MissingCompileTimeError
-static_field3_test/01: MissingCompileTimeError
-static_field3_test/02: MissingCompileTimeError
-static_field3_test/03: MissingCompileTimeError
-static_field3_test/04: MissingCompileTimeError
-static_field_test/01: MissingCompileTimeError
-static_field_test/02: MissingCompileTimeError
-static_field_test/03: MissingCompileTimeError
-static_field_test/04: MissingCompileTimeError
-static_final_field2_test/01: MissingCompileTimeError
-static_getter_no_setter1_test/01: MissingCompileTimeError
-static_getter_no_setter2_test/01: MissingCompileTimeError
-static_initializer_type_error_test: MissingCompileTimeError
-static_setter_conflicts_test/01: MissingCompileTimeError
-static_setter_conflicts_test/03: MissingCompileTimeError
-static_setter_conflicts_test/04: MissingCompileTimeError
-static_setter_conflicts_test/07: MissingCompileTimeError
-static_setter_get_test/01: MissingCompileTimeError
-string_interpolation_test/01: MissingCompileTimeError
-string_no_operator_test/01: MissingCompileTimeError
-string_no_operator_test/02: MissingCompileTimeError
-string_no_operator_test/03: MissingCompileTimeError
-string_no_operator_test/04: MissingCompileTimeError
-string_no_operator_test/05: MissingCompileTimeError
-string_no_operator_test/06: MissingCompileTimeError
-string_no_operator_test/07: MissingCompileTimeError
-string_no_operator_test/08: MissingCompileTimeError
-string_no_operator_test/09: MissingCompileTimeError
-string_no_operator_test/10: MissingCompileTimeError
-string_no_operator_test/11: MissingCompileTimeError
-string_no_operator_test/12: MissingCompileTimeError
-string_no_operator_test/13: MissingCompileTimeError
-string_no_operator_test/14: MissingCompileTimeError
-string_no_operator_test/15: MissingCompileTimeError
-string_no_operator_test/16: MissingCompileTimeError
-string_test/01: MissingCompileTimeError
-substring_test/01: MissingCompileTimeError
-super_assign_test/01: MissingCompileTimeError
-super_bound_closure_test/01: MissingCompileTimeError
-super_operator_index_test/01: MissingCompileTimeError
-super_operator_index_test/02: MissingCompileTimeError
-super_operator_index_test/03: MissingCompileTimeError
-super_operator_index_test/04: MissingCompileTimeError
-super_operator_index_test/05: MissingCompileTimeError
-super_operator_index_test/06: MissingCompileTimeError
-super_operator_index_test/07: MissingCompileTimeError
-switch_fallthru_test/01: MissingCompileTimeError
-symbol_literal_test/01: MissingCompileTimeError
-sync_generator1_test/01: MissingCompileTimeError
-syntax_test/59: MissingCompileTimeError
-top_level_getter_no_setter1_test: MissingCompileTimeError
-top_level_getter_no_setter2_test: MissingCompileTimeError
-transitive_private_library_access_test: MissingCompileTimeError
-try_catch_on_syntax_test/07: MissingCompileTimeError
-try_catch_on_syntax_test/10: MissingCompileTimeError
-try_catch_on_syntax_test/11: MissingCompileTimeError
-try_catch_syntax_test/08: MissingCompileTimeError
-try_catch_test/01: MissingCompileTimeError
-type_check_const_function_typedef2_test: MissingCompileTimeError
-type_checks_in_factory_method_test/01: MissingCompileTimeError
-type_inference_accessor_ref_test/03: MissingCompileTimeError
-type_inference_accessor_ref_test/06: MissingCompileTimeError
-type_inference_circularity_test: MissingCompileTimeError
-type_inference_inconsistent_inheritance_test: MissingCompileTimeError
-type_promotion_parameter_test/01: MissingCompileTimeError
-type_promotion_parameter_test/02: MissingCompileTimeError
-type_promotion_parameter_test/03: MissingCompileTimeError
-type_promotion_parameter_test/04: MissingCompileTimeError
-type_promotion_parameter_test/05: MissingCompileTimeError
-type_promotion_parameter_test/06: MissingCompileTimeError
-type_promotion_parameter_test/07: MissingCompileTimeError
-type_promotion_parameter_test/08: MissingCompileTimeError
-type_promotion_parameter_test/09: MissingCompileTimeError
-type_promotion_parameter_test/10: MissingCompileTimeError
-type_promotion_parameter_test/11: MissingCompileTimeError
-type_promotion_parameter_test/12: MissingCompileTimeError
-type_promotion_parameter_test/13: MissingCompileTimeError
-type_promotion_parameter_test/14: MissingCompileTimeError
-type_promotion_parameter_test/15: MissingCompileTimeError
-type_promotion_parameter_test/16: MissingCompileTimeError
-type_promotion_parameter_test/17: MissingCompileTimeError
-type_promotion_parameter_test/18: MissingCompileTimeError
-type_promotion_parameter_test/19: MissingCompileTimeError
-type_promotion_parameter_test/20: MissingCompileTimeError
-type_promotion_parameter_test/21: MissingCompileTimeError
-type_promotion_parameter_test/22: MissingCompileTimeError
-type_promotion_parameter_test/23: MissingCompileTimeError
-type_promotion_parameter_test/24: MissingCompileTimeError
-type_promotion_parameter_test/25: MissingCompileTimeError
-type_promotion_parameter_test/26: MissingCompileTimeError
-type_promotion_parameter_test/27: MissingCompileTimeError
-type_promotion_parameter_test/28: MissingCompileTimeError
-type_promotion_parameter_test/29: MissingCompileTimeError
-type_promotion_parameter_test/30: MissingCompileTimeError
-type_promotion_parameter_test/31: MissingCompileTimeError
-type_promotion_parameter_test/32: MissingCompileTimeError
-type_promotion_parameter_test/33: MissingCompileTimeError
-type_promotion_parameter_test/34: MissingCompileTimeError
-type_promotion_parameter_test/35: MissingCompileTimeError
-type_promotion_parameter_test/36: MissingCompileTimeError
-type_promotion_parameter_test/37: MissingCompileTimeError
-type_promotion_parameter_test/38: MissingCompileTimeError
-type_promotion_parameter_test/39: MissingCompileTimeError
-type_promotion_parameter_test/40: MissingCompileTimeError
-type_promotion_parameter_test/41: MissingCompileTimeError
-type_promotion_parameter_test/42: MissingCompileTimeError
-type_promotion_parameter_test/43: MissingCompileTimeError
-type_promotion_parameter_test/44: MissingCompileTimeError
-type_promotion_parameter_test/45: MissingCompileTimeError
-type_promotion_parameter_test/46: MissingCompileTimeError
-type_promotion_parameter_test/47: MissingCompileTimeError
-type_promotion_parameter_test/48: MissingCompileTimeError
-type_promotion_parameter_test/49: MissingCompileTimeError
-type_promotion_parameter_test/50: MissingCompileTimeError
-type_promotion_parameter_test/51: MissingCompileTimeError
-type_promotion_parameter_test/52: MissingCompileTimeError
-type_promotion_parameter_test/54: MissingCompileTimeError
-type_promotion_parameter_test/55: MissingCompileTimeError
-type_promotion_parameter_test/56: MissingCompileTimeError
-type_variable_bounds_test/00: MissingCompileTimeError
-type_variable_bounds_test/07: MissingCompileTimeError
-type_variable_bounds_test/09: MissingCompileTimeError
-type_variable_bounds_test/10: MissingCompileTimeError
-type_variable_conflict2_test/01: MissingCompileTimeError
-type_variable_conflict2_test/02: MissingCompileTimeError
-type_variable_conflict2_test/03: MissingCompileTimeError
-type_variable_conflict2_test/04: MissingCompileTimeError
-type_variable_conflict2_test/05: MissingCompileTimeError
-type_variable_conflict2_test/07: MissingCompileTimeError
-type_variable_conflict2_test/09: MissingCompileTimeError
-type_variable_identifier_expression_test: MissingCompileTimeError
-type_variable_scope2_test: MissingCompileTimeError
-type_variable_scope_test/00: MissingCompileTimeError
-type_variable_scope_test/01: MissingCompileTimeError
-type_variable_scope_test/02: MissingCompileTimeError
-type_variable_scope_test/03: MissingCompileTimeError
-type_variable_scope_test/04: MissingCompileTimeError
-type_variable_scope_test/05: MissingCompileTimeError
-type_variable_static_context_test: MissingCompileTimeError
-typed_selector2_test: MissingCompileTimeError
-unbound_getter_test: MissingCompileTimeError
-unresolved_default_constructor_test/01: MissingCompileTimeError
-unresolved_in_factory_test: MissingCompileTimeError
-unresolved_top_level_method_test: MissingCompileTimeError
-unresolved_top_level_var_test: MissingCompileTimeError
-
 [ $hot_reload_rollback && ($compiler == dartk || $compiler == dartkb) ]
 symbol_conflict_test: Pass, Slow
 
 # Enabling of dartk for sim{arm,arm64,dbc64} revealed these test failures, which
 # are to be triaged.  Isolate tests are skipped on purpose due to the usage of
 # batch mode.
-[ $strong && ($arch == simarm || $arch == simarm64 || $arch == simdbc64) && ($compiler == dartk || $compiler == dartkb) ]
+[ ($arch == simarm || $arch == simarm64 || $arch == simdbc64) && ($compiler == dartk || $compiler == dartkb) ]
 least_upper_bound_expansive_test/none: RuntimeError # Please triage.
 
-[ $strong && ($compiler == dartk || $compiler == dartkb) ]
-covariant_subtyping_test: RuntimeError
-redirecting_factory_reflection_test: RuntimeError
-
-[ !$strong && ($compiler == dartk || $compiler == dartkb || $compiler == dartkp || $runtime == dart_precompiled || $runtime == vm) ]
-*: SkipByDesign # language_2 is only supported in strong mode.
-
 [ ($compiler == app_jitk || $compiler == dartk || $compiler == dartkp) && ($runtime == dart_precompiled || $runtime == vm) ]
 covariant_subtyping_with_mixin_test: RuntimeError # Issue 34321
 type_alias_equality_test/03: RuntimeError # Issue 32783
@@ -2095,6 +1049,10 @@
 async_star_test/none: Skip # Timeout
 type_constants_test/none: Skip # Deferred libraries and hot reload.
 
+[ $compiler == dartk || $compiler == dartkb ]
+covariant_subtyping_test: RuntimeError
+redirecting_factory_reflection_test: RuntimeError
+
 [ $compiler == dartk || $compiler == dartkb || $compiler == dartkp ]
 generic_function_bounds_test: RuntimeError # Issue 32076
 
diff --git a/tests/language_2/language_2_vm.status b/tests/language_2/language_2_vm.status
index fef4d22..ceb8ec6 100644
--- a/tests/language_2/language_2_vm.status
+++ b/tests/language_2/language_2_vm.status
@@ -28,8 +28,5 @@
 [ $arch == ia32 && $mode == release && $runtime == vm ]
 deep_nesting_expression_test/01: Crash, Pass # Issue 31496
 
-[ !$strong && ($runtime == dart_precompiled || $runtime == vm) ]
-*: SkipByDesign # tests/language has the non-strong mode versions of these tests.
-
 [ $runtime == dart_precompiled || $runtime == vm ]
 superinterface_variance/*: Skip # Issue dart-lang/language#113
diff --git a/tests/language_2/nnbd/static_errors/nullable_function_types_test.dart b/tests/language_2/nnbd/static_errors/nullable_function_types_test.dart
new file mode 100644
index 0000000..714ecb8
--- /dev/null
+++ b/tests/language_2/nnbd/static_errors/nullable_function_types_test.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=non-nullable
+
+class C {
+  call() {}
+}
+
+// Test calling various nullable functions produces errors.
+void main() {
+  Function()? nf1;
+  Function? nf2;
+  C c1 = new C();
+  C? nc1;
+  var nf3 = c1?.call;
+  Object? object;
+
+
+  nf1(); //# 00: compile-time error
+  nf2(); //# 01: compile-time error
+  nf3(); //# 02: compile-time error
+  c1(); //# 03: ok
+  nc1(); //# 04: compile-time error
+  object(); //# 05: compile-time error
+}
diff --git a/tests/language_2/nnbd/static_errors/unchecked_use_of_nullable_test.dart b/tests/language_2/nnbd/static_errors/unchecked_use_of_nullable_test.dart
new file mode 100644
index 0000000..a991f55
--- /dev/null
+++ b/tests/language_2/nnbd/static_errors/unchecked_use_of_nullable_test.dart
@@ -0,0 +1,62 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=non-nullable
+
+// Test that it is an error to use nullable types in unsound ways.
+void main() async {
+  int? x;
+  bool? cond;
+  List? list;
+  dynamic dyn;
+  Function? func;
+  List<Function?> funcList;
+  Stream? stream;
+  x.isEven; //# 00: compile-time error
+  x.round(); //# 01: compile-time error
+  x.toString(); //# 02: ok
+  x.hashCode; //# 03: ok
+  x.runtimeType; //# 04: ok
+  x.noSuchMethod(null); //# 05: ok
+  x + 1; //# 06: compile-time error
+  -x; //# 06: compile-time error
+  x++; //# 07: compile-time error
+  ++x; //# 08: compile-time error
+  x..isEven; //# 09: compile-time error
+  list[0]; //# 10: compile-time error
+  list[0] = 0; //# 10: compile-time error
+  x += 1; //# 11: compile-time error
+  x ??= 1; //# 12: ok
+  x.round; //# 13: compile-time error
+  x.toString; //# 14: ok
+  x.noSuchMethod; //# 15: ok
+  func(); //# 16: compile-time error
+  funcList[0](); //# 17: compile-time error
+  funcList.single(); //# 18: compile-time error
+  throw x; //# 19: compile-time error
+  cond || true; //# 20: compile-time error
+  true || cond; //# 21: compile-time error
+  cond && true; //# 22: compile-time error
+  true && cond; //# 23: compile-time error
+  !cond; //# 24: compile-time error
+  cond ? null : null; //# 25: compile-time error
+  if (cond) {} //# 26: compile-time error
+  while (cond) {} //# 27: compile-time error
+  for (;cond;) {} //# 28: compile-time error
+  do {} while (cond); //# 29: compile-time error
+  cond!; //# 30: ok
+  cond ?? null; //# 31: ok
+  cond == null; //# 32: ok
+  cond != null; //# 33: ok
+  x?.isEven; //# 34: ok
+  x?.round(); //# 35: ok
+  for(i in list) {}; //# 36: compile-time error
+  await for(i in stream) {}; //# 37: compile-time error
+  assert(cond); //# 38: compile-time error
+}
+
+generator() sync* {
+  Iterable? iter;
+  yield* iter; //# 39: compile-time error
+}
diff --git a/tests/language_2/spread_collections/const_syntax_error_test.dart b/tests/language_2/spread_collections/const_syntax_error_test.dart
index 6bf98fe..1832821 100644
--- a/tests/language_2/spread_collections/const_syntax_error_test.dart
+++ b/tests/language_2/spread_collections/const_syntax_error_test.dart
@@ -5,7 +5,7 @@
 // Check that 'spread' in const collections is not enabled without the
 // experimental constant-update-2018 flag.
 
-// SharedOptions=--enable-experiment=spread-collections
+// SharedOptions=--enable-experiment=spread-collections,no-constant-update-2018
 
 const constList = [1, 2, 3, 4];
 const constSet = {1, 2, 3, 4};
diff --git a/tests/language_2/vm/causal_async_exception_stack2_test.dart b/tests/language_2/vm/causal_async_exception_stack2_test.dart
index a92ab7f..94dda4b 100644
--- a/tests/language_2/vm/causal_async_exception_stack2_test.dart
+++ b/tests/language_2/vm/causal_async_exception_stack2_test.dart
@@ -2,7 +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:expect/async_minitest.dart';
+import 'package:async_helper/async_minitest.dart';
 
 import 'causal_async_exception_stack_helper.dart' as h;
 
diff --git a/tests/language_2/vm/causal_async_exception_stack_test.dart b/tests/language_2/vm/causal_async_exception_stack_test.dart
index 3500fac..b4059e9 100644
--- a/tests/language_2/vm/causal_async_exception_stack_test.dart
+++ b/tests/language_2/vm/causal_async_exception_stack_test.dart
@@ -2,7 +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:expect/async_minitest.dart';
+import 'package:async_helper/async_minitest.dart';
 
 import 'causal_async_exception_stack_helper.dart' as h;
 
diff --git a/tests/lib_2/async/stream_controller_async_test.dart b/tests/lib_2/async/stream_controller_async_test.dart
index 3ee1725..a079250 100644
--- a/tests/lib_2/async/stream_controller_async_test.dart
+++ b/tests/lib_2/async/stream_controller_async_test.dart
@@ -8,7 +8,7 @@
 import 'dart:async';
 
 import 'package:expect/expect.dart';
-import 'package:expect/async_minitest.dart';
+import 'package:async_helper/async_minitest.dart';
 
 import 'event_helper.dart';
 import 'stream_state_helper.dart';
diff --git a/tests/lib_2/async/stream_from_iterable_test.dart b/tests/lib_2/async/stream_from_iterable_test.dart
index b8317f0..d80d989 100644
--- a/tests/lib_2/async/stream_from_iterable_test.dart
+++ b/tests/lib_2/async/stream_from_iterable_test.dart
@@ -8,7 +8,7 @@
 
 import 'package:async_helper/async_helper.dart';
 import 'package:expect/expect.dart';
-import 'package:expect/async_minitest.dart';
+import 'package:async_helper/async_minitest.dart';
 
 import 'event_helper.dart';
 
diff --git a/tests/lib_2/async/stream_iterator_test.dart b/tests/lib_2/async/stream_iterator_test.dart
index b4a6596..c50f53e 100644
--- a/tests/lib_2/async/stream_iterator_test.dart
+++ b/tests/lib_2/async/stream_iterator_test.dart
@@ -4,7 +4,7 @@
 
 import 'dart:async';
 
-import 'package:expect/async_minitest.dart';
+import 'package:async_helper/async_minitest.dart';
 
 main() {
   test("stream iterator basic", () async {
diff --git a/tests/lib_2/async/stream_join_test.dart b/tests/lib_2/async/stream_join_test.dart
index aeac53c..6e3a98b 100644
--- a/tests/lib_2/async/stream_join_test.dart
+++ b/tests/lib_2/async/stream_join_test.dart
@@ -8,7 +8,7 @@
 import 'dart:async';
 
 import 'package:expect/expect.dart';
-import 'package:expect/async_minitest.dart';
+import 'package:async_helper/async_minitest.dart';
 
 import 'event_helper.dart';
 
diff --git a/tests/lib_2/async/stream_periodic2_test.dart b/tests/lib_2/async/stream_periodic2_test.dart
index a69568d..1250131 100644
--- a/tests/lib_2/async/stream_periodic2_test.dart
+++ b/tests/lib_2/async/stream_periodic2_test.dart
@@ -7,7 +7,7 @@
 
 import 'dart:async';
 
-import 'package:expect/async_minitest.dart';
+import 'package:async_helper/async_minitest.dart';
 
 main() {
   test("stream-periodic2", () {
diff --git a/tests/lib_2/async/stream_periodic3_test.dart b/tests/lib_2/async/stream_periodic3_test.dart
index ab1adc2..a1fbbd0 100644
--- a/tests/lib_2/async/stream_periodic3_test.dart
+++ b/tests/lib_2/async/stream_periodic3_test.dart
@@ -7,7 +7,7 @@
 
 import 'dart:async';
 
-import 'package:expect/async_minitest.dart';
+import 'package:async_helper/async_minitest.dart';
 
 // The stopwatch is more precise than the Timer.
 // Some browsers (Firefox and IE so far) can trigger too early. So we add more
diff --git a/tests/lib_2/async/stream_periodic4_test.dart b/tests/lib_2/async/stream_periodic4_test.dart
index cbdc780..e687786 100644
--- a/tests/lib_2/async/stream_periodic4_test.dart
+++ b/tests/lib_2/async/stream_periodic4_test.dart
@@ -7,7 +7,7 @@
 
 import 'dart:async';
 
-import 'package:expect/async_minitest.dart';
+import 'package:async_helper/async_minitest.dart';
 
 void runTest(period, maxElapsed, pauseDuration) {
   Function done = expectAsync(() {});
diff --git a/tests/lib_2/async/stream_periodic5_test.dart b/tests/lib_2/async/stream_periodic5_test.dart
index 2a2f900..2be1c96 100644
--- a/tests/lib_2/async/stream_periodic5_test.dart
+++ b/tests/lib_2/async/stream_periodic5_test.dart
@@ -7,7 +7,7 @@
 
 import 'dart:async';
 
-import 'package:expect/async_minitest.dart';
+import 'package:async_helper/async_minitest.dart';
 
 watchMs(Stopwatch watch) {
   int microsecs = watch.elapsedMicroseconds;
diff --git a/tests/lib_2/async/stream_periodic6_test.dart b/tests/lib_2/async/stream_periodic6_test.dart
index 8b51ca8..0ef154e 100644
--- a/tests/lib_2/async/stream_periodic6_test.dart
+++ b/tests/lib_2/async/stream_periodic6_test.dart
@@ -7,7 +7,7 @@
 
 import 'dart:async';
 
-import 'package:expect/async_minitest.dart';
+import 'package:async_helper/async_minitest.dart';
 
 main() {
   test("stream-periodic1", () {
diff --git a/tests/lib_2/async/stream_periodic_test.dart b/tests/lib_2/async/stream_periodic_test.dart
index c8ea5a7..43a06d0 100644
--- a/tests/lib_2/async/stream_periodic_test.dart
+++ b/tests/lib_2/async/stream_periodic_test.dart
@@ -7,7 +7,7 @@
 
 import 'dart:async';
 
-import 'package:expect/async_minitest.dart';
+import 'package:async_helper/async_minitest.dart';
 
 main() {
   test("stream-periodic1", () {
diff --git a/tests/lib_2/async/stream_single_test.dart b/tests/lib_2/async/stream_single_test.dart
index 57bf54c..0156d71 100644
--- a/tests/lib_2/async/stream_single_test.dart
+++ b/tests/lib_2/async/stream_single_test.dart
@@ -8,7 +8,7 @@
 import 'dart:async';
 
 import 'package:expect/expect.dart';
-import 'package:expect/async_minitest.dart';
+import 'package:async_helper/async_minitest.dart';
 
 import 'event_helper.dart';
 
diff --git a/tests/lib_2/async/stream_single_to_multi_subscriber_test.dart b/tests/lib_2/async/stream_single_to_multi_subscriber_test.dart
index 9cedef0..e422a8d 100644
--- a/tests/lib_2/async/stream_single_to_multi_subscriber_test.dart
+++ b/tests/lib_2/async/stream_single_to_multi_subscriber_test.dart
@@ -8,7 +8,7 @@
 import 'dart:async';
 
 import 'package:expect/expect.dart';
-import 'package:expect/async_minitest.dart';
+import 'package:async_helper/async_minitest.dart';
 
 import 'event_helper.dart';
 
diff --git a/tests/lib_2/async/stream_state_helper.dart b/tests/lib_2/async/stream_state_helper.dart
index 2bd412f..6178495 100644
--- a/tests/lib_2/async/stream_state_helper.dart
+++ b/tests/lib_2/async/stream_state_helper.dart
@@ -7,7 +7,7 @@
 import 'dart:async';
 import 'dart:collection';
 
-import 'package:expect/async_minitest.dart';
+import 'package:async_helper/async_minitest.dart';
 
 class SubscriptionProtocolTest {
   final StreamProtocolTest _streamTest;
diff --git a/tests/lib_2/async/stream_state_nonzero_timer_test.dart b/tests/lib_2/async/stream_state_nonzero_timer_test.dart
index ff6cebb..8c7c115 100644
--- a/tests/lib_2/async/stream_state_nonzero_timer_test.dart
+++ b/tests/lib_2/async/stream_state_nonzero_timer_test.dart
@@ -9,7 +9,7 @@
 
 import 'dart:async';
 
-import 'package:expect/async_minitest.dart';
+import 'package:async_helper/async_minitest.dart';
 
 import 'stream_state_helper.dart';
 
diff --git a/tests/lib_2/async/stream_state_test.dart b/tests/lib_2/async/stream_state_test.dart
index b56f37f..651f74d 100644
--- a/tests/lib_2/async/stream_state_test.dart
+++ b/tests/lib_2/async/stream_state_test.dart
@@ -5,7 +5,7 @@
 // Test the event/callback protocol of the stream implementations.
 library stream_state_test;
 
-import 'package:expect/async_minitest.dart';
+import 'package:async_helper/async_minitest.dart';
 
 import 'stream_state_helper.dart';
 
diff --git a/tests/lib_2/async/stream_subscription_as_future_test.dart b/tests/lib_2/async/stream_subscription_as_future_test.dart
index 5dc109d..5be5c91 100644
--- a/tests/lib_2/async/stream_subscription_as_future_test.dart
+++ b/tests/lib_2/async/stream_subscription_as_future_test.dart
@@ -8,7 +8,7 @@
 import 'dart:async';
 
 import 'package:expect/expect.dart';
-import 'package:expect/async_minitest.dart';
+import 'package:async_helper/async_minitest.dart';
 
 main() {
   test("subscription.asFuture success", () {
diff --git a/tests/lib_2/async/stream_subscription_cancel_test.dart b/tests/lib_2/async/stream_subscription_cancel_test.dart
index 6ad6b56..017bac5 100644
--- a/tests/lib_2/async/stream_subscription_cancel_test.dart
+++ b/tests/lib_2/async/stream_subscription_cancel_test.dart
@@ -7,7 +7,7 @@
 
 import 'dart:async';
 
-import 'package:expect/async_minitest.dart';
+import 'package:async_helper/async_minitest.dart';
 
 void main() {
   test('subscription.cancel', () {
diff --git a/tests/lib_2/async/stream_timeout_test.dart b/tests/lib_2/async/stream_timeout_test.dart
index 876a767..eb33ad2 100644
--- a/tests/lib_2/async/stream_timeout_test.dart
+++ b/tests/lib_2/async/stream_timeout_test.dart
@@ -4,7 +4,7 @@
 
 import 'dart:async';
 
-import 'package:expect/async_minitest.dart';
+import 'package:async_helper/async_minitest.dart';
 
 main() {
   const ms5 = const Duration(milliseconds: 5);
diff --git a/tests/lib_2/async/stream_transform_test.dart b/tests/lib_2/async/stream_transform_test.dart
index f08f037..e8ac505 100644
--- a/tests/lib_2/async/stream_transform_test.dart
+++ b/tests/lib_2/async/stream_transform_test.dart
@@ -7,7 +7,7 @@
 import 'dart:async';
 
 import 'package:expect/expect.dart';
-import 'package:expect/async_minitest.dart';
+import 'package:async_helper/async_minitest.dart';
 
 import 'event_helper.dart';
 
diff --git a/tests/lib_2/async/stream_transformation_broadcast_test.dart b/tests/lib_2/async/stream_transformation_broadcast_test.dart
index 3bb9667..839933f 100644
--- a/tests/lib_2/async/stream_transformation_broadcast_test.dart
+++ b/tests/lib_2/async/stream_transformation_broadcast_test.dart
@@ -8,7 +8,7 @@
 import 'dart:async';
 
 import 'package:expect/expect.dart';
-import 'package:expect/async_minitest.dart';
+import 'package:async_helper/async_minitest.dart';
 
 import 'event_helper.dart';
 
diff --git a/tests/lib_2/async/stream_transformer_test.dart b/tests/lib_2/async/stream_transformer_test.dart
index f1b850d..9f89f6a 100644
--- a/tests/lib_2/async/stream_transformer_test.dart
+++ b/tests/lib_2/async/stream_transformer_test.dart
@@ -48,6 +48,8 @@
   var stream = controller.stream;
   var transformed = stream.transform(transformer);
 
+  Expect.isFalse(transformed.isBroadcast);
+
   var handleData = (String _) => 499;
   var handleError = (e, st) => 42;
   var handleDone = () => 99;
@@ -85,4 +87,17 @@
   Expect.identical(_defaultData, subscription.handleData);
   Expect.identical(_defaultError, subscription.handleError);
   Expect.identical(handleDone, subscription.handleDone);
+
+  controller = new StreamController.broadcast(sync: true);
+  stream = controller.stream;
+  transformed = stream.transform(transformer);
+  Expect.isTrue(transformed.isBroadcast);
+  subscription =
+      transformed.listen(null, onDone: handleDone, cancelOnError: true);
+
+  Expect.identical(stream, subscription.stream);
+  Expect.equals(true, subscription.cancelOnError);
+  Expect.identical(_defaultData, subscription.handleData);
+  Expect.identical(_defaultError, subscription.handleError);
+  Expect.identical(handleDone, subscription.handleDone);
 }
diff --git a/tests/lib_2/async/timer_cancel1_test.dart b/tests/lib_2/async/timer_cancel1_test.dart
index 49fb647..1295e96 100644
--- a/tests/lib_2/async/timer_cancel1_test.dart
+++ b/tests/lib_2/async/timer_cancel1_test.dart
@@ -6,7 +6,7 @@
 
 import 'dart:async';
 
-import 'package:expect/async_minitest.dart';
+import 'package:async_helper/async_minitest.dart';
 
 main() {
   // Test that a timeout handler can cancel another.
diff --git a/tests/lib_2/async/timer_isActive_test.dart b/tests/lib_2/async/timer_isActive_test.dart
index 84f872f..b688b21 100644
--- a/tests/lib_2/async/timer_isActive_test.dart
+++ b/tests/lib_2/async/timer_isActive_test.dart
@@ -4,7 +4,7 @@
 
 import 'dart:async';
 
-import 'package:expect/async_minitest.dart';
+import 'package:async_helper/async_minitest.dart';
 
 main() {
   test("timer isActive test", () {
diff --git a/tests/lib_2/async/timer_test.dart b/tests/lib_2/async/timer_test.dart
index 052ff63..220ac05 100644
--- a/tests/lib_2/async/timer_test.dart
+++ b/tests/lib_2/async/timer_test.dart
@@ -6,7 +6,7 @@
 
 import 'dart:async';
 
-import 'package:expect/async_minitest.dart';
+import 'package:async_helper/async_minitest.dart';
 
 const int STARTTIMEOUT = 1050;
 const int DECREASE = 200;
diff --git a/tests/lib_2/html/websql_test.dart b/tests/lib_2/html/websql_test.dart
index 07f9ff2..4c1e34d 100644
--- a/tests/lib_2/html/websql_test.dart
+++ b/tests/lib_2/html/websql_test.dart
@@ -4,7 +4,7 @@
 import 'dart:html';
 import 'dart:web_sql';
 
-import 'package:expect/async_minitest.dart';
+import 'package:async_helper/async_minitest.dart';
 
 Future<SqlResultSet> createTable(
     SqlTransaction transaction, String tableName, String columnName) async {
diff --git a/tests/lib_2/isolate/deferred_in_isolate2_test.dart b/tests/lib_2/isolate/deferred_in_isolate2_test.dart
index 636eb73..47d401a 100644
--- a/tests/lib_2/isolate/deferred_in_isolate2_test.dart
+++ b/tests/lib_2/isolate/deferred_in_isolate2_test.dart
@@ -6,7 +6,7 @@
 
 import 'dart:isolate';
 import 'dart:async';
-import 'package:expect/async_minitest.dart';
+import 'package:async_helper/async_minitest.dart';
 
 import 'deferred_in_isolate2_lib.dart' deferred as lib;
 
diff --git a/tests/lib_2/isolate/spawn_uri_multi_test.dart b/tests/lib_2/isolate/spawn_uri_multi_test.dart
index c74c517..6076617 100644
--- a/tests/lib_2/isolate/spawn_uri_multi_test.dart
+++ b/tests/lib_2/isolate/spawn_uri_multi_test.dart
@@ -9,7 +9,7 @@
 library spawn_tests;
 
 import 'dart:isolate';
-import 'package:expect/async_minitest.dart';
+import 'package:async_helper/async_minitest.dart';
 
 /* Dummy import so multi-test copies the file.
 import 'spawn_uri_child_isolate.dart';
diff --git a/tests/lib_2/isolate/spawn_uri_nested_vm_test.dart b/tests/lib_2/isolate/spawn_uri_nested_vm_test.dart
index b13aff1..6d37e26 100644
--- a/tests/lib_2/isolate/spawn_uri_nested_vm_test.dart
+++ b/tests/lib_2/isolate/spawn_uri_nested_vm_test.dart
@@ -9,7 +9,7 @@
 library NestedSpawnUriLibrary;
 
 import 'dart:isolate';
-import 'package:expect/async_minitest.dart';
+import 'package:async_helper/async_minitest.dart';
 
 main() {
   test('isolate fromUri - nested send and reply', () {
diff --git a/tests/lib_2/isolate/spawn_uri_test.dart b/tests/lib_2/isolate/spawn_uri_test.dart
index a4d89c3..3f52215 100644
--- a/tests/lib_2/isolate/spawn_uri_test.dart
+++ b/tests/lib_2/isolate/spawn_uri_test.dart
@@ -9,7 +9,7 @@
 library spawn_tests;
 
 import 'dart:isolate';
-import 'package:expect/async_minitest.dart';
+import 'package:async_helper/async_minitest.dart';
 
 main() {
   test('isolate fromUri - send and reply', () async {
diff --git a/tests/lib_2/isolate/spawn_uri_vm_test.dart b/tests/lib_2/isolate/spawn_uri_vm_test.dart
index a61c2f9..6bc2e6e 100644
--- a/tests/lib_2/isolate/spawn_uri_vm_test.dart
+++ b/tests/lib_2/isolate/spawn_uri_vm_test.dart
@@ -9,7 +9,7 @@
 library spawn_tests;
 
 import 'dart:isolate';
-import 'package:expect/async_minitest.dart';
+import 'package:async_helper/async_minitest.dart';
 
 main() {
   test('isolate fromUri - send and reply', () {
diff --git a/tests/lib_2/isolate/timer_isolate_test.dart b/tests/lib_2/isolate/timer_isolate_test.dart
index cf7fb26..a34005a 100644
--- a/tests/lib_2/isolate/timer_isolate_test.dart
+++ b/tests/lib_2/isolate/timer_isolate_test.dart
@@ -6,7 +6,7 @@
 
 import 'dart:isolate';
 import 'dart:async';
-import 'package:expect/async_minitest.dart';
+import 'package:async_helper/async_minitest.dart';
 
 const Duration TIMEOUT = const Duration(milliseconds: 100);
 
diff --git a/tests/lib_2/lib_2.status b/tests/lib_2/lib_2.status
index 3a5dc80..a3df3b7 100644
--- a/tests/lib_2/lib_2.status
+++ b/tests/lib_2/lib_2.status
@@ -149,24 +149,11 @@
 [ $jscl ]
 isolate/spawn_uri_multi_test/none: RuntimeError # Issue 13544
 
-[ !$strong ]
-async/future_test: SkipByDesign # Uses Dart 2 syntax.
-async/stream_first_where_test/badType: MissingCompileTimeError
-async/stream_from_iterable_test: SkipByDesign # Uses Dart 2 syntax.
-async/stream_last_where_test/badType: MissingCompileTimeError
-mirrors/redirecting_factory_different_type_test/02: MissingCompileTimeError
-
 [ $builder_tag == mac10_7 && $runtime == safari ]
 typed_data/setRange_2_test: Fail # Safari doesn't fully implement spec for TypedArray.set
 typed_data/setRange_3_test: Fail # Safari doesn't fully implement spec for TypedArray.set
 typed_data/setRange_4_test: Fail # Safari doesn't fully implement spec for TypedArray.set
 
-[ $compiler != dart2analyzer && $compiler != fasta && !$strong ]
-async/future_or_type_test: Fail # Strong mode implements FutureOr, non-strong treats it as dynamic.
-
-[ $compiler != dartdevc && $checked && !$strong ]
-async/future_or_only_in_async_test/00: MissingCompileTimeError
-
 [ $compiler == dartk && $system == macos && $hot_reload && ($arch == simdbc || $arch == simdbc64) ]
 isolate/unresolved_ports_test: Pass, RuntimeError #  Issue 35410
 
@@ -198,18 +185,6 @@
 html/request_animation_frame_test: Skip # Times out. Issue 22167
 html/transition_event_test: Skip # Times out. Issue 22167
 
-[ !$checked && !$strong ]
-async/future_or_only_in_async_test/00: MissingCompileTimeError
-async/multiple_timer_test: Pass, Fail # Timing related
-isolate/issue_24243_parent_isolate_test: SkipByDesign # Requires type checks.
-
-[ !$fasta && !$strong ]
-isolate/isolate_import_test/01: MissingCompileTimeError
-mirrors/top_level_accessors_test/01: MissingCompileTimeError
-typed_data/float32x4_static_test: MissingCompileTimeError
-typed_data/int32x4_static_test/01: MissingCompileTimeError
-typed_data/int32x4_static_test/02: MissingCompileTimeError
-
 [ !$preview_dart_2 && ($runtime == dart_precompiled || $runtime == vm) ]
 *: SkipByDesign # Deprecating all Dart1 modes of execution
 
diff --git a/tests/lib_2/lib_2_dart2js.status b/tests/lib_2/lib_2_dart2js.status
index 705ddba..6cd2ce3 100644
--- a/tests/lib_2/lib_2_dart2js.status
+++ b/tests/lib_2/lib_2_dart2js.status
@@ -3,6 +3,10 @@
 # BSD-style license that can be found in the LICENSE file.
 
 [ $compiler == dart2js ]
+async/future_or_type_test: RuntimeError
+async/slow_consumer2_test: RuntimeError
+async/stream_distinct_test: RuntimeError
+collection/list_test: RuntimeError
 convert/chunked_conversion_utf88_test: Slow
 convert/utf85_test: Slow
 developer/timeline_test: Skip # Not supported
@@ -16,6 +20,7 @@
 html/custom/mirrors_2_test: Skip # mirrors not supported, delete this test.
 html/custom/mirrors_test: Skip # mirrors not supported, delete this test.
 html/custom_elements_test: Slow # Issue 26789
+html/element_classes_test: RuntimeError
 html/isolates_test: SkipByDesign
 html/mirrors_js_typed_interop_test: Skip # mirrors not supported, delete this test.
 html/worker_api_test: SkipByDesign
@@ -36,6 +41,7 @@
 html/element_types_keygen_test: RuntimeError # Issue 29055
 html/file_sample_test: Pass, RuntimeError
 html/fileapi_entry_test: Pass, RuntimeError
+html/interactive_media_test: RuntimeError
 html/media_stream_test: RuntimeError # Please triage.
 html/speechrecognition_test: RuntimeError # Please triage.
 
@@ -57,9 +63,6 @@
 html/js_typed_interop_rename_static_test: RuntimeError
 html/worker_test/functional: RuntimeError # Issue 32261
 
-[ $compiler == dart2js && $runtime == chrome && $strong ]
-html/interactive_media_test: RuntimeError
-
 [ $compiler == dart2js && $runtime == chromeOnAndroid ]
 html/audiobuffersourcenode_test/supported: Fail # TODO(dart2js-team): Please triage this failure.
 html/audiocontext_test/supported: RuntimeError # TODO(dart2js-team): Please triage this failure.
@@ -316,9 +319,6 @@
 html/input_element_attributes_test: RuntimeError
 html/js_extend_class_test: RuntimeError
 
-[ $compiler == dart2js && $runtime != d8 && !$strong ]
-html/js_dart_functions_test: RuntimeError # does not implement Dart 2 implicit `.call` tearoff
-
 [ $compiler == dart2js && $runtime == ff ]
 async/slow_consumer2_test: SkipSlow # Times out. Issue 22050
 convert/streamed_conversion_json_utf8_decode_test: SkipSlow # Times out. Issue 22050
@@ -340,6 +340,7 @@
 html/fileapi_supported_test: Skip # FileSystem not supported on FireFox.
 html/fileapi_supported_throws_test: Skip # FileSystem not supported on FireFox.
 html/fontface_test: Fail # Fontface not supported on ff
+html/gamepad_test: RuntimeError
 html/history_test/history: Skip # Issue 22050
 html/input_element_datetime_test: Fail
 html/input_element_month_test: Fail
@@ -354,10 +355,6 @@
 html/text_event_test: Fail # Issue 17893
 html/webgl_1_test: Pass, Fail # Issue 8219
 
-[ $compiler == dart2js && $runtime == ff && $strong ]
-html/gamepad_test: RuntimeError
-html/interactive_media_test: RuntimeError
-
 [ $compiler == dart2js && $runtime == ie11 ]
 html/element_types_content_test: RuntimeError # Issue 29922
 html/element_types_datalist_test: RuntimeError # Issue 29922
@@ -428,7 +425,12 @@
 
 [ $compiler == dart2js && $runtime == safari ]
 html/audiobuffersourcenode_test: RuntimeError
+html/audiobuffersourcenode_test: Pass, RuntimeError
 html/callback_list_test: SkipByDesign # FileSystem not supported in Safari.
+html/canvasrenderingcontext2d_test/arc: Pass, RuntimeError
+html/canvasrenderingcontext2d_test/drawImage_canvas_element: Pass, RuntimeError
+html/canvasrenderingcontext2d_test/drawImage_image_element: Pass, RuntimeError
+html/canvasrenderingcontext2d_test/fillText: Pass, RuntimeError
 html/css_test/functional/functional: RuntimeError # Issue 32576
 html/custom/attribute_changed_callback_test: RuntimeError, Timeout
 html/custom/constructor_calls_created_synchronously_test: Pass, Timeout
@@ -439,26 +441,10 @@
 html/element_types_shadow_test: RuntimeError # Issue 29922
 html/file_sample_test: Skip # FileSystem not supported on Safari.
 html/fileapi_supported_throws_test: Skip # FileSystem not supported on Safari
-html/storage_promise_test: RuntimeError # Not supported on Safari
-html/xhr_test: RuntimeError
-
-[ $compiler == dart2js && $runtime == safari && $strong ]
-html/audiobuffersourcenode_test: Pass, RuntimeError
-html/canvasrenderingcontext2d_test/arc: Pass, RuntimeError
-html/canvasrenderingcontext2d_test/drawImage_canvas_element: Pass, RuntimeError
-html/canvasrenderingcontext2d_test/drawImage_image_element: Pass, RuntimeError
-html/canvasrenderingcontext2d_test/fillText: Pass, RuntimeError
 html/interactive_media_test: SkipSlow
 html/notification_test: Pass, RuntimeError # Safari doesn't let us access the fields of the Notification to verify them.
-
-[ $compiler == dart2js && $runtime == safari && !$strong ]
-convert/json_test: Fail # https://bugs.webkit.org/show_bug.cgi?id=134920
-html/fontface_loaded_test: RuntimeError # FontFace polyfill?
-html/fontface_test: Fail # FontFace polyfill?
-html/notification_test: Fail # Safari doesn't let us access the fields of the Notification to verify them.
-
-[ $compiler == dart2js && $runtime != safari && !$strong ]
-html/element_classes_test: RuntimeError
+html/storage_promise_test: RuntimeError # Not supported on Safari
+html/xhr_test: RuntimeError
 
 [ $compiler == dart2js && $system == linux ]
 html/interactive_geolocation_test: Skip # Requires allowing geo location.
@@ -468,20 +454,18 @@
 
 [ $compiler == dart2js && $browser ]
 html/custom/created_callback_test: RuntimeError
+html/element_classes_svg_test: RuntimeError
+html/js_array_test: RuntimeError
 html/js_typed_interop_lazy_test/01: RuntimeError
 html/notification_permission_test: Timeout, Pass # Issue 32002
 html/private_extension_member_test: RuntimeError
+html/typed_arrays_range_checks_test: RuntimeError
 js/null_test: RuntimeError # Issue 30652
 
 [ $compiler == dart2js && $browser && $csp ]
 html/custom/element_upgrade_test: Fail # Issue 17298
 html/custom/js_custom_test: Fail # Issue 14643
 
-[ $compiler == dart2js && $browser && $strong ]
-html/element_classes_svg_test: RuntimeError
-html/js_array_test: RuntimeError
-html/typed_arrays_range_checks_test: RuntimeError
-
 [ $compiler == dart2js && $checked ]
 async/stream_listen_zone_test: RuntimeError
 convert/utf85_test: Pass, Slow # Issue 12029.
@@ -671,8 +655,6 @@
 [ $compiler == dart2js && $ie ]
 html/fontface_loaded_test: RuntimeError # FontFace polyfill?
 html/fontface_test: Fail # Fontface not supported on ie
-
-[ $compiler == dart2js && $ie && $strong ]
 html/interactive_media_test: RuntimeError
 
 [ $compiler == dart2js && $minified ]
@@ -752,17 +734,6 @@
 html/typed_arrays_1_test/supported: RuntimeError
 html/webgl_1_test: Crash # NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.
 
-[ $compiler == dart2js && $strong ]
-async/future_or_type_test: RuntimeError
-async/slow_consumer2_test: RuntimeError
-async/stream_distinct_test: RuntimeError
-collection/list_test: RuntimeError
-html/element_classes_test: RuntimeError
-
-[ $compiler == dart2js && !$strong ]
-html/custom/element_upgrade_failure_test: MissingCompileTimeError
-html/element_classes_svg_test: RuntimeError # Expected runtime type check only in strong mode.
-
 [ $compiler == dart2js && ($runtime == chrome || $runtime == ff) ]
 async/slow_consumer2_test: SkipSlow # Times out. Issue 22050
 convert/streamed_conversion_json_utf8_decode_test: SkipSlow # Times out. Issue 22050
diff --git a/tests/lib_2/lib_2_kernel.status b/tests/lib_2/lib_2_kernel.status
index b582fa7..46fe6b7 100644
--- a/tests/lib_2/lib_2_kernel.status
+++ b/tests/lib_2/lib_2_kernel.status
@@ -17,12 +17,29 @@
 isolate/ping_pause_test: Skip # Timeout
 
 [ $compiler == dartkb ]
+convert/streamed_conversion_json_utf8_decode_test: Pass, Timeout # Please triage.
+isolate/isolate_complex_messages_test: Pass, Crash # runtime/vm/object.cc: 17395: error: expected: type_arguments.IsNull() || type_arguments.IsCanonical()
+isolate/mandel_isolate_test: Pass, Timeout # Please triage.
+isolate/spawn_uri_exported_main_test: Pass, RuntimeError # Please triage: Expect.fail('Isolate was not spawned successfully.')
 mirrors/*: Skip # Mirrors are not yet supported in bytecode modes.
+mirrors/invocation_fuzz_test/emptyarray: Skip # Times out, issue 32232
+mirrors/invocation_fuzz_test/false: Skip # Times out, issue 32232
+mirrors/library_uri_io_test: RuntimeError # Platform.script points to dill file.
+mirrors/method_mirror_location_test: Crash # runtime/lib/mirrors.cc: 1634: error: expected: token_pos != TokenPosition::kNoSource
 
 [ $compiler == fasta ]
 html/*: Skip # TODO(ahe): Make dart:html available.
 isolate/browser/*: Skip # TODO(ahe): Make dart:html available.
+isolate/isolate_stress_test: CompileTimeError
 js/*: Skip # TODO(ahe): Make dart:js available.
+mirrors/deferred_type_test: CompileTimeError
+mirrors/metadata_allowed_values_test/02: MissingCompileTimeError
+mirrors/metadata_allowed_values_test/27: MissingCompileTimeError
+mirrors/metadata_constructor_arguments_test/04: MissingCompileTimeError
+mirrors/mirrors_nsm_mismatch_test: CompileTimeError
+mirrors/mirrors_nsm_test/dart2js: CompileTimeError
+mirrors/mirrors_nsm_test/none: CompileTimeError
+mirrors/native_class_test: CompileTimeError
 
 [ $fasta ]
 async/future_or_type_test: CompileTimeError # Issue 34626
@@ -32,19 +49,19 @@
 mirrors/redirecting_factory_test/01: CompileTimeError # Issue 34714
 mirrors/redirecting_factory_test/none: CompileTimeError # Issue 34714
 
-[ $arch == simdbc64 && $mode == debug && $runtime == vm && $strong && ($compiler == dartk || $compiler == dartkb) ]
+[ $arch == simdbc64 && $mode == debug && $runtime == vm && ($compiler == dartk || $compiler == dartkb) ]
 isolate/isolate_complex_messages_test: Crash # http://dartbug.com/33128
 
 [ $arch == simdbc64 && $hot_reload_rollback ]
 convert/streamed_conversion_json_utf8_decode_test: SkipSlow # Uses --verify_before_gc --verify_after_gc --old_gen_growth_rate=1 flags
 
-[ $arch == simdbc64 && $strong && ($compiler == dartk || $compiler == dartkb) ]
+[ $arch == simdbc64 && ($compiler == dartk || $compiler == dartkb) ]
 isolate/issue_24243_parent_isolate_test: RuntimeError # dartbug.com/35373
 
 [ $arch == x64 && $builder_tag == asan && $compiler == dartk ]
 mirrors/dynamic_load_test: Fail # Memory leak (issue 34724)
 
-[ $arch == x64 && $mode == debug && $runtime == vm && $strong && ($compiler == dartk || $compiler == dartkb) ]
+[ $arch == x64 && $mode == debug && $runtime == vm && ($compiler == dartk || $compiler == dartkb) ]
 mirrors/invocation_fuzz_test: Skip # Because it times out, issue 29439.
 
 [ $arch == x64 && ($hot_reload || $hot_reload_rollback) ]
@@ -65,28 +82,11 @@
 [ $compiler == app_jitk && ($mode == product || $mode == release) ]
 isolate/spawn_uri_nested_vm_test: Skip # Timeout, Issue 33385
 
-[ $compiler != dart2js && $fasta && !$strong ]
-isolate/browser/compute_this_script_browser_test: CompileTimeError
-isolate/browser/package_resolve_browser_hook2_test: CompileTimeError
-isolate/browser/package_resolve_browser_hook_test: CompileTimeError
-isolate/browser/package_resolve_browser_test: CompileTimeError
-
-# The failures below still need to be investigated and possibly fixed, or marked as skipped.
-[ $compiler == dartkb && $strong ]
-convert/streamed_conversion_json_utf8_decode_test: Pass, Timeout # Please triage.
-isolate/isolate_complex_messages_test: Pass, Crash # runtime/vm/object.cc: 17395: error: expected: type_arguments.IsNull() || type_arguments.IsCanonical()
-isolate/mandel_isolate_test: Pass, Timeout # Please triage.
-isolate/spawn_uri_exported_main_test: Pass, RuntimeError # Please triage: Expect.fail('Isolate was not spawned successfully.')
-mirrors/invocation_fuzz_test/emptyarray: Skip # Times out, issue 32232
-mirrors/invocation_fuzz_test/false: Skip # Times out, issue 32232
-mirrors/library_uri_io_test: RuntimeError # Platform.script points to dill file.
-mirrors/method_mirror_location_test: Crash # runtime/lib/mirrors.cc: 1634: error: expected: token_pos != TokenPosition::kNoSource
-
-[ $compiler == dartkp && $mode == debug && $runtime == dart_precompiled && $strong ]
+[ $compiler == dartkp && $mode == debug && $runtime == dart_precompiled ]
 isolate/static_function_test: Skip # Flaky (https://github.com/dart-lang/sdk/issues/30063).
 
 # ===== dartkp + dart_precompiled status lines =====
-[ $compiler == dartkp && $runtime == dart_precompiled && $strong ]
+[ $compiler == dartkp && $runtime == dart_precompiled ]
 async/slow_consumer2_test: RuntimeError # Issue 31402 (Invocation arguments)
 async/stream_distinct_test: RuntimeError
 async/timer_not_available_test: RuntimeError
@@ -98,32 +98,18 @@
 isolate/spawn_uri_nested_vm_test: Pass, Timeout
 mirrors/*: SkipByDesign # Mirrors are not supported in AOT mode.
 
-[ $compiler == dartkp && !$strong ]
-*: SkipByDesign
-
-[ $compiler == fasta && $strong ]
-isolate/isolate_stress_test: CompileTimeError
-mirrors/deferred_type_test: CompileTimeError
-mirrors/metadata_allowed_values_test/02: MissingCompileTimeError
-mirrors/metadata_allowed_values_test/27: MissingCompileTimeError
-mirrors/metadata_constructor_arguments_test/04: MissingCompileTimeError
-mirrors/mirrors_nsm_mismatch_test: CompileTimeError
-mirrors/mirrors_nsm_test/dart2js: CompileTimeError
-mirrors/mirrors_nsm_test/none: CompileTimeError
-mirrors/native_class_test: CompileTimeError
-
-[ $mode == debug && $runtime == vm && $strong && ($compiler == dartk || $compiler == dartkb) ]
+[ $mode == debug && $runtime == vm && ($compiler == dartk || $compiler == dartkb) ]
 mirrors/other_declarations_location_test: Crash # Issue 33325 (assertion error, TypeParameter not having position).
 
 [ $mode == debug && $hot_reload_rollback && ($compiler == dartk || $compiler == dartkb) ]
 isolate/message3_test/constList_identical: Skip # Timeout
 
-[ $runtime == vm && $checked && $strong && ($compiler == dartk || $compiler == dartkb) ]
+[ $runtime == vm && $checked && ($compiler == dartk || $compiler == dartkb) ]
 mirrors/redirecting_factory_different_type_test/none: RuntimeError # Issue 28424
 mirrors/reflected_type_generics_test/02: Pass
 
 # ===== dartk + vm status lines =====
-[ $runtime == vm && $strong && ($compiler == dartk || $compiler == dartkb) ]
+[ $runtime == vm && ($compiler == dartk || $compiler == dartkb) ]
 async/slow_consumer2_test: CompileTimeError # Issue 31402 (Invocation arguments)
 async/timer_not_available_test: RuntimeError
 html/*: SkipByDesign # dart:html not supported on VM.
@@ -214,25 +200,6 @@
 mirrors/typedef_test: RuntimeError
 mirrors/typevariable_mirror_metadata_test: RuntimeError
 
-[ $fasta && !$strong ]
-isolate/isolate_import_test/01: MissingCompileTimeError
-isolate/isolate_stress_test: CompileTimeError
-mirrors/generics_test/01: MissingCompileTimeError
-mirrors/metadata_allowed_values_test/02: MissingCompileTimeError
-mirrors/metadata_allowed_values_test/27: MissingCompileTimeError
-mirrors/metadata_constructor_arguments_test/04: MissingCompileTimeError
-mirrors/native_class_test: CompileTimeError
-mirrors/redirecting_factory_different_type_test/01: MissingCompileTimeError
-mirrors/reflect_class_test/01: MissingCompileTimeError
-mirrors/reflect_class_test/02: MissingCompileTimeError
-mirrors/reflected_type_classes_test/01: MissingCompileTimeError
-mirrors/reflected_type_test/01: MissingCompileTimeError
-mirrors/regress_16321_test/01: MissingCompileTimeError
-mirrors/top_level_accessors_test/01: MissingCompileTimeError
-typed_data/float32x4_static_test: MissingCompileTimeError
-typed_data/int32x4_static_test/01: MissingCompileTimeError
-typed_data/int32x4_static_test/02: MissingCompileTimeError
-
 [ $hot_reload_rollback && ($compiler == dartk || $compiler == dartkb) ]
 isolate/illegal_msg_function_test: Skip # Timeout
 isolate/pause_test: Skip # Timeout
@@ -240,34 +207,11 @@
 # Enabling of dartk for sim{arm,arm64,dbc64} revealed these test failures, which
 # are to be triaged.  Isolate tests are skipped on purpose due to the usage of
 # batch mode.
-[ $strong && ($arch == simarm || $arch == simarm64 || $arch == simdbc64) && ($compiler == dartk || $compiler == dartkb) ]
+[ ($arch == simarm || $arch == simarm64 || $arch == simdbc64) && ($compiler == dartk || $compiler == dartkb) ]
 isolate/mandel_isolate_test: Pass, Timeout
 isolate/nested_spawn2_test: Pass, RuntimeError # RuntimeError caused by timeout
 mirrors/library_uri_io_test: RuntimeError # Please triage.
 
-[ $strong && ($compiler == dartk || $compiler == dartkb) ]
-async/slow_consumer2_test: RuntimeError # Issue 31402 (Invocation arguments)
-async/stream_distinct_test: RuntimeError
-isolate/ping_pause_test: RuntimeError
-isolate/request_reply_test: Pass, Timeout
-isolate/stacktrace_message_test: RuntimeError
-mirrors/constructor_optional_args_test: RuntimeError
-mirrors/constructors_test: RuntimeError
-mirrors/fake_function_with_call_test: RuntimeError
-mirrors/instance_members_easier_test: RuntimeError
-mirrors/instance_members_test: RuntimeError
-mirrors/instance_members_with_override_test: RuntimeError
-mirrors/invoke_closurization2_test: RuntimeError
-mirrors/invoke_throws_test: RuntimeError
-mirrors/mixin_members_test: RuntimeError
-mirrors/operator_test: RuntimeError
-mirrors/redirecting_factory_different_type_test/none: RuntimeError
-mirrors/redirecting_factory_reflection_test: RuntimeError
-
-# ===== Skip dartk and darkp in !$strong mode ====
-[ !$strong && ($compiler == dartk || $compiler == dartkb) ]
-*: SkipByDesign
-
 [ ($compiler == dartk || $compiler == dartkb) && ($hot_reload || $hot_reload_rollback) ]
 isolate/mandel_isolate_test: Pass, Timeout, RuntimeError # Test can time out which results in runtime error
 isolate/message4_test: Pass, Timeout, Crash # Timeout and sporadic crash (issue 33824)
@@ -281,7 +225,24 @@
 js/*: SkipByDesign
 
 [ $compiler == dartk || $compiler == dartkb ]
+async/slow_consumer2_test: RuntimeError # Issue 31402 (Invocation arguments)
+async/stream_distinct_test: RuntimeError
+isolate/ping_pause_test: RuntimeError
 isolate/ping_pause_test: Skip # Issues 32137 and 32138
+isolate/request_reply_test: Pass, Timeout
+isolate/stacktrace_message_test: RuntimeError
+mirrors/constructor_optional_args_test: RuntimeError
+mirrors/constructors_test: RuntimeError
+mirrors/fake_function_with_call_test: RuntimeError
+mirrors/instance_members_easier_test: RuntimeError
+mirrors/instance_members_test: RuntimeError
+mirrors/instance_members_with_override_test: RuntimeError
+mirrors/invoke_closurization2_test: RuntimeError
+mirrors/invoke_throws_test: RuntimeError
+mirrors/mixin_members_test: RuntimeError
+mirrors/operator_test: RuntimeError
+mirrors/redirecting_factory_different_type_test/none: RuntimeError
+mirrors/redirecting_factory_reflection_test: RuntimeError
 
 [ $hot_reload || $hot_reload_rollback ]
 isolate/issue_6610_test: Skip # Sources are looked up on every reload request.
diff --git a/tests/lib_2/lib_2_vm.status b/tests/lib_2/lib_2_vm.status
index a652e636..869e7c8 100644
--- a/tests/lib_2/lib_2_vm.status
+++ b/tests/lib_2/lib_2_vm.status
@@ -18,6 +18,7 @@
 convert/utf85_test: Skip # Pass, Slow Issue 20111.
 
 [ $compiler != app_jitk && $compiler != dartk && $compiler != dartkb && $runtime == vm ]
+async/future_or_only_in_async_test/00: MissingCompileTimeError
 convert/streamed_conversion_json_utf8_decode_test: Pass, Slow # Infrequent timeouts.
 html/*: SkipByDesign # dart:html not supported on VM.
 js/datetime_roundtrip_test: CompileTimeError
@@ -40,24 +41,6 @@
 [ $compiler != app_jitk && $compiler != dartk && $compiler != dartkb && $runtime == vm && !$checked ]
 mirrors/inference_and_no_such_method_test: RuntimeError
 
-[ $compiler != app_jitk && $compiler != dartk && $compiler != dartkb && $runtime == vm && $strong ]
-async/future_or_only_in_async_test/00: MissingCompileTimeError
-
-[ $compiler != app_jitk && $compiler != dartk && $compiler != dartkb && $runtime == vm && !$strong ]
-mirrors/redirecting_factory_test/02: MissingCompileTimeError
-mirrors/redirecting_factory_test/03: MissingCompileTimeError
-mirrors/redirecting_factory_test/04: MissingCompileTimeError
-
-[ $compiler != dartk && $compiler != dartkb && $runtime == vm && !$strong ]
-mirrors/reflect_class_test/01: MissingCompileTimeError
-mirrors/reflect_class_test/02: MissingCompileTimeError
-mirrors/reflected_type_classes_test/01: MissingCompileTimeError
-mirrors/reflected_type_classes_test/02: MissingCompileTimeError
-mirrors/reflected_type_classes_test/03: MissingCompileTimeError
-mirrors/reflected_type_test/01: MissingCompileTimeError
-mirrors/reflected_type_test/02: MissingCompileTimeError
-mirrors/reflected_type_test/03: MissingCompileTimeError
-
 [ $runtime == vm && $system == fuchsia ]
 async/first_regression_test: RuntimeError
 async/future_timeout_test: RuntimeError
@@ -96,9 +79,6 @@
 mirrors/library_uri_io_test: RuntimeError
 mirrors/library_uri_package_test: RuntimeError
 
-[ $runtime == vm && !$checked && !$strong ]
-mirrors/regress_16321_test/01: MissingCompileTimeError
-
 [ $runtime == vm && $no_preview_dart_2 ]
 async/async_no_await_zones_test: RuntimeError # not supported in Dart 1 mode.
 
diff --git a/tests/lib_2/mirrors/library_uri_io_test.dart b/tests/lib_2/mirrors/library_uri_io_test.dart
index 74553b4..e072a83 100644
--- a/tests/lib_2/mirrors/library_uri_io_test.dart
+++ b/tests/lib_2/mirrors/library_uri_io_test.dart
@@ -9,7 +9,7 @@
 import 'dart:io';
 import 'dart:mirrors';
 
-import 'package:expect/async_minitest.dart';
+import 'package:async_helper/async_minitest.dart';
 
 class Class {}
 
diff --git a/tests/lib_2/mirrors/library_uri_package_test.dart b/tests/lib_2/mirrors/library_uri_package_test.dart
index f9db81d..a8be56d 100644
--- a/tests/lib_2/mirrors/library_uri_package_test.dart
+++ b/tests/lib_2/mirrors/library_uri_package_test.dart
@@ -8,7 +8,7 @@
 
 import 'dart:mirrors';
 import 'package:args/args.dart';
-import 'package:expect/async_minitest.dart';
+import 'package:async_helper/async_minitest.dart';
 
 testLibraryUri(var value, Uri expectedUri) {
   var valueMirror = reflect(value);
diff --git a/tests/standalone_2/standalone_2.status b/tests/standalone_2/standalone_2.status
index 74d303c..10647f5 100644
--- a/tests/standalone_2/standalone_2.status
+++ b/tests/standalone_2/standalone_2.status
@@ -68,14 +68,11 @@
 io/wait_for_event_zone_test: SkipByDesign # Uses mirrors.
 io/wait_for_test: SkipByDesign # Uses mirrors.
 
-[ !$strong ]
-float_array_static_test: MissingCompileTimeError
-
 [ $builder_tag == swarming && $system == macos ]
 io/*: Skip # Issue 30618
 
 # All static_tests have expected compile-time errors.
-[ $compiler != app_jitk && $compiler != dart2analyzer && $compiler != dartdevc && $compiler != dartk && $compiler != dartkb && $compiler != dartkp && $runtime != none && $strong ]
+[ $compiler != app_jitk && $compiler != dart2analyzer && $compiler != dartdevc && $compiler != dartk && $compiler != dartkb && $compiler != dartkp && $runtime != none ]
 float_array_static_test: MissingCompileTimeError
 
 [ $compiler == none && $runtime == vm && $system == fuchsia ]
@@ -91,9 +88,6 @@
 [ $mode == release && $runtime == vm && $system == macos ]
 io/named_pipe_script_test: Pass, RuntimeError # Issue 28737
 
-[ $runtime == none && !$strong ]
-io/process_exit_negative_test: Fail, OK # Must be run to exit with non-zero exit code.
-
 [ $runtime == vm && $system == linux ]
 io/http_basic_test: Pass, Slow, Timeout # Issue 28046, These tests might be slow on an opt counter threshold bot. They also time out on the bot occasionally => flaky test issue 28046
 io/http_launch_test: Pass, Slow, Timeout # Issue 28046, These tests might be slow on an opt counter threshold bot. They also time out on the bot occasionally => flaky test issue 28046
@@ -108,7 +102,13 @@
 [ !$preview_dart_2 && ($runtime == dart_precompiled || $runtime == vm) ]
 *: SkipByDesign # Deprecating all Dart1 modes of execution
 
-[ $strong && ($compiler == dartk || $compiler == dartkb || $compiler == dartkp) ]
+[ $arch == arm || $arch == arm64 || $runtime != vm || $mode == debug && $system == windows ]
+fragmentation_test: Skip
+
+[ $compiler == dart2js || $compiler == dartdevc || $compiler == dartdevk ]
+*: SkipByDesign
+
+[ $compiler == dartk || $compiler == dartkb || $compiler == dartkp ]
 io/file_error_test: RuntimeError
 io/file_test: RuntimeError
 io/http_auth_digest_test: RuntimeError
@@ -125,37 +125,6 @@
 io/web_socket_protocol_processor_test: CompileTimeError
 io/zlib_test: RuntimeError
 
-[ !$strong && ($compiler == dartk || $compiler == dartkb || $compiler == dartkp) ]
-io/compile_all_test: Skip # Crashes
-io/http_client_connect_test: Skip # Flaky.
-io/http_content_length_test: Skip # Flaky.
-io/http_proxy_test: Skip # Flaky.
-io/http_response_deadline_test: Skip # Flaky.
-io/http_reuse_server_port_test: Skip # Flaky.
-io/http_server_close_response_after_error_test: Skip # Flaky.
-io/http_shutdown_test: Skip # Flaky.
-io/raw_secure_server_closing_test: Skip # Flaky.
-io/secure_multiple_client_server_test: Skip # Flaky.
-io/secure_server_closing_test: Skip # Flaky.
-io/secure_server_socket_test: Skip # Flaky.
-io/web_socket_error_test: Skip # Flaky
-io/web_socket_ping_test: Skip # Flaky.
-io/web_socket_test: Skip # Flaky.
-map_insert_remove_oom_test: Skip # Heap limit too low.
-no_support_debugger_test: Skip # kernel-service snapshot not compatible with flag disabled
-package/package1_test: CompileTimeError
-package/package_test: CompileTimeError
-package/scenarios/invalid/invalid_utf8_test: CompileTimeError
-package/scenarios/invalid/non_existent_packages_file_test: CompileTimeError
-package/scenarios/invalid/same_package_twice_test: CompileTimeError
-regress_29350_test: MissingCompileTimeError
-
-[ $arch == arm || $arch == arm64 || $runtime != vm || $mode == debug && $system == windows ]
-fragmentation_test: Skip
-
-[ $compiler == dart2js || $compiler == dartdevc || $compiler == dartdevk ]
-*: SkipByDesign
-
 [ $mode == product || $runtime == dart_precompiled ]
 no_assert_test: SkipByDesign
 
diff --git a/tests/standalone_2/standalone_2_kernel.status b/tests/standalone_2/standalone_2_kernel.status
index 5bece55..69cdf98 100644
--- a/tests/standalone_2/standalone_2_kernel.status
+++ b/tests/standalone_2/standalone_2_kernel.status
@@ -35,19 +35,36 @@
 io/zlib_test: RuntimeError
 
 [ $compiler == dartkb ]
+io/dart_std_io_pipe_test: Pass, Timeout # Please triage
+io/platform_resolved_executable_test/00: RuntimeError # Reruns the same script (dill file without AST) without passing --enable-interpreter or --use-bytecode-compiler.
+io/platform_resolved_executable_test/01: RuntimeError # Reruns the same script (dill file without AST) without passing --enable-interpreter or --use-bytecode-compiler.
+io/platform_resolved_executable_test/02: RuntimeError # Reruns the same script (dill file without AST) without passing --enable-interpreter or --use-bytecode-compiler.
 io/platform_resolved_executable_test/03: RuntimeError
 io/platform_resolved_executable_test/04: RuntimeError
+io/platform_resolved_executable_test/05: RuntimeError # Reruns the same script (dill file without AST) without passing --enable-interpreter or --use-bytecode-compiler.
+io/platform_test: RuntimeError # Platform.script points to dill file.
+io/test_extension_fail_test: RuntimeError # Platform.script points to dill file.
+io/test_extension_test: RuntimeError # Platform.script points to dill file.
+no_lazy_dispatchers_test: SkipByDesign # KBC interpreter doesn't support --no_lazy_dispatchers
 
 [ $compiler == dartkp ]
 io/arguments_test: Fail # Test harness passes runtime arguments to the compiler
 io/test_runner_test: SkipByDesign # Is not relevant for AOT.
 
+[ $compiler == fasta ]
+io/http_cookie_date_test: CompileTimeError
+io/http_headers_test: CompileTimeError
+io/http_parser_test: CompileTimeError
+io/secure_socket_argument_test: CompileTimeError
+io/web_socket_protocol_processor_test: CompileTimeError
+
 [ $system == android ]
 entrypoints_verification_test: Skip # Requires shared objects which the test script doesn't "adb push".
 
 [ $fasta ]
 deferred_transitive_import_error_test: CompileTimeError
 package/package1_test: CompileTimeError
+package/package_isolate_test: CompileTimeError
 package/package_test: CompileTimeError
 package/scenarios/invalid/invalid_utf8_test: CompileTimeError
 package/scenarios/invalid/non_existent_packages_file_test: CompileTimeError
@@ -56,10 +73,10 @@
 [ $arch == ia32 && $builder_tag == optimization_counter_threshold ]
 io/file_lock_test: SkipSlow # Timeout
 
-[ $arch == ia32 && $compiler == dartk && $strong ]
+[ $arch == ia32 && $compiler == dartk ]
 io/dart_std_io_pipe_test: Timeout, Pass # Issue 34723
 
-[ $arch == simarm64 && $strong && ($compiler == dartk || $compiler == dartkb) ]
+[ $arch == simarm64 && ($compiler == dartk || $compiler == dartkb) ]
 io/http_bind_test: Pass, Slow
 
 [ $arch == x64 && $builder_tag == asan && $compiler == dartk ]
@@ -71,19 +88,7 @@
 [ $builder_tag == optimization_counter_threshold && ($compiler == dartk || $compiler == dartkb) ]
 map_insert_remove_oom_test: Skip # Heap limit too low.
 
-# The failures below still need to be investigated and possibly fixed, or marked as skipped.
-[ $compiler == dartkb && $strong ]
-io/dart_std_io_pipe_test: Pass, Timeout # Please triage
-io/platform_resolved_executable_test/00: RuntimeError # Reruns the same script (dill file without AST) without passing --enable-interpreter or --use-bytecode-compiler.
-io/platform_resolved_executable_test/01: RuntimeError # Reruns the same script (dill file without AST) without passing --enable-interpreter or --use-bytecode-compiler.
-io/platform_resolved_executable_test/02: RuntimeError # Reruns the same script (dill file without AST) without passing --enable-interpreter or --use-bytecode-compiler.
-io/platform_resolved_executable_test/05: RuntimeError # Reruns the same script (dill file without AST) without passing --enable-interpreter or --use-bytecode-compiler.
-io/platform_test: RuntimeError # Platform.script points to dill file.
-io/test_extension_fail_test: RuntimeError # Platform.script points to dill file.
-io/test_extension_test: RuntimeError # Platform.script points to dill file.
-no_lazy_dispatchers_test: SkipByDesign # KBC interpreter doesn't support --no_lazy_dispatchers
-
-[ $compiler == dartkp && $mode == debug && $runtime == dart_precompiled && $strong ]
+[ $compiler == dartkp && $mode == debug && $runtime == dart_precompiled ]
 io/raw_socket_test: Crash
 io/skipping_dart2js_compilations_test: Crash
 io/socket_exception_test: Pass, Crash
@@ -92,14 +97,10 @@
 io/socket_info_ipv6_test: Pass, Crash
 io/socket_port_test: Pass, Crash
 
-[ $compiler == dartkp && $mode == product && $runtime == dart_precompiled && $strong ]
+[ $compiler == dartkp && $mode == product && $runtime == dart_precompiled ]
 io/compile_all_test: Pass
 
-# ===== dartkp + dart_precompiled status lines =====
-[ $compiler == dartkp && $runtime == dart_precompiled && $system != windows && $strong ]
-io/namespace_test: RuntimeError
-
-[ $compiler == dartkp && $runtime == dart_precompiled && $strong ]
+[ $compiler == dartkp && $runtime == dart_precompiled ]
 io/compile_all_test: Skip # We do not support --compile-all for precompilation
 io/file_fuzz_test: RuntimeError, Pass
 io/http_client_connect_test: Skip # Flaky.
@@ -131,20 +132,14 @@
 regress_29350_test: MissingCompileTimeError
 regress_29350_test/none: Pass # Issue 31537
 
+# ===== dartkp + dart_precompiled status lines =====
+[ $compiler == dartkp && $runtime == dart_precompiled && $system != windows ]
+io/namespace_test: RuntimeError
+
 [ $compiler == dartkp && $system == android ]
 io/http_close_test: Timeout # Issue 28380
 
-[ $compiler == dartkp && !$strong ]
-*: SkipByDesign
-
-[ $compiler == fasta && $strong ]
-io/http_cookie_date_test: CompileTimeError
-io/http_headers_test: CompileTimeError
-io/http_parser_test: CompileTimeError
-io/secure_socket_argument_test: CompileTimeError
-io/web_socket_protocol_processor_test: CompileTimeError
-
-[ $mode == debug && $runtime == vm && $strong && ($compiler == dartk || $compiler == dartkb) ]
+[ $mode == debug && $runtime == vm && ($compiler == dartk || $compiler == dartkb) ]
 io/file_lock_test: Slow, Pass
 io/raw_socket_test: Crash
 io/socket_exception_test: Pass, Crash
@@ -156,7 +151,7 @@
 [ $mode == debug && $hot_reload && ($compiler == dartk || $compiler == dartkb) ]
 io/web_socket_ping_test: Crash, Pass
 
-[ $runtime == vm && $strong && ($compiler == dartk || $compiler == dartkb) ]
+[ $runtime == vm && ($compiler == dartk || $compiler == dartkb) ]
 io/http_client_request_test: Pass, Timeout
 io/secure_builtin_roots_test: Pass, Timeout
 io/socket_finalizer_test: Pass, Timeout
@@ -164,22 +159,14 @@
 regress_29350_test: MissingCompileTimeError
 regress_29350_test/none: Pass # Issue 31537
 
-[ $system == windows && $strong && ($compiler == dartk || $compiler == dartkb) ]
-io/compile_all_test: Pass, Fail # Possibly related to issue 32373
-map_insert_remove_oom_test: Skip # Heap limit too low.
-
 [ $system == windows && ($compiler == dartk || $compiler == dartkb) ]
+io/compile_all_test: Pass, Fail # Possibly related to issue 32373
 io/dart_std_io_pipe_test: Pass, Slow
 io/secure_builtin_roots_test: Skip # Issues 32137 and 32138.
 io/test_extension_fail_test: RuntimeError, Pass # Issue 32137.
 io/test_extension_test: RuntimeError, Pass # Issue 32137.
 io/wait_for_event_isolate_test: Skip # Issues 32137 and 32138.
-
-[ $fasta && $strong ]
-package/package_isolate_test: CompileTimeError
-
-[ $fasta && !$strong ]
-regress_29350_test/none: MissingCompileTimeError
+map_insert_remove_oom_test: Skip # Heap limit too low.
 
 [ $hot_reload && ($compiler == dartk || $compiler == dartkb) ]
 io/http_no_reason_phrase_test: Pass, Crash
@@ -192,7 +179,7 @@
 # Enabling of dartk for sim{arm,arm64,dbc64} revealed these test failures, which
 # are to be triaged.  Isolate tests are skipped on purpose due to the usage of
 # batch mode.
-[ $strong && ($arch == simarm || $arch == simarm64 || $arch == simdbc64) && ($compiler == dartk || $compiler == dartkb) ]
+[ ($arch == simarm || $arch == simarm64 || $arch == simdbc64) && ($compiler == dartk || $compiler == dartkb) ]
 fragmentation_test: Timeout, Pass
 io/dart_std_io_pipe_test: Timeout, Pass
 io/directory_list_sync_test: Timeout, Pass # Please triage.
@@ -204,13 +191,6 @@
 io/test_extension_test: RuntimeError # Platform.script points to dill file.
 map_insert_remove_oom_test: Skip # Heap limit too low.
 
-# ===== Skip dartk and darkp in !$strong mode ====
-[ !$strong && ($compiler == dartk || $compiler == dartkb) ]
-*: SkipByDesign
-
-[ !$strong && ($compiler == dartk || $compiler == dartkb || $compiler == dartkp || $runtime == dart_precompiled || $runtime == vm) ]
-*: SkipByDesign # standalone_2 is only supported in strong mode.
-
 [ ($compiler == dartk || $compiler == dartkb) && ($hot_reload || $hot_reload_rollback) ]
 io/addlatexhash_test: Skip # Timeout
 io/http_advanced_test: Skip # Timeout
@@ -228,6 +208,5 @@
 io/web_socket_compression_test: Skip # Timeout
 io/web_socket_test: Skip # Timeout
 
-
 [ $compiler != dartk && $compiler != dartkb && $compiler != dartkp || $compiler == dartkp && $system == windows ]
 entrypoints_verification_test: SkipByDesign # Requires VM to run. Cannot run in precompiled Windows because the DLL is linked against dart.exe instead of dart_precompiled_runtime.exe.
diff --git a/tests/standalone_2/standalone_2_precompiled.status b/tests/standalone_2/standalone_2_precompiled.status
index 3209e7b..e17acac 100644
--- a/tests/standalone_2/standalone_2_precompiled.status
+++ b/tests/standalone_2/standalone_2_precompiled.status
@@ -62,9 +62,6 @@
 io/namespace_test: RuntimeError
 io/test_runner_test: RuntimeError
 
-[ $runtime == dart_precompiled && !$checked && !$strong ]
-io/file_constructor_test: RuntimeError
-
 [ $compiler == app_jit || $compiler == precompiler ]
 io/compile_all_test: Skip # Incompatible flag --compile_all
 
diff --git a/tests/standalone_2/standalone_2_vm.status b/tests/standalone_2/standalone_2_vm.status
index f6f03df..ee8622a 100644
--- a/tests/standalone_2/standalone_2_vm.status
+++ b/tests/standalone_2/standalone_2_vm.status
@@ -88,9 +88,6 @@
 [ $runtime == dart_precompiled && $system == linux && ($arch == simarm || $arch == simarm64 || $arch == x64) ]
 io/stdout_stderr_non_blocking_test: Pass, Timeout # Issue 35192
 
-[ $runtime == vm && !$checked && !$strong ]
-io/file_constructor_test: RuntimeError
-
 [ $runtime == vm && ($arch == arm || $arch == arm64) ]
 io/dart_std_io_pipe_test: Timeout, Pass
 io/file_input_stream_test: Skip # Issue 26109
diff --git a/tools/VERSION b/tools/VERSION
index 9bf1a57..fb1b7d6 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -32,8 +32,8 @@
 CHANNEL dev
 MAJOR 2
 MINOR 3
-PATCH 1
+PATCH 2
 PRERELEASE 0
 PRERELEASE_PATCH 0
-ABI_VERSION 4
+ABI_VERSION 5
 OLDEST_SUPPORTED_ABI_VERSION 3
diff --git a/tools/bots/test_matrix.json b/tools/bots/test_matrix.json
index e39d0d6..b9af47b 100644
--- a/tools/bots/test_matrix.json
+++ b/tools/bots/test_matrix.json
@@ -555,7 +555,6 @@
     },
     {
       "builders": [
-        "vm-kernel-precomp-linux-debug-x64",
         "vm-kernel-precomp-linux-product-x64",
         "vm-kernel-precomp-linux-release-simarm",
         "vm-kernel-precomp-linux-release-simarm64",
@@ -588,6 +587,32 @@
     },
     {
       "builders": [
+        "vm-kernel-precomp-linux-debug-x64"
+      ],
+      "meta": {
+        "description": "This configuration is used by the vm kernel precomp debug builders. It uses 15 shards for testing to avoid 1 hour shard timeouts."
+      },
+      "steps": [
+        {
+          "name": "build dart",
+          "script": "tools/build.py",
+          "arguments": [
+            "runtime_kernel",
+            "dart_precompiled_runtime"
+          ]
+        },
+        {
+          "name": "vm tests",
+          "arguments": [
+            "-ndartkp-${system}-${mode}-${arch}"
+          ],
+          "fileset": "vm-kernel",
+          "shards": 15
+        }
+      ]
+    },
+    {
+      "builders": [
         "vm-kernel-precomp-bare-linux-release-x64",
         "vm-kernel-precomp-bare-linux-release-simarm",
         "vm-kernel-precomp-bare-linux-release-simarm64"
@@ -1612,7 +1637,7 @@
         {
           "name": "analyze pkg/dev_compiler",
           "script": "out/ReleaseX64/dart-sdk/bin/dartanalyzer",
-          "arguments": ["--fatal-warnings", "pkg/dev_compiler"]
+          "arguments": ["--fatal-warnings", "--fatal-lints", "pkg/dev_compiler"]
         },
         {
           "name": "analyze pkg/expect",
diff --git a/tools/patches/flutter-engine/apply.sh b/tools/patches/flutter-engine/apply.sh
index 9c2bd33..06811d4 100755
--- a/tools/patches/flutter-engine/apply.sh
+++ b/tools/patches/flutter-engine/apply.sh
@@ -53,7 +53,7 @@
   # DEPS file might have been patched with new version of packages that
   # Dart SDK depends on. Get information about dependencies from the
   # DEPS file and forcefully update checkouts of those dependencies.
-  gclient.py revinfo | grep 'src/third_party/dart/' | while read -r line; do
+  gclient.py revinfo | grep 'src/third_party/dart/third_party' | while read -r line; do
     # revinfo would produce lines in the following format:
     #     path: git-url@tag-or-hash
     # Where no spaces occur inside path, git-url or tag-or-hash.
diff --git a/tools/patches/flutter-engine/b48c8b1d1c9050734c0491f4e36b7d61ef005233.patch b/tools/patches/flutter-engine/b48c8b1d1c9050734c0491f4e36b7d61ef005233.patch
new file mode 100644
index 0000000..1e357de
--- /dev/null
+++ b/tools/patches/flutter-engine/b48c8b1d1c9050734c0491f4e36b7d61ef005233.patch
@@ -0,0 +1,16 @@
+diff --git a/frontend_server/lib/server.dart b/frontend_server/lib/server.dart
+index 44a3d69b9..9620a5de0 100644
+--- a/frontend_server/lib/server.dart
++++ b/frontend_server/lib/server.dart
+@@ -85,11 +85,6 @@ Future<int> starter(
+       StringSink output,
+     }) async {
+   ArgResults options;
+-  frontend.argParser
+-    ..addFlag('track-widget-creation',
+-      help: 'Run a kernel transformer to track creation locations for widgets.',
+-      defaultsTo: false);
+-
+   try {
+     options = frontend.argParser.parse(args);
+   } catch (error) {
diff --git a/tools/patches/flutter-engine/cc63d6e647df1cfd34a54adb63aba7f937ce6f6b.patch b/tools/patches/flutter-engine/cc63d6e647df1cfd34a54adb63aba7f937ce6f6b.patch
deleted file mode 100644
index 5e81c49..0000000
--- a/tools/patches/flutter-engine/cc63d6e647df1cfd34a54adb63aba7f937ce6f6b.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-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 f3fee45..7c55c86 100644
--- a/tools/testing/dart/compiler_configuration.dart
+++ b/tools/testing/dart/compiler_configuration.dart
@@ -188,11 +188,6 @@
       List<String> originalArguments,
       CommandArtifact artifact) {
     var args = <String>[];
-    if (_isDebug) {
-      // Temporarily disable background compilation to avoid flaky crashes
-      // (see http://dartbug.com/30016 for details).
-      args.add('--no-background-compilation');
-    }
     if (_useEnableAsserts) {
       args.add('--enable_asserts');
     }
@@ -1148,8 +1143,10 @@
         !arguments.any((String arg) => noCausalAsyncStacksRegExp.hasMatch(arg));
     args.add('-Ddart.developer.causal_async_stacks=$causalAsyncStacks');
 
-    if (_useEnableAsserts) {
-      args.add('--enable_asserts');
+    if (_useEnableAsserts ||
+        arguments.contains('--enable-asserts') ||
+        arguments.contains('--enable_asserts')) {
+      args.add('--enable-asserts');
     }
 
     if (_configuration.useKernelBytecode) {
diff --git a/tools/utils.py b/tools/utils.py
index 7b69465..a8f96f6 100644
--- a/tools/utils.py
+++ b/tools/utils.py
@@ -340,8 +340,8 @@
       version.prerelease_patch))
 
 
-def GetSemanticSDKVersion(no_git_hash=False):
-  version = ReadVersionFile()
+def GetSemanticSDKVersion(no_git_hash=False, version_file=None):
+  version = ReadVersionFile(version_file)
   if not version:
     return None
 
@@ -356,8 +356,8 @@
   return '%s.%s.%s%s' % (version.major, version.minor, version.patch, postfix)
 
 
-def GetVersion(no_git_hash=False):
-  return GetSemanticSDKVersion(no_git_hash)
+def GetVersion(no_git_hash=False, version_file=None):
+  return GetSemanticSDKVersion(no_git_hash, version_file)
 
 
 # The editor used to produce the VERSION file put on gcs. We now produce this
diff --git a/utils/application_snapshot.gni b/utils/application_snapshot.gni
index e577331..2c257a2 100644
--- a/utils/application_snapshot.gni
+++ b/utils/application_snapshot.gni
@@ -176,49 +176,3 @@
     forward_variables_from(invoker, "*")
   }
 }
-
-template("aot_assembly") {
-  assert(defined(invoker.main_dart), "Must specify 'main_dart'")
-  aot_vm_args = []
-  if (defined(invoker.vm_args)) {
-    aot_vm_args = invoker.vm_args
-  }
-  main_dart = invoker.main_dart
-  aot_vm_args = aot_vm_args + [ rebase_path("$main_dart") ]
-  name = target_name
-  if (defined(invoker.name)) {
-    name = invoker.name
-  }
-  extra_deps = []
-  if (defined(invoker.deps)) {
-    extra_deps += invoker.deps
-  }
-  extra_inputs = [ main_dart ]
-  if (defined(invoker.inputs)) {
-    extra_inputs += invoker.inputs
-  }
-  output = "$root_gen_dir/$name.dart.S"
-  if (defined(invoker.output)) {
-    output = invoker.output
-  }
-  gen_snapshot_action(target_name) {
-    deps = extra_deps
-    depfile = "$output.d"
-
-    inputs = extra_inputs
-
-    outputs = [
-      output,
-    ]
-
-    abs_output = rebase_path(output, root_build_dir)
-
-    vm_args = [
-      "--deterministic",
-      "--snapshot-kind=app-aot-assembly",
-      "--assembly=$abs_output",
-    ] + aot_vm_args
-
-    args = []
-  }
-}
diff --git a/utils/bazel/kernel_worker.dart b/utils/bazel/kernel_worker.dart
index 2ff11ba..8ebfaee 100644
--- a/utils/bazel/kernel_worker.dart
+++ b/utils/bazel/kernel_worker.dart
@@ -16,7 +16,6 @@
 import 'package:bazel_worker/bazel_worker.dart';
 import 'package:build_integration/file_system/multi_root.dart';
 import 'package:dev_compiler/src/kernel/target.dart';
-import 'package:dev_compiler/src/flutter/track_widget_constructor_locations.dart';
 import 'package:front_end/src/api_unstable/bazel_worker.dart' as fe;
 import 'package:kernel/ast.dart' show Component, Library;
 import 'package:kernel/target/targets.dart';
@@ -129,7 +128,7 @@
   ..addOption('output')
   ..addFlag('reuse-compiler-result', defaultsTo: false)
   ..addFlag('use-incremental-compiler', defaultsTo: false)
-  ..addFlag('track-kernel-creation', defaultsTo: false);
+  ..addFlag('track-widget-creation', defaultsTo: false);
 
 class ComputeKernelResult {
   final bool succeeded;
@@ -173,18 +172,13 @@
   var excludeNonSources = parsedArgs['exclude-non-sources'] as bool;
 
   var summaryOnly = parsedArgs['summary-only'] as bool;
-  var trackKernelCreation = parsedArgs['track-kernel-creation'] as bool;
-
-  if (summaryOnly && trackKernelCreation) {
-    throw new ArgumentError('error: --summary-only is not compatible with '
-        '--track-kernel-creation');
-  }
+  var trackWidgetCreation = parsedArgs['track-widget-creation'] as bool;
 
   // TODO(sigmund,jakemac): make target mandatory. We allow null to be backwards
   // compatible while we migrate existing clients of this tool.
   var targetName =
       (parsedArgs['target'] as String) ?? (summaryOnly ? 'ddc' : 'vm');
-  var targetFlags = new TargetFlags();
+  var targetFlags = new TargetFlags(trackWidgetCreation: trackWidgetCreation);
   Target target;
   switch (targetName) {
     case 'vm':
@@ -217,7 +211,8 @@
     case 'ddc':
       // TODO(jakemac):If `generateKernel` changes to return a summary
       // component, process the component instead.
-      target = new DevCompilerSummaryTarget(sources, excludeNonSources);
+      target =
+          new DevCompilerSummaryTarget(sources, excludeNonSources, targetFlags);
       if (!summaryOnly) {
         out.writeln('error: --no-summary-only not supported for the '
             'ddc target');
@@ -243,7 +238,9 @@
 
   fe.InitializedCompilerState state;
   bool usingIncrementalCompiler = false;
-  if (parsedArgs['use-incremental-compiler'] && linkedInputs.isEmpty) {
+  if (parsedArgs['use-incremental-compiler'] &&
+      linkedInputs.isEmpty &&
+      isWorker) {
     usingIncrementalCompiler = true;
 
     /// Build a map of uris to digests.
@@ -296,23 +293,23 @@
         incrementalComponent.problemsAsJson = null;
         incrementalComponent.mainMethod = null;
         target.performOutlineTransformations(incrementalComponent);
-      } else if (trackKernelCreation) {
-        (new WidgetCreatorTracker()).transform(incrementalComponent);
+        return Future.value(fe.serializeComponent(incrementalComponent,
+            includeSources: false, includeOffsets: false));
       }
 
       return Future.value(fe.serializeComponent(incrementalComponent));
     });
+
+    state.options.onDiagnostic = null; // See http://dartbug.com/36983.
   } else if (summaryOnly) {
-    kernel = await fe.compileSummary(state, sources, onDiagnostic);
+    kernel = await fe.compileSummary(state, sources, onDiagnostic,
+        includeOffsets: false);
   } else {
     Component component =
         await fe.compileComponent(state, sources, onDiagnostic);
-
-    if (trackKernelCreation) {
-      (new WidgetCreatorTracker()).transform(component);
-    }
     kernel = fe.serializeComponent(component,
-        filter: (library) => sources.contains(library.importUri));
+        filter: (library) => sources.contains(library.importUri),
+        includeOffsets: true);
   }
 
   if (kernel != null) {
@@ -342,7 +339,9 @@
   final List<Uri> sources;
   final bool excludeNonSources;
 
-  DevCompilerSummaryTarget(this.sources, this.excludeNonSources);
+  DevCompilerSummaryTarget(
+      this.sources, this.excludeNonSources, TargetFlags targetFlags)
+      : super(targetFlags);
 
   @override
   void performOutlineTransformations(Component component) {
diff --git a/utils/dartanalyzer/BUILD.gn b/utils/dartanalyzer/BUILD.gn
index ad45cf1..7665d74 100644
--- a/utils/dartanalyzer/BUILD.gn
+++ b/utils/dartanalyzer/BUILD.gn
@@ -31,65 +31,6 @@
   name = "dartanalyzer"
 }
 
-if (current_os == "linux") {
-  prebuilt_dart_action("dart_analyzer_dill") {
-    deps = [
-      "../../runtime/vm:vm_platform",
-      "../../runtime/vm:kernel_platform_files($dart_host_toolchain)",
-    ]
-    dart_analyzer_script = "../../pkg/vm/bin/kernel_service.dart"
-    gen_kernel_script = "../../pkg/vm/bin/gen_kernel.dart"
-
-    inputs = [
-      gen_kernel_script,
-      dart_analyzer_script,
-      "$root_out_dir/vm_platform_strong.dill",
-    ]
-    output = "$root_gen_dir/dart_analyzer.dill"
-    outputs = [
-      output,
-    ]
-
-    depfile = "$root_gen_dir/dart_analyzer_dill.d"
-    abs_depfile = rebase_path(depfile)
-    rebased_output = rebase_path(output, root_out_dir)
-    vm_args = [
-      "--depfile=$abs_depfile",
-      "--depfile_output_filename=$rebased_output",
-    ]
-
-    script = gen_kernel_script
-
-    args = [
-      "--packages=" + rebase_path("../../.packages"),
-      "--platform=" + rebase_path("$root_out_dir/vm_platform_strong.dill"),
-      "--aot",
-      "--no-embed-sources",
-      "--output=" + rebase_path("$root_gen_dir/dart_analyzer.dill"),
-      rebase_path(dart_analyzer_script),
-    ]
-  }
-
-  aot_assembly("dartanalyzer_aot_assembly") {
-    main_dart = "$root_gen_dir/dart_analyzer.dill"
-    name = "dartanalyzer"
-    deps = [
-      ":dart_analyzer_dill"
-    ]
-  }
-
-  # This target is for Goma. It should not be used in the SDK.
-  executable("dartanalyzer_aot") {
-    deps = [
-      "../../runtime/bin:dart_precompiled_runtime_for_linking",
-      ":dartanalyzer_aot_assembly",
-    ]
-    sources = [
-      "$root_gen_dir/dartanalyzer.dart.S"
-    ]
-  }
-}
-
 sdk_lib_files = exec_script("../../tools/list_dart_files.py",
                             [
                               "absolute",