Version 2.6.0-dev.4.0

Merge commit '942af5bd62496330ab24720333cab08a2e8e5e07' into dev
diff --git a/BUILD.gn b/BUILD.gn
index 1aff52e..60d07ff 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -3,7 +3,6 @@
 # BSD-style license that can be found in the LICENSE file.
 
 import("build/config/gclient_args.gni")
-import("build/dart/dart_host_sdk_toolchain.gni")
 
 targetting_fuchsia = target_os == "fuchsia"
 
@@ -17,9 +16,7 @@
     ":runtime",
   ]
   if (defined(checkout_llvm) && checkout_llvm) {
-    deps += [
-      ":llvm_codegen"
-    ]
+    deps += [ ":llvm_codegen" ]
   }
 }
 
@@ -51,13 +48,13 @@
   }
   deps = [
     "runtime/bin:dart",
+    "runtime/bin:entrypoints_verification_test_extension",
+    "runtime/bin:ffi_test_dynamic_library",
+    "runtime/bin:ffi_test_functions",
     "runtime/bin:process_test",
     "runtime/bin:run_vm_tests",
     "runtime/bin:sample_extension",
     "runtime/bin:test_extension",
-    "runtime/bin:entrypoints_verification_test_extension",
-    "runtime/bin:ffi_test_dynamic_library",
-    "runtime/bin:ffi_test_functions",
     "runtime/vm:kernel_platform_files($host_toolchain)",
     "utils/kernel-service:kernel-service",
   ]
@@ -92,15 +89,6 @@
   ]
 }
 
-if (defined(dart_host_sdk_toolchain) &&
-    dart_host_sdk_toolchain != host_toolchain) {
-  group("create_host_sdk") {
-    deps = [
-      "sdk:create_sdk($dart_host_sdk_toolchain)",
-    ]
-  }
-}
-
 group("dart2js") {
   deps = [
     "utils/compiler:dart2js",
@@ -142,8 +130,8 @@
 group("llvm_codegen") {
   if (defined(checkout_llvm) && checkout_llvm) {
     deps = [
-      "runtime/llvm_codegen/codegen",
       "runtime/llvm_codegen/bit",
+      "runtime/llvm_codegen/codegen",
     ]
   }
 }
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ee267aa..ec7b523 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -33,7 +33,7 @@
 
 The Linter was updated to `0.1.98`, which includes:
 
-* fixed null raw expression accesses in use_to_and_as_if_applicable
+* fixed null raw expression accesses in `use_to_and_as_if_applicable`
 * internal migration to using analyzer `InheritanceManager3`
 * internal migration away from using analyzer `resolutionMap`
 * various fixes and improvements to anticipate support for extension-methods
diff --git a/DEPS b/DEPS
index 7d7529e..60b6900 100644
--- a/DEPS
+++ b/DEPS
@@ -82,9 +82,9 @@
   #     and land the review.
   #
   # For more details, see https://github.com/dart-lang/sdk/issues/30164
-  "dart_style_tag": "1.3.0",  # Please see the note above before updating.
+  "dart_style_tag": "1.3.1",  # Please see the note above before updating.
 
-  "dartdoc_rev" : "6934accd88c29a73cae26d0c4def3323efc2119c",
+  "dartdoc_tag" : "v0.28.6",
   "fixnum_tag": "0.10.9",
   "glob_tag": "1.1.7",
   "html_tag" : "0.14.0+1",
@@ -102,7 +102,7 @@
   "linter_tag": "0.1.98",
   "logging_tag": "0.11.3+2",
   "markupsafe_rev": "8f45f5cfa0009d2a70589bcda0349b8cb2b72783",
-  "markdown_tag": "2.0.3",
+  "markdown_tag": "2.1.1",
   "matcher_tag": "0.12.3",
   "mime_tag": "0.9.6+2",
   "mockito_tag": "d39ac507483b9891165e422ec98d9fb480037c8b",
@@ -174,7 +174,7 @@
   Var("dart_root") + "/tools/sdks": {
       "packages": [{
           "package": "dart/dart-sdk/${{platform}}",
-          "version": "version:2.5.0",
+          "version": "version:2.6.0-dev.3.0",
       }],
       "dep_type": "cipd",
   },
@@ -276,7 +276,7 @@
   Var("dart_root") + "/third_party/pkg/dart2js_info":
       Var("dart_git") + "dart2js_info.git" + "@" + Var("dart2js_info_tag"),
   Var("dart_root") + "/third_party/pkg/dartdoc":
-      Var("dart_git") + "dartdoc.git" + "@" + Var("dartdoc_rev"),
+      Var("dart_git") + "dartdoc.git" + "@" + Var("dartdoc_tag"),
   Var("dart_root") + "/third_party/pkg/fixnum":
       Var("dart_git") + "fixnum.git" + "@" + Var("fixnum_tag"),
   Var("dart_root") + "/third_party/pkg/glob":
diff --git a/build/dart/dart_action.gni b/build/dart/dart_action.gni
index e3d36f6..8fa5e57 100644
--- a/build/dart/dart_action.gni
+++ b/build/dart/dart_action.gni
@@ -3,7 +3,6 @@
 # BSD-style license that can be found in the LICENSE file.
 
 import("../executable_suffix.gni")
-import("dart_host_sdk_toolchain.gni")
 import("prebuilt_dart_sdk.gni")
 
 _is_fuchsia = defined(is_fuchsia_tree) && is_fuchsia_tree
@@ -62,7 +61,7 @@
     outputs = invoker.outputs
 
     # Construct the host toolchain version of the tool.
-    host_tool = invoker.tool + "($dart_host_toolchain)"
+    host_tool = invoker.tool + "($host_toolchain)"
 
     # Get the path to the executable. Currently, this assumes that the tool
     # does not specify output_name so that the target name is the name to use.
diff --git a/build/dart/dart_host_sdk_toolchain.gni b/build/dart/dart_host_sdk_toolchain.gni
deleted file mode 100644
index f61d287..0000000
--- a/build/dart/dart_host_sdk_toolchain.gni
+++ /dev/null
@@ -1,16 +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.
-
-# dart_host_toolchain should be used in the Dart tree instead of host_toolchain.
-# It will ensure that we are selecting the correct host toolchain.
-dart_host_toolchain = host_toolchain
-
-# Config variable: dart_host_sdk_toolchain
-# In a cross-build, this should be set to the toolchain to use to build a Dart
-# SDK to run on the host that targets the host. This is distinct from
-# 'host_toolchain', which in a cross-build builds artifacts to run on the host
-# that target the target architecture.
-if (defined(dart_host_sdk_toolchain) && current_toolchain == dart_host_sdk_toolchain) {
-  dart_host_toolchain = dart_host_sdk_toolchain
-}
diff --git a/pkg/analysis_server/analysis_options.yaml b/pkg/analysis_server/analysis_options.yaml
index ed8c3c5..589be1c 100644
--- a/pkg/analysis_server/analysis_options.yaml
+++ b/pkg/analysis_server/analysis_options.yaml
@@ -1,4 +1,5 @@
 include: package:pedantic/analysis_options.1.8.0.yaml
+
 analyzer:
   # This currently finds ~1,200 implicit-casts issues when enabled.
   # strong-mode:
@@ -6,6 +7,8 @@
   exclude:
     - test/mock_packages/**
   errors:
+    # Increase the severity of the unused_import hint.
+    unused_import: warning
     # Ignoring "style" lint rules from pedantic for now. There are pre-existing
     # violations that need to be cleaned up. Each one can be cleaned up and
     # enabled according to the value provided.
diff --git a/pkg/analysis_server/lib/src/edit/fix/non_nullable_fix.dart b/pkg/analysis_server/lib/src/edit/fix/non_nullable_fix.dart
index b1173da..ef4751b 100644
--- a/pkg/analysis_server/lib/src/edit/fix/non_nullable_fix.dart
+++ b/pkg/analysis_server/lib/src/edit/fix/non_nullable_fix.dart
@@ -9,6 +9,8 @@
 import 'package:analysis_server/src/edit/nnbd_migration/info_builder.dart';
 import 'package:analysis_server/src/edit/nnbd_migration/instrumentation_listener.dart';
 import 'package:analysis_server/src/edit/nnbd_migration/instrumentation_renderer.dart';
+import 'package:analysis_server/src/edit/nnbd_migration/highlight_js.dart';
+import 'package:analysis_server/src/edit/nnbd_migration/highlight_css.dart';
 import 'package:analysis_server/src/edit/nnbd_migration/migration_info.dart';
 import 'package:analyzer/dart/analysis/results.dart';
 import 'package:analyzer/dart/ast/ast.dart';
@@ -214,22 +216,36 @@
 
   /// Generate output into the given [folder].
   void _generateOutput(OverlayResourceProvider provider, Folder folder) async {
-    List<LibraryInfo> libraryInfos = await InfoBuilder(listener.server)
-        .explainMigration(instrumentationListener.data, listener);
-    listener.addDetail('libraryInfos has ${libraryInfos.length} libs');
+    List<LibraryInfo> libraryInfos =
+        await InfoBuilder(instrumentationListener.data, listener)
+            .explainMigration();
+    var pathContext = provider.pathContext;
+    MigrationInfo migrationInfo =
+        MigrationInfo(libraryInfos, pathContext, includedRoot);
     for (LibraryInfo info in libraryInfos) {
-      var pathContext = provider.pathContext;
-      var libraryPath =
+      assert(info.units.isNotEmpty);
+      String libraryPath =
           pathContext.setExtension(info.units.first.path, '.html');
-      // TODO(srawlins): Choose a better scheme than the double underscores,
-      // likely with actual directories, which need to be individually created.
-      var relativePath = pathContext
-          .relative(libraryPath, from: includedRoot)
-          .replaceAll('/', '__');
-      File output = folder.getChildAssumingFile(relativePath);
-      String rendered = InstrumentationRenderer(info).render();
+      String relativePath =
+          pathContext.relative(libraryPath, from: includedRoot);
+      List<String> directories =
+          pathContext.split(pathContext.dirname(relativePath));
+      for (int i = 0; i < directories.length; i++) {
+        String directory = pathContext.joinAll(directories.sublist(0, i + 1));
+        folder.getChildAssumingFolder(directory).create();
+      }
+      File output =
+          provider.getFile(pathContext.join(folder.path, relativePath));
+      String rendered = InstrumentationRenderer(info, migrationInfo).render();
       output.writeAsStringSync(rendered);
     }
+    // Generate resource files:
+    File highlightJsOutput =
+        provider.getFile(pathContext.join(folder.path, 'highlight.pack.js'));
+    highlightJsOutput.writeAsStringSync(decodeHighlightJs());
+    File highlightCssOutput =
+        provider.getFile(pathContext.join(folder.path, 'androidstudio.css'));
+    highlightCssOutput.writeAsStringSync(decodeHighlightCss());
   }
 
   static void task(DartFixRegistrar registrar, DartFixListener listener,
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/highlight_css.dart b/pkg/analysis_server/lib/src/edit/nnbd_migration/highlight_css.dart
new file mode 100644
index 0000000..1dbdb96
--- /dev/null
+++ b/pkg/analysis_server/lib/src/edit/nnbd_migration/highlight_css.dart
@@ -0,0 +1,25 @@
+// 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.
+
+/* To regenerate this file:
+
+1. Build and download highlight.zip for Dart [1].
+2. Extract highlight.zip, and find styles/androidstudio.css.
+3. Run:
+
+       sed -i -e '/^const _highlightCss =/{
+       r'<(echo 'const _highlightCss = "'"$(base64 < styles/androidstudio.css)"'";')'
+       d
+       }' highlight_css.dart
+
+[1] https://highlightjs.org/download/
+*/
+
+import 'dart:convert';
+
+const _highlightCss =
+    "LyoKRGF0ZTogMjQgRmV2IDIwMTUKQXV0aG9yOiBQZWRybyBPbGl2ZWlyYSA8a2FueXR1QGdtYWlsIC4gY29tPgoqLwoKLmhsanMgewogIGNvbG9yOiAjYTliN2M2OwogIGJhY2tncm91bmQ6ICMyODJiMmU7CiAgZGlzcGxheTogYmxvY2s7CiAgb3ZlcmZsb3cteDogYXV0bzsKICBwYWRkaW5nOiAwLjVlbTsKfQoKLmhsanMtbnVtYmVyLAouaGxqcy1saXRlcmFsLAouaGxqcy1zeW1ib2wsCi5obGpzLWJ1bGxldCB7CiAgY29sb3I6ICM2ODk3QkI7Cn0KCi5obGpzLWtleXdvcmQsCi5obGpzLXNlbGVjdG9yLXRhZywKLmhsanMtZGVsZXRpb24gewogIGNvbG9yOiAjY2M3ODMyOwp9CgouaGxqcy12YXJpYWJsZSwKLmhsanMtdGVtcGxhdGUtdmFyaWFibGUsCi5obGpzLWxpbmsgewogIGNvbG9yOiAjNjI5NzU1Owp9CgouaGxqcy1jb21tZW50LAouaGxqcy1xdW90ZSB7CiAgY29sb3I6ICM4MDgwODA7Cn0KCi5obGpzLW1ldGEgewogIGNvbG9yOiAjYmJiNTI5Owp9CgouaGxqcy1zdHJpbmcsCi5obGpzLWF0dHJpYnV0ZSwKLmhsanMtYWRkaXRpb24gewogIGNvbG9yOiAjNkE4NzU5Owp9CgouaGxqcy1zZWN0aW9uLAouaGxqcy10aXRsZSwKLmhsanMtdHlwZSB7CiAgY29sb3I6ICNmZmM2NmQ7Cn0KCi5obGpzLW5hbWUsCi5obGpzLXNlbGVjdG9yLWlkLAouaGxqcy1zZWxlY3Rvci1jbGFzcyB7CiAgY29sb3I6ICNlOGJmNmE7Cn0KCi5obGpzLWVtcGhhc2lzIHsKICBmb250LXN0eWxlOiBpdGFsaWM7Cn0KCi5obGpzLXN0cm9uZyB7CiAgZm9udC13ZWlnaHQ6IGJvbGQ7Cn0K";
+
+String decodeHighlightCss() =>
+    String.fromCharCodes(base64Decode(_highlightCss));
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/highlight_js.dart b/pkg/analysis_server/lib/src/edit/nnbd_migration/highlight_js.dart
new file mode 100644
index 0000000..fdec128
--- /dev/null
+++ b/pkg/analysis_server/lib/src/edit/nnbd_migration/highlight_js.dart
@@ -0,0 +1,24 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/* To regenerate this file:
+
+1. Build and download highlight.zip for Dart [1].
+2. Extract highlight.zip, and find highlight.pack.js.
+3. Run:
+
+       sed -i -e '/^const _highlightJs =/{
+       r'<(echo 'const _highlightJs = "'"$(base64 < highlight.pack.js)"'";')'
+       d
+       }' highlightjs.dart
+
+[1] https://highlightjs.org/download/
+*/
+
+import 'dart:convert';
+
+const _highlightJs =
+    "LyohIGhpZ2hsaWdodC5qcyB2OS4xNS4xMCB8IEJTRDMgTGljZW5zZSB8IGdpdC5pby9obGpzbGljZW5zZSAqLwohZnVuY3Rpb24oZSl7dmFyIG49Im9iamVjdCI9PXR5cGVvZiB3aW5kb3cmJndpbmRvd3x8Im9iamVjdCI9PXR5cGVvZiBzZWxmJiZzZWxmOyJ1bmRlZmluZWQiPT10eXBlb2YgZXhwb3J0c3x8ZXhwb3J0cy5ub2RlVHlwZT9uJiYobi5obGpzPWUoe30pLCJmdW5jdGlvbiI9PXR5cGVvZiBkZWZpbmUmJmRlZmluZS5hbWQmJmRlZmluZShbXSxmdW5jdGlvbigpe3JldHVybiBuLmhsanN9KSk6ZShleHBvcnRzKX0oZnVuY3Rpb24oYSl7dmFyIGY9W10sdT1PYmplY3Qua2V5cyxOPXt9LGM9e30sbj0vXihuby0/aGlnaGxpZ2h0fHBsYWlufHRleHQpJC9pLHM9L1xibGFuZyg/OnVhZ2UpPy0oW1x3LV0rKVxiL2ksdD0vKCheKDxbXj5dKz58XHR8KSt8KD86XG4pKSkvZ20scj17Y2FzZV9pbnNlbnNpdGl2ZToiY0kiLGxleGVtZXM6ImwiLGNvbnRhaW5zOiJjIixrZXl3b3JkczoiayIsc3ViTGFuZ3VhZ2U6InNMIixjbGFzc05hbWU6ImNOIixiZWdpbjoiYiIsYmVnaW5LZXl3b3JkczoiYksiLGVuZDoiZSIsZW5kc1dpdGhQYXJlbnQ6ImVXIixpbGxlZ2FsOiJpIixleGNsdWRlQmVnaW46ImVCIixleGNsdWRlRW5kOiJlRSIscmV0dXJuQmVnaW46InJCIixyZXR1cm5FbmQ6InJFIixyZWxldmFuY2U6InIiLHZhcmlhbnRzOiJ2IixJREVOVF9SRToiSVIiLFVOREVSU0NPUkVfSURFTlRfUkU6IlVJUiIsTlVNQkVSX1JFOiJOUiIsQ19OVU1CRVJfUkU6IkNOUiIsQklOQVJZX05VTUJFUl9SRToiQk5SIixSRV9TVEFSVEVSU19SRToiUlNSIixCQUNLU0xBU0hfRVNDQVBFOiJCRSIsQVBPU19TVFJJTkdfTU9ERToiQVNNIixRVU9URV9TVFJJTkdfTU9ERToiUVNNIixQSFJBU0FMX1dPUkRTX01PREU6IlBXTSIsQ19MSU5FX0NPTU1FTlRfTU9ERToiQ0xDTSIsQ19CTE9DS19DT01NRU5UX01PREU6IkNCQ00iLEhBU0hfQ09NTUVOVF9NT0RFOiJIQ00iLE5VTUJFUl9NT0RFOiJOTSIsQ19OVU1CRVJfTU9ERToiQ05NIixCSU5BUllfTlVNQkVSX01PREU6IkJOTSIsQ1NTX05VTUJFUl9NT0RFOiJDU1NOTSIsUkVHRVhQX01PREU6IlJNIixUSVRMRV9NT0RFOiJUTSIsVU5ERVJTQ09SRV9USVRMRV9NT0RFOiJVVE0iLENPTU1FTlQ6IkMiLGJlZ2luUmU6ImJSIixlbmRSZToiZVIiLGlsbGVnYWxSZToiaVIiLGxleGVtZXNSZToibFIiLHRlcm1pbmF0b3JzOiJ0Iix0ZXJtaW5hdG9yX2VuZDoidEUifSxiPSI8L3NwYW4+IixoPXtjbGFzc1ByZWZpeDoiaGxqcy0iLHRhYlJlcGxhY2U6bnVsbCx1c2VCUjohMSxsYW5ndWFnZXM6dm9pZCAwfTtmdW5jdGlvbiBfKGUpe3JldHVybiBlLnJlcGxhY2UoLyYvZywiJmFtcDsiKS5yZXBsYWNlKC88L2csIiZsdDsiKS5yZXBsYWNlKC8+L2csIiZndDsiKX1mdW5jdGlvbiBFKGUpe3JldHVybiBlLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCl9ZnVuY3Rpb24gdihlLG4pe3ZhciB0PWUmJmUuZXhlYyhuKTtyZXR1cm4gdCYmMD09PXQuaW5kZXh9ZnVuY3Rpb24gbChlKXtyZXR1cm4gbi50ZXN0KGUpfWZ1bmN0aW9uIGcoZSl7dmFyIG4sdD17fSxyPUFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywxKTtmb3IobiBpbiBlKXRbbl09ZVtuXTtyZXR1cm4gci5mb3JFYWNoKGZ1bmN0aW9uKGUpe2ZvcihuIGluIGUpdFtuXT1lW25dfSksdH1mdW5jdGlvbiBSKGUpe3ZhciBhPVtdO3JldHVybiBmdW5jdGlvbiBlKG4sdCl7Zm9yKHZhciByPW4uZmlyc3RDaGlsZDtyO3I9ci5uZXh0U2libGluZykzPT09ci5ub2RlVHlwZT90Kz1yLm5vZGVWYWx1ZS5sZW5ndGg6MT09PXIubm9kZVR5cGUmJihhLnB1c2goe2V2ZW50OiJzdGFydCIsb2Zmc2V0OnQsbm9kZTpyfSksdD1lKHIsdCksRShyKS5tYXRjaCgvYnJ8aHJ8aW1nfGlucHV0Lyl8fGEucHVzaCh7ZXZlbnQ6InN0b3AiLG9mZnNldDp0LG5vZGU6cn0pKTtyZXR1cm4gdH0oZSwwKSxhfWZ1bmN0aW9uIGkoZSl7aWYociYmIWUubGFuZ0FwaVJlc3RvcmVkKXtmb3IodmFyIG4gaW4gZS5sYW5nQXBpUmVzdG9yZWQ9ITAscillW25dJiYoZVtyW25dXT1lW25dKTsoZS5jfHxbXSkuY29uY2F0KGUudnx8W10pLmZvckVhY2goaSl9fWZ1bmN0aW9uIG0obyl7ZnVuY3Rpb24gcyhlKXtyZXR1cm4gZSYmZS5zb3VyY2V8fGV9ZnVuY3Rpb24gYyhlLG4pe3JldHVybiBuZXcgUmVnRXhwKHMoZSksIm0iKyhvLmNJPyJpIjoiIikrKG4/ImciOiIiKSl9IWZ1bmN0aW9uIG4odCxlKXtpZighdC5jb21waWxlZCl7aWYodC5jb21waWxlZD0hMCx0Lms9dC5rfHx0LmJLLHQuayl7ZnVuY3Rpb24gcih0LGUpe28uY0kmJihlPWUudG9Mb3dlckNhc2UoKSksZS5zcGxpdCgiICIpLmZvckVhY2goZnVuY3Rpb24oZSl7dmFyIG49ZS5zcGxpdCgifCIpO2FbblswXV09W3QsblsxXT9OdW1iZXIoblsxXSk6MV19KX12YXIgYT17fTsic3RyaW5nIj09dHlwZW9mIHQuaz9yKCJrZXl3b3JkIix0LmspOnUodC5rKS5mb3JFYWNoKGZ1bmN0aW9uKGUpe3IoZSx0LmtbZV0pfSksdC5rPWF9dC5sUj1jKHQubHx8L1x3Ky8sITApLGUmJih0LmJLJiYodC5iPSJcXGIoIit0LmJLLnNwbGl0KCIgIikuam9pbigifCIpKyIpXFxiIiksdC5ifHwodC5iPS9cQnxcYi8pLHQuYlI9Yyh0LmIpLHQuZW5kU2FtZUFzQmVnaW4mJih0LmU9dC5iKSx0LmV8fHQuZVd8fCh0LmU9L1xCfFxiLyksdC5lJiYodC5lUj1jKHQuZSkpLHQudEU9cyh0LmUpfHwiIix0LmVXJiZlLnRFJiYodC50RSs9KHQuZT8ifCI6IiIpK2UudEUpKSx0LmkmJih0LmlSPWModC5pKSksbnVsbD09dC5yJiYodC5yPTEpLHQuY3x8KHQuYz1bXSksdC5jPUFycmF5LnByb3RvdHlwZS5jb25jYXQuYXBwbHkoW10sdC5jLm1hcChmdW5jdGlvbihlKXtyZXR1cm4gZnVuY3Rpb24obil7cmV0dXJuIG4udiYmIW4uY2FjaGVkX3ZhcmlhbnRzJiYobi5jYWNoZWRfdmFyaWFudHM9bi52Lm1hcChmdW5jdGlvbihlKXtyZXR1cm4gZyhuLHt2Om51bGx9LGUpfSkpLG4uY2FjaGVkX3ZhcmlhbnRzfHxuLmVXJiZbZyhuKV18fFtuXX0oInNlbGYiPT09ZT90OmUpfSkpLHQuYy5mb3JFYWNoKGZ1bmN0aW9uKGUpe24oZSx0KX0pLHQuc3RhcnRzJiZuKHQuc3RhcnRzLGUpO3ZhciBpPXQuYy5tYXAoZnVuY3Rpb24oZSl7cmV0dXJuIGUuYks/IlxcLj8oPzoiK2UuYisiKVxcLj8iOmUuYn0pLmNvbmNhdChbdC50RSx0LmldKS5tYXAocykuZmlsdGVyKEJvb2xlYW4pO3QudD1pLmxlbmd0aD9jKGZ1bmN0aW9uKGUsbil7Zm9yKHZhciB0PS9cWyg/OlteXFxcXV18XFwuKSpcXXxcKFw/P3xcXChbMS05XVswLTldKil8XFwuLyxyPTAsYT0iIixpPTA7aTxlLmxlbmd0aDtpKyspe3ZhciBvPXIsYz1zKGVbaV0pO2ZvcigwPGkmJihhKz1uKTswPGMubGVuZ3RoOyl7dmFyIHU9dC5leGVjKGMpO2lmKG51bGw9PXUpe2ErPWM7YnJlYWt9YSs9Yy5zdWJzdHJpbmcoMCx1LmluZGV4KSxjPWMuc3Vic3RyaW5nKHUuaW5kZXgrdVswXS5sZW5ndGgpLCJcXCI9PXVbMF1bMF0mJnVbMV0/YSs9IlxcIitTdHJpbmcoTnVtYmVyKHVbMV0pK28pOihhKz11WzBdLCIoIj09dVswXSYmcisrKX19cmV0dXJuIGF9KGksInwiKSwhMCk6e2V4ZWM6ZnVuY3Rpb24oKXtyZXR1cm4gbnVsbH19fX0obyl9ZnVuY3Rpb24gQyhlLG4saSx0KXtmdW5jdGlvbiBjKGUsbix0LHIpe3ZhciBhPSc8c3BhbiBjbGFzcz0iJysocj8iIjpoLmNsYXNzUHJlZml4KTtyZXR1cm4gZT8oYSs9ZSsnIj4nKStuKyh0PyIiOmIpOm59ZnVuY3Rpb24gbygpe0UrPW51bGwhPWwuc0w/ZnVuY3Rpb24oKXt2YXIgZT0ic3RyaW5nIj09dHlwZW9mIGwuc0w7aWYoZSYmIU5bbC5zTF0pcmV0dXJuIF8oZyk7dmFyIG49ZT9DKGwuc0wsZywhMCxmW2wuc0xdKTpPKGcsbC5zTC5sZW5ndGg/bC5zTDp2b2lkIDApO3JldHVybiAwPGwuciYmKFIrPW4uciksZSYmKGZbbC5zTF09bi50b3ApLGMobi5sYW5ndWFnZSxuLnZhbHVlLCExLCEwKX0oKTpmdW5jdGlvbigpe3ZhciBlLG4sdCxyLGEsaSxvO2lmKCFsLmspcmV0dXJuIF8oZyk7Zm9yKHI9IiIsbj0wLGwubFIubGFzdEluZGV4PTAsdD1sLmxSLmV4ZWMoZyk7dDspcis9XyhnLnN1YnN0cmluZyhuLHQuaW5kZXgpKSxhPWwsaT10LHZvaWQgMCxvPXMuY0k/aVswXS50b0xvd2VyQ2FzZSgpOmlbMF0sKGU9YS5rLmhhc093blByb3BlcnR5KG8pJiZhLmtbb10pPyhSKz1lWzFdLHIrPWMoZVswXSxfKHRbMF0pKSk6cis9Xyh0WzBdKSxuPWwubFIubGFzdEluZGV4LHQ9bC5sUi5leGVjKGcpO3JldHVybiByK18oZy5zdWJzdHIobikpfSgpLGc9IiJ9ZnVuY3Rpb24gdShlKXtFKz1lLmNOP2MoZS5jTiwiIiwhMCk6IiIsbD1PYmplY3QuY3JlYXRlKGUse3BhcmVudDp7dmFsdWU6bH19KX1mdW5jdGlvbiByKGUsbil7aWYoZys9ZSxudWxsPT1uKXJldHVybiBvKCksMDt2YXIgdD1mdW5jdGlvbihlLG4pe3ZhciB0LHIsYTtmb3IodD0wLHI9bi5jLmxlbmd0aDt0PHI7dCsrKWlmKHYobi5jW3RdLmJSLGUpKXJldHVybiBuLmNbdF0uZW5kU2FtZUFzQmVnaW4mJihuLmNbdF0uZVI9KGE9bi5jW3RdLmJSLmV4ZWMoZSlbMF0sbmV3IFJlZ0V4cChhLnJlcGxhY2UoL1stXC9cXF4kKis/LigpfFtcXXt9XS9nLCJcXCQmIiksIm0iKSkpLG4uY1t0XX0obixsKTtpZih0KXJldHVybiB0LnNraXA/Zys9bjoodC5lQiYmKGcrPW4pLG8oKSx0LnJCfHx0LmVCfHwoZz1uKSksdSh0KSx0LnJCPzA6bi5sZW5ndGg7dmFyIHI9ZnVuY3Rpb24gZShuLHQpe2lmKHYobi5lUix0KSl7Zm9yKDtuLmVuZHNQYXJlbnQmJm4ucGFyZW50OyluPW4ucGFyZW50O3JldHVybiBufWlmKG4uZVcpcmV0dXJuIGUobi5wYXJlbnQsdCl9KGwsbik7aWYocil7dmFyIGE9bDtmb3IoYS5za2lwP2crPW46KGEuckV8fGEuZUV8fChnKz1uKSxvKCksYS5lRSYmKGc9bikpO2wuY04mJihFKz1iKSxsLnNraXB8fGwuc0x8fChSKz1sLnIpLChsPWwucGFyZW50KSE9PXIucGFyZW50Oyk7cmV0dXJuIHIuc3RhcnRzJiYoci5lbmRTYW1lQXNCZWdpbiYmKHIuc3RhcnRzLmVSPXIuZVIpLHUoci5zdGFydHMpKSxhLnJFPzA6bi5sZW5ndGh9aWYoZnVuY3Rpb24oZSxuKXtyZXR1cm4haSYmdihuLmlSLGUpfShuLGwpKXRocm93IG5ldyBFcnJvcignSWxsZWdhbCBsZXhlbWUgIicrbisnIiBmb3IgbW9kZSAiJysobC5jTnx8Ijx1bm5hbWVkPiIpKyciJyk7cmV0dXJuIGcrPW4sbi5sZW5ndGh8fDF9dmFyIHM9QihlKTtpZighcyl0aHJvdyBuZXcgRXJyb3IoJ1Vua25vd24gbGFuZ3VhZ2U6ICInK2UrJyInKTttKHMpO3ZhciBhLGw9dHx8cyxmPXt9LEU9IiI7Zm9yKGE9bDthIT09czthPWEucGFyZW50KWEuY04mJihFPWMoYS5jTiwiIiwhMCkrRSk7dmFyIGc9IiIsUj0wO3RyeXtmb3IodmFyIGQscCxNPTA7bC50Lmxhc3RJbmRleD1NLGQ9bC50LmV4ZWMobik7KXA9cihuLnN1YnN0cmluZyhNLGQuaW5kZXgpLGRbMF0pLE09ZC5pbmRleCtwO2ZvcihyKG4uc3Vic3RyKE0pKSxhPWw7YS5wYXJlbnQ7YT1hLnBhcmVudClhLmNOJiYoRSs9Yik7cmV0dXJue3I6Uix2YWx1ZTpFLGxhbmd1YWdlOmUsdG9wOmx9fWNhdGNoKGUpe2lmKGUubWVzc2FnZSYmLTEhPT1lLm1lc3NhZ2UuaW5kZXhPZigiSWxsZWdhbCIpKXJldHVybntyOjAsdmFsdWU6XyhuKX07dGhyb3cgZX19ZnVuY3Rpb24gTyh0LGUpe2U9ZXx8aC5sYW5ndWFnZXN8fHUoTik7dmFyIHI9e3I6MCx2YWx1ZTpfKHQpfSxhPXI7cmV0dXJuIGUuZmlsdGVyKEIpLmZpbHRlcihNKS5mb3JFYWNoKGZ1bmN0aW9uKGUpe3ZhciBuPUMoZSx0LCExKTtuLmxhbmd1YWdlPWUsbi5yPmEuciYmKGE9biksbi5yPnIuciYmKGE9cixyPW4pfSksYS5sYW5ndWFnZSYmKHIuc2Vjb25kX2Jlc3Q9YSkscn1mdW5jdGlvbiBkKGUpe3JldHVybiBoLnRhYlJlcGxhY2V8fGgudXNlQlI/ZS5yZXBsYWNlKHQsZnVuY3Rpb24oZSxuKXtyZXR1cm4gaC51c2VCUiYmIlxuIj09PWU/Ijxicj4iOmgudGFiUmVwbGFjZT9uLnJlcGxhY2UoL1x0L2csaC50YWJSZXBsYWNlKToiIn0pOmV9ZnVuY3Rpb24gbyhlKXt2YXIgbix0LHIsYSxpLG89ZnVuY3Rpb24oZSl7dmFyIG4sdCxyLGEsaT1lLmNsYXNzTmFtZSsiICI7aWYoaSs9ZS5wYXJlbnROb2RlP2UucGFyZW50Tm9kZS5jbGFzc05hbWU6IiIsdD1zLmV4ZWMoaSkpcmV0dXJuIEIodFsxXSk/dFsxXToibm8taGlnaGxpZ2h0Ijtmb3Iobj0wLHI9KGk9aS5zcGxpdCgvXHMrLykpLmxlbmd0aDtuPHI7bisrKWlmKGwoYT1pW25dKXx8QihhKSlyZXR1cm4gYX0oZSk7bChvKXx8KGgudXNlQlI/KG49ZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sIiwiZGl2IikpLmlubmVySFRNTD1lLmlubmVySFRNTC5yZXBsYWNlKC9cbi9nLCIiKS5yZXBsYWNlKC88YnJbIFwvXSo+L2csIlxuIik6bj1lLGk9bi50ZXh0Q29udGVudCxyPW8/QyhvLGksITApOk8oaSksKHQ9UihuKSkubGVuZ3RoJiYoKGE9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sIiwiZGl2IikpLmlubmVySFRNTD1yLnZhbHVlLHIudmFsdWU9ZnVuY3Rpb24oZSxuLHQpe3ZhciByPTAsYT0iIixpPVtdO2Z1bmN0aW9uIG8oKXtyZXR1cm4gZS5sZW5ndGgmJm4ubGVuZ3RoP2VbMF0ub2Zmc2V0IT09blswXS5vZmZzZXQ/ZVswXS5vZmZzZXQ8blswXS5vZmZzZXQ/ZTpuOiJzdGFydCI9PT1uWzBdLmV2ZW50P2U6bjplLmxlbmd0aD9lOm59ZnVuY3Rpb24gYyhlKXthKz0iPCIrRShlKStmLm1hcC5jYWxsKGUuYXR0cmlidXRlcyxmdW5jdGlvbihlKXtyZXR1cm4iICIrZS5ub2RlTmFtZSsnPSInK18oZS52YWx1ZSkucmVwbGFjZSgnIicsIiZxdW90OyIpKyciJ30pLmpvaW4oIiIpKyI+In1mdW5jdGlvbiB1KGUpe2ErPSI8LyIrRShlKSsiPiJ9ZnVuY3Rpb24gcyhlKXsoInN0YXJ0Ij09PWUuZXZlbnQ/Yzp1KShlLm5vZGUpfWZvcig7ZS5sZW5ndGh8fG4ubGVuZ3RoOyl7dmFyIGw9bygpO2lmKGErPV8odC5zdWJzdHJpbmcocixsWzBdLm9mZnNldCkpLHI9bFswXS5vZmZzZXQsbD09PWUpe2ZvcihpLnJldmVyc2UoKS5mb3JFYWNoKHUpO3MobC5zcGxpY2UoMCwxKVswXSksKGw9bygpKT09PWUmJmwubGVuZ3RoJiZsWzBdLm9mZnNldD09PXI7KTtpLnJldmVyc2UoKS5mb3JFYWNoKGMpfWVsc2Uic3RhcnQiPT09bFswXS5ldmVudD9pLnB1c2gobFswXS5ub2RlKTppLnBvcCgpLHMobC5zcGxpY2UoMCwxKVswXSl9cmV0dXJuIGErXyh0LnN1YnN0cihyKSl9KHQsUihhKSxpKSksci52YWx1ZT1kKHIudmFsdWUpLGUuaW5uZXJIVE1MPXIudmFsdWUsZS5jbGFzc05hbWU9ZnVuY3Rpb24oZSxuLHQpe3ZhciByPW4/Y1tuXTp0LGE9W2UudHJpbSgpXTtyZXR1cm4gZS5tYXRjaCgvXGJobGpzXGIvKXx8YS5wdXNoKCJobGpzIiksLTE9PT1lLmluZGV4T2YocikmJmEucHVzaChyKSxhLmpvaW4oIiAiKS50cmltKCl9KGUuY2xhc3NOYW1lLG8sci5sYW5ndWFnZSksZS5yZXN1bHQ9e2xhbmd1YWdlOnIubGFuZ3VhZ2UscmU6ci5yfSxyLnNlY29uZF9iZXN0JiYoZS5zZWNvbmRfYmVzdD17bGFuZ3VhZ2U6ci5zZWNvbmRfYmVzdC5sYW5ndWFnZSxyZTpyLnNlY29uZF9iZXN0LnJ9KSl9ZnVuY3Rpb24gcCgpe2lmKCFwLmNhbGxlZCl7cC5jYWxsZWQ9ITA7dmFyIGU9ZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgicHJlIGNvZGUiKTtmLmZvckVhY2guY2FsbChlLG8pfX1mdW5jdGlvbiBCKGUpe3JldHVybiBlPShlfHwiIikudG9Mb3dlckNhc2UoKSxOW2VdfHxOW2NbZV1dfWZ1bmN0aW9uIE0oZSl7dmFyIG49QihlKTtyZXR1cm4gbiYmIW4uZGlzYWJsZUF1dG9kZXRlY3R9cmV0dXJuIGEuaGlnaGxpZ2h0PUMsYS5oaWdobGlnaHRBdXRvPU8sYS5maXhNYXJrdXA9ZCxhLmhpZ2hsaWdodEJsb2NrPW8sYS5jb25maWd1cmU9ZnVuY3Rpb24oZSl7aD1nKGgsZSl9LGEuaW5pdEhpZ2hsaWdodGluZz1wLGEuaW5pdEhpZ2hsaWdodGluZ09uTG9hZD1mdW5jdGlvbigpe2FkZEV2ZW50TGlzdGVuZXIoIkRPTUNvbnRlbnRMb2FkZWQiLHAsITEpLGFkZEV2ZW50TGlzdGVuZXIoImxvYWQiLHAsITEpfSxhLnJlZ2lzdGVyTGFuZ3VhZ2U9ZnVuY3Rpb24obixlKXt2YXIgdD1OW25dPWUoYSk7aSh0KSx0LmFsaWFzZXMmJnQuYWxpYXNlcy5mb3JFYWNoKGZ1bmN0aW9uKGUpe2NbZV09bn0pfSxhLmxpc3RMYW5ndWFnZXM9ZnVuY3Rpb24oKXtyZXR1cm4gdShOKX0sYS5nZXRMYW5ndWFnZT1CLGEuYXV0b0RldGVjdGlvbj1NLGEuaW5oZXJpdD1nLGEuSVI9YS5JREVOVF9SRT0iW2EtekEtWl1cXHcqIixhLlVJUj1hLlVOREVSU0NPUkVfSURFTlRfUkU9IlthLXpBLVpfXVxcdyoiLGEuTlI9YS5OVU1CRVJfUkU9IlxcYlxcZCsoXFwuXFxkKyk/IixhLkNOUj1hLkNfTlVNQkVSX1JFPSIoLT8pKFxcYjBbeFhdW2EtZkEtRjAtOV0rfChcXGJcXGQrKFxcLlxcZCopP3xcXC5cXGQrKShbZUVdWy0rXT9cXGQrKT8pIixhLkJOUj1hLkJJTkFSWV9OVU1CRVJfUkU9IlxcYigwYlswMV0rKSIsYS5SU1I9YS5SRV9TVEFSVEVSU19SRT0iIXwhPXwhPT18JXwlPXwmfCYmfCY9fFxcKnxcXCo9fFxcK3xcXCs9fCx8LXwtPXwvPXwvfDp8O3w8PHw8PD18PD18PHw9PT18PT18PXw+Pj49fD4+PXw+PXw+Pj58Pj58PnxcXD98XFxbfFxce3xcXCh8XFxefFxcXj18XFx8fFxcfD18XFx8XFx8fH4iLGEuQkU9YS5CQUNLU0xBU0hfRVNDQVBFPXtiOiJcXFxcW1xcc1xcU10iLHI6MH0sYS5BU009YS5BUE9TX1NUUklOR19NT0RFPXtjTjoic3RyaW5nIixiOiInIixlOiInIixpOiJcXG4iLGM6W2EuQkVdfSxhLlFTTT1hLlFVT1RFX1NUUklOR19NT0RFPXtjTjoic3RyaW5nIixiOiciJyxlOiciJyxpOiJcXG4iLGM6W2EuQkVdfSxhLlBXTT1hLlBIUkFTQUxfV09SRFNfTU9ERT17YjovXGIoYXxhbnx0aGV8YXJlfEknbXxpc24ndHxkb24ndHxkb2Vzbid0fHdvbid0fGJ1dHxqdXN0fHNob3VsZHxwcmV0dHl8c2ltcGx5fGVub3VnaHxnb25uYXxnb2luZ3x3dGZ8c298c3VjaHx3aWxsfHlvdXx5b3VyfHRoZXl8bGlrZXxtb3JlKVxiL30sYS5DPWEuQ09NTUVOVD1mdW5jdGlvbihlLG4sdCl7dmFyIHI9YS5pbmhlcml0KHtjTjoiY29tbWVudCIsYjplLGU6bixjOltdfSx0fHx7fSk7cmV0dXJuIHIuYy5wdXNoKGEuUFdNKSxyLmMucHVzaCh7Y046ImRvY3RhZyIsYjoiKD86VE9ET3xGSVhNRXxOT1RFfEJVR3xYWFgpOiIscjowfSkscn0sYS5DTENNPWEuQ19MSU5FX0NPTU1FTlRfTU9ERT1hLkMoIi8vIiwiJCIpLGEuQ0JDTT1hLkNfQkxPQ0tfQ09NTUVOVF9NT0RFPWEuQygiL1xcKiIsIlxcKi8iKSxhLkhDTT1hLkhBU0hfQ09NTUVOVF9NT0RFPWEuQygiIyIsIiQiKSxhLk5NPWEuTlVNQkVSX01PREU9e2NOOiJudW1iZXIiLGI6YS5OUixyOjB9LGEuQ05NPWEuQ19OVU1CRVJfTU9ERT17Y046Im51bWJlciIsYjphLkNOUixyOjB9LGEuQk5NPWEuQklOQVJZX05VTUJFUl9NT0RFPXtjTjoibnVtYmVyIixiOmEuQk5SLHI6MH0sYS5DU1NOTT1hLkNTU19OVU1CRVJfTU9ERT17Y046Im51bWJlciIsYjphLk5SKyIoJXxlbXxleHxjaHxyZW18dnd8dmh8dm1pbnx2bWF4fGNtfG1tfGlufHB0fHBjfHB4fGRlZ3xncmFkfHJhZHx0dXJufHN8bXN8SHp8a0h6fGRwaXxkcGNtfGRwcHgpPyIscjowfSxhLlJNPWEuUkVHRVhQX01PREU9e2NOOiJyZWdleHAiLGI6L1wvLyxlOi9cL1tnaW11eV0qLyxpOi9cbi8sYzpbYS5CRSx7YjovXFsvLGU6L1xdLyxyOjAsYzpbYS5CRV19XX0sYS5UTT1hLlRJVExFX01PREU9e2NOOiJ0aXRsZSIsYjphLklSLHI6MH0sYS5VVE09YS5VTkRFUlNDT1JFX1RJVExFX01PREU9e2NOOiJ0aXRsZSIsYjphLlVJUixyOjB9LGEuTUVUSE9EX0dVQVJEPXtiOiJcXC5cXHMqIithLlVJUixyOjB9LGF9KTtobGpzLnJlZ2lzdGVyTGFuZ3VhZ2UoInhtbCIsZnVuY3Rpb24ocyl7dmFyIGU9e2VXOiEwLGk6LzwvLHI6MCxjOlt7Y046ImF0dHIiLGI6IltBLVphLXowLTlcXC5fOi1dKyIscjowfSx7YjovPVxzKi8scjowLGM6W3tjTjoic3RyaW5nIixlbmRzUGFyZW50OiEwLHY6W3tiOi8iLyxlOi8iL30se2I6LycvLGU6LycvfSx7YjovW15ccyInPTw+YF0rL31dfV19XX07cmV0dXJue2FsaWFzZXM6WyJodG1sIiwieGh0bWwiLCJyc3MiLCJhdG9tIiwieGpiIiwieHNkIiwieHNsIiwicGxpc3QiLCJ3c2YiXSxjSTohMCxjOlt7Y046Im1ldGEiLGI6IjwhRE9DVFlQRSIsZToiPiIscjoxMCxjOlt7YjoiXFxbIixlOiJcXF0ifV19LHMuQygiXHgzYyEtLSIsIi0tXHgzZSIse3I6MTB9KSx7YjoiPFxcIVxcW0NEQVRBXFxbIixlOiJcXF1cXF0+IixyOjEwfSx7Y046Im1ldGEiLGI6LzxcP3htbC8sZTovXD8+LyxyOjEwfSx7YjovPFw/KHBocCk/LyxlOi9cPz4vLHNMOiJwaHAiLGM6W3tiOiIvXFwqIixlOiJcXCovIixza2lwOiEwfSx7YjonYiInLGU6JyInLHNraXA6ITB9LHtiOiJiJyIsZToiJyIsc2tpcDohMH0scy5pbmhlcml0KHMuQVNNLHtpOm51bGwsY046bnVsbCxjOm51bGwsc2tpcDohMH0pLHMuaW5oZXJpdChzLlFTTSx7aTpudWxsLGNOOm51bGwsYzpudWxsLHNraXA6ITB9KV19LHtjTjoidGFnIixiOiI8c3R5bGUoPz1cXHN8PnwkKSIsZToiPiIsazp7bmFtZToic3R5bGUifSxjOltlXSxzdGFydHM6e2U6Ijwvc3R5bGU+IixyRTohMCxzTDpbImNzcyIsInhtbCJdfX0se2NOOiJ0YWciLGI6IjxzY3JpcHQoPz1cXHN8PnwkKSIsZToiPiIsazp7bmFtZToic2NyaXB0In0sYzpbZV0sc3RhcnRzOntlOiI8XC9zY3JpcHQ+IixyRTohMCxzTDpbImFjdGlvbnNjcmlwdCIsImphdmFzY3JpcHQiLCJoYW5kbGViYXJzIiwieG1sIiwidmJzY3JpcHQiXX19LHtjTjoidGFnIixiOiI8Lz8iLGU6Ii8/PiIsYzpbe2NOOiJuYW1lIixiOi9bXlwvPjxcc10rLyxyOjB9LGVdfV19fSk7aGxqcy5yZWdpc3Rlckxhbmd1YWdlKCJtYXJrZG93biIsZnVuY3Rpb24oZSl7cmV0dXJue2FsaWFzZXM6WyJtZCIsIm1rZG93biIsIm1rZCJdLGM6W3tjTjoic2VjdGlvbiIsdjpbe2I6Il4jezEsNn0iLGU6IiQifSx7YjoiXi4rP1xcbls9LV17Mix9JCJ9XX0se2I6IjwiLGU6Ij4iLHNMOiJ4bWwiLHI6MH0se2NOOiJidWxsZXQiLGI6Il5cXHMqKFsqKy1dfChcXGQrXFwuKSlcXHMrIn0se2NOOiJzdHJvbmciLGI6IlsqX117Mn0uKz9bKl9dezJ9In0se2NOOiJlbXBoYXNpcyIsdjpbe2I6IlxcKi4rP1xcKiJ9LHtiOiJfLis/XyIscjowfV19LHtjTjoicXVvdGUiLGI6Il4+XFxzKyIsZToiJCJ9LHtjTjoiY29kZSIsdjpbe2I6Il5gYGB3KnMqJCIsZToiXmBgYHMqJCJ9LHtiOiJgLis/YCJ9LHtiOiJeKCB7NH18XHQpIixlOiIkIixyOjB9XX0se2I6Il5bLVxcKl17Myx9IixlOiIkIn0se2I6IlxcWy4rP1xcXVtcXChcXFtdLio/W1xcKVxcXV0iLHJCOiEwLGM6W3tjTjoic3RyaW5nIixiOiJcXFsiLGU6IlxcXSIsZUI6ITAsckU6ITAscjowfSx7Y046ImxpbmsiLGI6IlxcXVxcKCIsZToiXFwpIixlQjohMCxlRTohMH0se2NOOiJzeW1ib2wiLGI6IlxcXVxcWyIsZToiXFxdIixlQjohMCxlRTohMH1dLHI6MTB9LHtiOi9eXFtbXlxuXStcXTovLHJCOiEwLGM6W3tjTjoic3ltYm9sIixiOi9cWy8sZTovXF0vLGVCOiEwLGVFOiEwfSx7Y046ImxpbmsiLGI6LzpccyovLGU6LyQvLGVCOiEwfV19XX19KTtobGpzLnJlZ2lzdGVyTGFuZ3VhZ2UoImRhcnQiLGZ1bmN0aW9uKGUpe3ZhciB0PXtjTjoic3Vic3QiLHY6W3tiOiJcXCRbQS1aYS16MC05X10rIn1dfSxyPXtjTjoic3Vic3QiLHY6W3tiOiJcXCR7IixlOiJ9In1dLGs6InRydWUgZmFsc2UgbnVsbCB0aGlzIGlzIG5ldyBzdXBlciJ9LG49e2NOOiJzdHJpbmciLHY6W3tiOiJyJycnIixlOiInJycifSx7YjonciIiIicsZTonIiIiJ30se2I6InInIixlOiInIixpOiJcXG4ifSx7YjonciInLGU6JyInLGk6IlxcbiJ9LHtiOiInJyciLGU6IicnJyIsYzpbZS5CRSx0LHJdfSx7YjonIiIiJyxlOiciIiInLGM6W2UuQkUsdCxyXX0se2I6IiciLGU6IiciLGk6IlxcbiIsYzpbZS5CRSx0LHJdfSx7YjonIicsZTonIicsaToiXFxuIixjOltlLkJFLHQscl19XX07ci5jPVtlLkNOTSxuXTtyZXR1cm57azp7a2V5d29yZDoiYXNzZXJ0IGFzeW5jIGF3YWl0IGJyZWFrIGNhc2UgY2F0Y2ggY2xhc3MgY29uc3QgY29udGludWUgZGVmYXVsdCBkbyBlbHNlIGVudW0gZXh0ZW5kcyBmYWxzZSBmaW5hbCBmaW5hbGx5IGZvciBpZiBpbiBpcyBuZXcgbnVsbCByZXRocm93IHJldHVybiBzdXBlciBzd2l0Y2ggc3luYyB0aGlzIHRocm93IHRydWUgdHJ5IHZhciB2b2lkIHdoaWxlIHdpdGggeWllbGQgYWJzdHJhY3QgYXMgZHluYW1pYyBleHBvcnQgZXh0ZXJuYWwgZmFjdG9yeSBnZXQgaW1wbGVtZW50cyBpbXBvcnQgbGlicmFyeSBvcGVyYXRvciBwYXJ0IHNldCBzdGF0aWMgdHlwZWRlZiIsYnVpbHRfaW46InByaW50IENvbXBhcmFibGUgRGF0ZVRpbWUgRHVyYXRpb24gRnVuY3Rpb24gSXRlcmFibGUgSXRlcmF0b3IgTGlzdCBNYXAgTWF0Y2ggTnVsbCBPYmplY3QgUGF0dGVybiBSZWdFeHAgU2V0IFN0b3B3YXRjaCBTdHJpbmcgU3RyaW5nQnVmZmVyIFN0cmluZ1NpbmsgU3ltYm9sIFR5cGUgVXJpIGJvb2wgZG91YmxlIGludCBudW0gZG9jdW1lbnQgd2luZG93IHF1ZXJ5U2VsZWN0b3IgcXVlcnlTZWxlY3RvckFsbCBFbGVtZW50IEVsZW1lbnRMaXN0In0sYzpbbixlLkMoIi9cXCpcXCoiLCJcXCovIix7c0w6Im1hcmtkb3duIn0pLGUuQygiLy8vIiwiJCIse3NMOiJtYXJrZG93biJ9KSxlLkNMQ00sZS5DQkNNLHtjTjoiY2xhc3MiLGJLOiJjbGFzcyBpbnRlcmZhY2UiLGU6InsiLGVFOiEwLGM6W3tiSzoiZXh0ZW5kcyBpbXBsZW1lbnRzIn0sZS5VVE1dfSxlLkNOTSx7Y046Im1ldGEiLGI6IkBbQS1aYS16XSsifSx7YjoiPT4ifV19fSk7";
+
+String decodeHighlightJs() => String.fromCharCodes(base64Decode(_highlightJs));
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/info_builder.dart b/pkg/analysis_server/lib/src/edit/nnbd_migration/info_builder.dart
index acd9c24..694a210 100644
--- a/pkg/analysis_server/lib/src/edit/nnbd_migration/info_builder.dart
+++ b/pkg/analysis_server/lib/src/edit/nnbd_migration/info_builder.dart
@@ -6,23 +6,49 @@
 import 'package:analysis_server/src/edit/fix/dartfix_listener.dart';
 import 'package:analysis_server/src/edit/nnbd_migration/instrumentation_information.dart';
 import 'package:analysis_server/src/edit/nnbd_migration/migration_info.dart';
+import 'package:analysis_server/src/edit/nnbd_migration/offset_mapper.dart';
 import 'package:analyzer/dart/analysis/results.dart';
 import 'package:analyzer/dart/analysis/session.dart';
+import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer_plugin/protocol/protocol_common.dart';
+import 'package:analyzer_plugin/protocol/protocol_common.dart'
+    show Location, SourceEdit, SourceFileEdit;
+import 'package:nnbd_migration/instrumentation.dart';
+import 'package:nnbd_migration/nnbd_migration.dart';
+
+class FixInfo {
+  /// The fix being described.
+  SingleNullabilityFix fix;
+
+  /// The reasons why the fix was made.
+  List<FixReasonInfo> reasons;
+
+  /// Initialize information about a fix from the given map [entry].
+  FixInfo(this.fix, this.reasons);
+}
 
 /// A builder used to build the migration information for a library.
 class InfoBuilder {
-  /// The analysis session used to get information about libraries.
-  AnalysisServer server;
+  /// The instrumentation information gathered while the migration engine was
+  /// running.
+  final InstrumentationInformation info;
+
+  /// The listener used to gather the changes to be applied.
+  final DartFixListener listener;
+
+  /// A map from the path of a compilation unit to the information about that
+  /// unit.
+  final Map<String, UnitInfo> unitMap = {};
 
   /// Initialize a newly created builder.
-  InfoBuilder(this.server);
+  InfoBuilder(this.info, this.listener);
+
+  /// The analysis server used to get information about libraries.
+  AnalysisServer get server => listener.server;
 
   /// Return the migration information for all of the libraries that were
   /// migrated.
-  Future<List<LibraryInfo>> explainMigration(
-      InstrumentationInformation info, DartFixListener listener) async {
+  Future<List<LibraryInfo>> explainMigration() async {
     Map<Source, SourceInformation> sourceInfo = info.sourceInformation;
     List<LibraryInfo> libraries = [];
     for (Source source in sourceInfo.keys) {
@@ -38,6 +64,42 @@
     return libraries;
   }
 
+  /// Compute the details for the fix with the given [fixInfo].
+  List<RegionDetail> _computeDetails(FixInfo fixInfo) {
+    List<RegionDetail> details = [];
+    for (FixReasonInfo reason in fixInfo.reasons) {
+      if (reason is NullabilityNodeInfo) {
+        for (EdgeInfo edge in reason.upstreamEdges) {
+          EdgeOriginInfo origin = info.edgeOrigin[edge];
+          if (origin != null) {
+            AstNode node = origin.node;
+            if (node.parent is ArgumentList) {
+              if (node is NullLiteral) {
+                details.add(RegionDetail(
+                    'null is explicitly passed as an argument.',
+                    _targetFor(origin)));
+              } else {
+                details.add(RegionDetail(
+                    'A nullable value is explicitly passed as an argument.',
+                    _targetFor(origin)));
+              }
+            } else {
+              details.add(RegionDetail(
+                  'A nullable value is assigned.', _targetFor(origin)));
+            }
+          }
+        }
+      } else if (reason is EdgeInfo) {
+        // TODO(brianwilkerson) Implement this after finding an example whose
+        //  reason is an edge.
+      } else {
+        throw UnimplementedError(
+            'Unexpected class of reason: ${reason.runtimeType}');
+      }
+    }
+    return details;
+  }
+
   /// Return the migration information for the given library.
   LibraryInfo _explainLibrary(
       ParsedLibraryResult result,
@@ -47,50 +109,76 @@
     List<UnitInfo> units = [];
     for (ParsedUnitResult unit in result.units) {
       SourceFileEdit edit = listener.sourceChange.getFileEdit(unit.path);
-      units.add(_explainUnit(unit, edit));
+      units.add(_explainUnit(sourceInfo, unit, edit));
     }
     return LibraryInfo(units);
   }
 
   /// Return the migration information for the given unit.
-  UnitInfo _explainUnit(ParsedUnitResult result, SourceFileEdit fileEdit) {
-    List<RegionInfo> regions = [];
+  UnitInfo _explainUnit(SourceInformation sourceInfo, ParsedUnitResult result,
+      SourceFileEdit fileEdit) {
+    UnitInfo unitInfo = _unitForPath(result.path);
     String content = result.content;
     // [fileEdit] is null when a file has no edits.
-    if (fileEdit == null) {
-      return UnitInfo(result.path, content, regions);
-    }
-    List<SourceEdit> edits = fileEdit.edits;
-    edits.sort((first, second) => first.offset.compareTo(second.offset));
-    // Compute the deltas for the regions that will be computed as we apply the
-    // edits. We need the deltas because the offsets to the regions are relative
-    // to the edited source, but the edits are being applied in reverse order so
-    // the offset in the pre-edited source will not match the offset in the
-    // post-edited source. The deltas compensate for that difference.
-    List<int> deltas = [];
-    int previousDelta = 0;
-    for (SourceEdit edit in edits) {
-      deltas.add(previousDelta);
-      previousDelta += (edit.replacement.length - edit.length);
-    }
-    // Apply edits in reverse order and build the regions.
-    int index = edits.length - 1;
-    for (SourceEdit edit in edits.reversed) {
-      int offset = edit.offset;
-      int length = edit.length;
-      String replacement = edit.replacement;
-      int end = offset + length;
-      int delta = deltas[index--];
-      // Insert the replacement text without deleting the replaced text.
-      content = content.replaceRange(end, end, replacement);
-      if (length > 0) {
-        // TODO(brianwilkerson) Create a sensible explanation.
-        regions.add(RegionInfo(offset + delta, length, 'removed'));
+    if (fileEdit != null) {
+      List<RegionInfo> regions = unitInfo.regions;
+      List<SourceEdit> edits = fileEdit.edits;
+      edits.sort((first, second) => first.offset.compareTo(second.offset));
+      OffsetMapper mapper = OffsetMapper.forEdits(edits);
+      // Apply edits in reverse order and build the regions.
+      for (SourceEdit edit in edits.reversed) {
+        int offset = edit.offset;
+        int length = edit.length;
+        String replacement = edit.replacement;
+        int end = offset + length;
+        // Insert the replacement text without deleting the replaced text.
+        content = content.replaceRange(end, end, replacement);
+        FixInfo fixInfo = _findFixInfo(sourceInfo, offset);
+        if (fixInfo != null) {
+          String explanation = '${fixInfo.fix.description.appliedMessage}.';
+          List<RegionDetail> details = _computeDetails(fixInfo);
+          if (length > 0) {
+            regions.add(
+                RegionInfo(mapper.map(offset), length, explanation, details));
+          }
+          regions.add(RegionInfo(
+              mapper.map(end), replacement.length, explanation, details));
+        }
       }
-      // TODO(brianwilkerson) Create a sensible explanation.
-      regions.add(RegionInfo(end + delta, replacement.length, 'added'));
+      regions.sort((first, second) => first.offset.compareTo(second.offset));
+      unitInfo.offsetMapper = mapper;
     }
-    regions.sort((first, second) => first.offset.compareTo(second.offset));
-    return UnitInfo(result.path, content, regions);
+    unitInfo.content = content;
+    return unitInfo;
+  }
+
+  /// Return information about the fix that was applied at the given [offset],
+  /// or `null` if the information could not be found. The information is
+  /// extracted from the [sourceInfo].
+  FixInfo _findFixInfo(SourceInformation sourceInfo, int offset) {
+    for (MapEntry<SingleNullabilityFix, List<FixReasonInfo>> entry
+        in sourceInfo.fixes.entries) {
+      Location location = entry.key.location;
+      if (location.offset == offset) {
+        return FixInfo(entry.key, entry.value);
+      }
+    }
+    return null;
+  }
+
+  /// Return the navigation target corresponding to the given [origin].
+  NavigationTarget _targetFor(EdgeOriginInfo origin) {
+    AstNode node = origin.node;
+    String filePath = origin.source.fullName;
+    UnitInfo unitInfo = _unitForPath(filePath);
+    NavigationTarget target =
+        NavigationTarget(filePath, node.offset, node.length);
+    unitInfo.targets.add(target);
+    return target;
+  }
+
+  /// Return the unit info for the file at the given [path].
+  UnitInfo _unitForPath(String path) {
+    return unitMap.putIfAbsent(path, () => UnitInfo(path));
   }
 }
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/instrumentation_listener.dart b/pkg/analysis_server/lib/src/edit/nnbd_migration/instrumentation_listener.dart
index bb3f1d0..b51c370 100644
--- a/pkg/analysis_server/lib/src/edit/nnbd_migration/instrumentation_listener.dart
+++ b/pkg/analysis_server/lib/src/edit/nnbd_migration/instrumentation_listener.dart
@@ -31,7 +31,8 @@
 
   @override
   void fix(SingleNullabilityFix fix, Iterable<FixReasonInfo> reasons) {
-    _sourceInfo(fix.source).fixes[fix] = reasons.toList();
+    _sourceInfo(fix.source).fixes[fix] =
+        reasons.where((reason) => reason != null).toList();
   }
 
   @override
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/instrumentation_renderer.dart b/pkg/analysis_server/lib/src/edit/nnbd_migration/instrumentation_renderer.dart
index 5b14508..6735746 100644
--- a/pkg/analysis_server/lib/src/edit/nnbd_migration/instrumentation_renderer.dart
+++ b/pkg/analysis_server/lib/src/edit/nnbd_migration/instrumentation_renderer.dart
@@ -1,19 +1,31 @@
 import 'package:analysis_server/src/edit/nnbd_migration/migration_info.dart';
+import 'package:meta/meta.dart';
 import 'package:mustache/mustache.dart' as mustache;
+import 'package:path/path.dart' as path;
 
-/// Instrumentation display output for a library that was migrated to use non-nullable types.
+/// Instrumentation display output for a library that was migrated to use
+/// non-nullable types.
 class InstrumentationRenderer {
   /// Display information for a library.
-  final LibraryInfo info;
+  final LibraryInfo libraryInfo;
+
+  /// Information for a whole migration, so that libraries can reference each
+  /// other.
+  final MigrationInfo migrationInfo;
 
   /// Creates an output object for the given library info.
-  InstrumentationRenderer(this.info);
+  InstrumentationRenderer(this.libraryInfo, this.migrationInfo);
 
-  /// Builds an HTML view of the instrumentation information in [info].
+  /// Builds an HTML view of the instrumentation information in [libraryInfo].
   String render() {
     int previousIndex = 0;
-    Map<String, dynamic> mustacheContext = {'units': <Map<String, dynamic>>[]};
-    for (var compilationUnit in info.units) {
+    Map<String, dynamic> mustacheContext = {
+      'units': <Map<String, dynamic>>[],
+      'links': migrationInfo.libraryLinks(libraryInfo),
+      'highlightJsPath': migrationInfo.highlightJsPath(libraryInfo),
+      'highlightStylePath': migrationInfo.highlightStylePath(libraryInfo),
+    };
+    for (var compilationUnit in libraryInfo.units) {
       // List of Mustache context for both unmodified and modified regions:
       //
       // * 'modified': Whether this region represents modified source, or
@@ -55,13 +67,70 @@
   }
 }
 
+/// A class storing rendering information for an entire migration report.
+///
+/// This generally provides one [InstrumentationRenderer] (for one library)
+/// with information about the rest of the libraries represented in the
+/// instrumentation output.
+class MigrationInfo {
+  /// The information about the libraries that are are migrated.
+  final List<LibraryInfo> libraries;
+
+  /// The resource provider's path context.
+  final path.Context pathContext;
+
+  /// The filesystem root used to create relative paths for each unit.
+  final String includedRoot;
+
+  MigrationInfo(this.libraries, this.pathContext, this.includedRoot);
+
+  /// Generate mustache context for library links, for navigation in the
+  /// instrumentation document for [thisLibrary].
+  List<Map<String, Object>> libraryLinks(LibraryInfo thisLibrary) {
+    return [
+      for (var library in libraries)
+        {
+          'name': _computeName(library),
+          'isLink': library != thisLibrary,
+          if (library != thisLibrary)
+            'href': _pathTo(library, source: thisLibrary)
+        }
+    ];
+  }
+
+  /// Return the path to [library] from [includedRoot], to be used as a display
+  /// name for a library.
+  String _computeName(LibraryInfo library) =>
+      pathContext.relative(library.units.first.path, from: includedRoot);
+
+  /// The path to [target], relative to [from].
+  String _pathTo(LibraryInfo target, {@required LibraryInfo source}) {
+    assert(target.units.isNotEmpty);
+    assert(source.units.isNotEmpty);
+    String targetPath =
+        pathContext.setExtension(target.units.first.path, '.html');
+    String sourceDir = pathContext.dirname(source.units.first.path);
+    return pathContext.relative(targetPath, from: sourceDir);
+  }
+
+  /// The path to the highlight.js script, relative to [libraryInfo].
+  String highlightJsPath(LibraryInfo libraryInfo) =>
+      pathContext.relative(pathContext.join(includedRoot, 'highlight.pack.js'),
+          from: pathContext.dirname(libraryInfo.units.first.path));
+
+  /// The path to the highlight.js stylesheet, relative to [libraryInfo].
+  String highlightStylePath(LibraryInfo libraryInfo) =>
+      pathContext.relative(pathContext.join(includedRoot, 'androidstudio.css'),
+          from: pathContext.dirname(libraryInfo.units.first.path));
+}
+
 /// A mustache template for one library's instrumentation output.
 mustache.Template _template = mustache.Template(r'''
 <html>
   <head>
     <title>Non-nullable fix instrumentation report</title>
-    <script src="highlight.pack.js"></script>
-    <link rel="stylesheet" href="styles/androidstudio.css">
+    <script src="{{ highlightJsPath }}"></script>
+    <link rel="stylesheet" href="{{ highlightStylePath }}">
     <style>
 body {
   font-family: sans-serif;
@@ -75,15 +144,13 @@
 
 .content {
   font-family: monospace;
-  white-space: pre;
-}
-
-.content.highlighting {
   position: relative;
+  white-space: pre;
 }
 
 .regions {
   position: absolute;
+  left: 0.5em;
   top: 0.5em;
   /* The content of the regions is not visible; the user instead will see the
    * highlighted copy of the content. */
@@ -105,12 +172,15 @@
   border: solid 2px #999;
   color: #333;
   cursor: auto;
-  left: 50%;
-  margin-left: -100px;
+  font-family: sans-serif;
+  font-size: 0.8em;
+  left: 0;
+  margin-left: 0;
   padding: 1px;
   position: absolute;
   top: 100%;
   visibility: hidden;
+  white-space: normal;
   width: 200px;
   z-index: 1;
 }
@@ -122,16 +192,25 @@
   </head>
   <body>
     <h1>Non-nullable fix instrumentation report</h1>
-    <p><em>Well-written introduction to this report.</em></p>'''
-    '    {{# units }}'
-    '      <h2>{{{ path }}}</h2>'
-    '      <div class="content highlighting">'
+    <p><em>Well-written introduction to this report.</em></p>
+    <div class="navigation">
+      {{# links }}
+        {{# isLink }}<a href="{{ href }}">{{ name }}</a>{{/ isLink }}
+        {{^ isLink }}{{ name }}{{/ isLink }}
+        <br />
+      {{/ links }}
+    </div>
+    {{# units }}'''
+    '<h2>{{{ path }}}</h2>'
+    '<div class="content">'
+    '<div class="highlighting">'
     '{{! These regions are written out, unmodified, as they need to be found }}'
     '{{! in one simple text string for highlight.js to hightlight them. }}'
     '{{# regions }}'
     '{{ content }}'
     '{{/ regions }}'
-    '      <div class="regions">'
+    '</div>'
+    '<div class="regions">'
     '{{! The regions are then printed again, overlaying the first copy of the }}'
     '{{! content, to provide tooltips for modified regions. }}'
     '{{# regions }}'
@@ -140,13 +219,14 @@
     '<span class="tooltip">{{explanation}}</span></span>{{/ modified }}'
     '{{/ regions }}'
     '</div></div>'
-    '    {{/ units }}'
-    '    <script lang="javascript">'
-    'document.addEventListener("DOMContentLoaded", (event) => {'
-    '  document.querySelectorAll(".highlighting").forEach((block) => {'
-    '    hljs.highlightBlock(block);'
-    '  });'
-    '});'
-    '    </script>'
-    '  </body>'
-    '</html>');
+    r'''
+    {{/ units }}
+    <script lang="javascript">
+document.addEventListener("DOMContentLoaded", (event) => {
+  document.querySelectorAll(".highlighting").forEach((block) => {
+    hljs.highlightBlock(block);
+  });
+});
+    </script>
+  </body>
+</html>''');
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/migration_info.dart b/pkg/analysis_server/lib/src/edit/nnbd_migration/migration_info.dart
index 2f872624..7a66011 100644
--- a/pkg/analysis_server/lib/src/edit/nnbd_migration/migration_info.dart
+++ b/pkg/analysis_server/lib/src/edit/nnbd_migration/migration_info.dart
@@ -2,6 +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:analysis_server/src/edit/nnbd_migration/offset_mapper.dart';
+import 'package:analyzer/src/generated/utilities_general.dart';
+
 /// The migration information associated with a single library.
 class LibraryInfo {
   /// The information about the units in the library. The information about the
@@ -12,6 +15,45 @@
   LibraryInfo(this.units);
 }
 
+/// A location to which a user might want to navigate.
+class NavigationTarget {
+  /// The file containing the anchor.
+  final String filePath;
+
+  /// The offset of the anchor.
+  final int offset;
+
+  /// The length of the anchor.
+  final int length;
+
+  /// Initialize a newly created anchor.
+  NavigationTarget(this.filePath, this.offset, this.length);
+
+  @override
+  int get hashCode => JenkinsSmiHash.hash3(filePath.hashCode, offset, length);
+
+  @override
+  bool operator ==(other) {
+    return other is NavigationTarget &&
+        other.filePath == filePath &&
+        other.offset == offset &&
+        other.length == length;
+  }
+}
+
+/// An additional detail related to a region.
+class RegionDetail {
+  /// A textual description of the detail.
+  final String description;
+
+  /// The location associated with the detail, such as the location of an
+  /// argument that's assigned to a parameter.
+  final NavigationTarget target;
+
+  /// Initialize a newly created detail.
+  RegionDetail(this.description, this.target);
+}
+
 /// A description of an explanation associated with a region of code that was
 /// modified.
 class RegionInfo {
@@ -24,8 +66,11 @@
   /// The explanation to be displayed for the region.
   final String explanation;
 
+  /// Details that further explain why a change was made.
+  final List<RegionDetail> details;
+
   /// Initialize a newly created region.
-  RegionInfo(this.offset, this.length, this.explanation);
+  RegionInfo(this.offset, this.length, this.explanation, this.details);
 }
 
 /// The migration information associated with a single compilation unit.
@@ -34,12 +79,20 @@
   final String path;
 
   /// The content of unit.
-  final String content;
+  String content;
 
   /// The information about the regions that have an explanation associated with
-  /// them.
-  final List<RegionInfo> regions;
+  /// them. The offsets in these regions are offsets into the post-edit content.
+  final List<RegionInfo> regions = [];
+
+  /// The navigation targets that are located in this file. The offsets in these
+  /// targets are offsets into the pre-edit content.
+  final Set<NavigationTarget> targets = {};
+
+  /// The object used to map the pre-edit offsets in the navigation targets to
+  /// the post-edit offsets in the [content].
+  OffsetMapper offsetMapper = OffsetMapper.identity;
 
   /// Initialize a newly created unit.
-  UnitInfo(this.path, this.content, this.regions);
+  UnitInfo(this.path);
 }
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/offset_mapper.dart b/pkg/analysis_server/lib/src/edit/nnbd_migration/offset_mapper.dart
new file mode 100644
index 0000000..24d2c3e
--- /dev/null
+++ b/pkg/analysis_server/lib/src/edit/nnbd_migration/offset_mapper.dart
@@ -0,0 +1,73 @@
+// 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_plugin/protocol/protocol_common.dart';
+
+/// An object that can map the offsets before a sequence of edits to the offsets
+/// after applying the edits.
+abstract class OffsetMapper {
+  /// A mapper used for files that were not modified.
+  static OffsetMapper identity = _IdentityMapper();
+
+  /// Return a mapper representing the file modified by the given [edits].
+  factory OffsetMapper.forEdits(List<SourceEdit> edits) => _EditMapper(edits);
+
+  /// Return the post-edit offset that corresponds to the given pre-edit
+  /// [offset].
+  int map(int offset);
+}
+
+/// A mapper used for files that were modified by a set of edits.
+class _EditMapper implements OffsetMapper {
+  /// A list whose elements are the highest pre-edit offset for which the
+  /// corresponding element of [_deltas] should be applied.
+  List<int> _offsets = [];
+
+  /// A list whose elements are the deltas to be applied for all pre-edit
+  /// offsets that are less than or equal to the corresponding element of
+  /// [_offsets].
+  List<int> _deltas = [];
+
+  /// Initialize a newly created mapper based on the given set of [edits].
+  _EditMapper(List<SourceEdit> edits) {
+    _initializeDeltas(edits);
+  }
+
+  @override
+  int map(int offset) => offset + _deltaFor(offset);
+
+  /// Return the delta to be added to the pre-edit [offset] to produce the
+  /// post-edit offset.
+  int _deltaFor(int offset) {
+    for (int i = 0; i < _offsets.length; i++) {
+      int currentOffset = _offsets[i];
+      if (currentOffset >= offset || currentOffset < 0) {
+        return _deltas[i];
+      }
+    }
+    // We should never get here because [_initializeDeltas] always adds an
+    // offset/delta pair at the end of the list whose offset is less than zero.
+    return 0;
+  }
+
+  /// Initialize the list of old offsets and deltas used by [_deltaFor].
+  void _initializeDeltas(List<SourceEdit> edits) {
+    int previousDelta = 0;
+    for (SourceEdit edit in edits) {
+      int offset = edit.offset;
+      int length = edit.length;
+      _offsets.add(offset);
+      _deltas.add(previousDelta);
+      previousDelta += (edit.replacement.length - length);
+    }
+    _offsets.add(-1);
+    _deltas.add(previousDelta);
+  }
+}
+
+/// A mapper used for files that were not modified.
+class _IdentityMapper implements OffsetMapper {
+  @override
+  int map(int offset) => offset;
+}
diff --git a/pkg/analysis_server/test/analysis/notification_analyzedFiles_test.dart b/pkg/analysis_server/test/analysis/notification_analyzed_files_test.dart
similarity index 100%
rename from pkg/analysis_server/test/analysis/notification_analyzedFiles_test.dart
rename to pkg/analysis_server/test/analysis/notification_analyzed_files_test.dart
diff --git a/pkg/analysis_server/test/analysis/notification_closingLabels_test.dart b/pkg/analysis_server/test/analysis/notification_closing_labels_test.dart
similarity index 100%
rename from pkg/analysis_server/test/analysis/notification_closingLabels_test.dart
rename to pkg/analysis_server/test/analysis/notification_closing_labels_test.dart
diff --git a/pkg/analysis_server/test/analysis/test_all.dart b/pkg/analysis_server/test/analysis/test_all.dart
index 5b8b7e9..bd8d396 100644
--- a/pkg/analysis_server/test/analysis/test_all.dart
+++ b/pkg/analysis_server/test/analysis/test_all.dart
@@ -4,52 +4,47 @@
 
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
-import 'get_errors_test.dart' as get_errors_test;
-import 'get_hover_test.dart' as get_hover_test;
-import 'get_navigation_test.dart' as get_navigation_test;
-import 'get_signature_test.dart' as get_signature_information_test;
+import 'get_errors_test.dart' as get_errors;
+import 'get_hover_test.dart' as get_hover;
+import 'get_navigation_test.dart' as get_navigation;
+import 'get_signature_test.dart' as get_signature_information;
 import 'notification_analysis_options_test.dart'
-    as notification_analysis_options_test;
-import 'notification_analyzedFiles_test.dart'
-    as notification_analyzedFiles_test;
-import 'notification_closingLabels_test.dart'
-    as notification_closingLabels_test;
-import 'notification_errors_test.dart' as notification_errors_test;
-import 'notification_folding_test.dart' as notification_folding_test;
-import 'notification_highlights2_test.dart' as notification_highlights2_test;
-import 'notification_highlights_test.dart' as notification_highlights_test;
-import 'notification_implemented_test.dart' as notification_implemented_test;
-import 'notification_navigation_test.dart' as notification_navigation_test;
-import 'notification_occurrences_test.dart' as notification_occurrences_test;
-import 'notification_outline_test.dart' as notification_outline_test;
-import 'notification_overrides_test.dart' as notification_overrides_test;
-import 'reanalyze_test.dart' as reanalyze_test;
-import 'set_priority_files_test.dart' as set_priority_files_test;
-import 'update_content_test.dart' as update_content_test;
+    as notification_analysis_options;
+import 'notification_analyzed_files_test.dart' as notification_analyzed_files;
+import 'notification_closing_labels_test.dart' as notification_closing_labels;
+import 'notification_errors_test.dart' as notification_errors;
+import 'notification_folding_test.dart' as notification_folding;
+import 'notification_highlights2_test.dart' as notification_highlights2;
+import 'notification_highlights_test.dart' as notification_highlights;
+import 'notification_implemented_test.dart' as notification_implemented;
+import 'notification_navigation_test.dart' as notification_navigation;
+import 'notification_occurrences_test.dart' as notification_occurrences;
+import 'notification_outline_test.dart' as notification_outline;
+import 'notification_overrides_test.dart' as notification_overrides;
+import 'reanalyze_test.dart' as reanalyze;
+import 'set_priority_files_test.dart' as set_priority_files;
+import 'update_content_test.dart' as update_content;
 
-/**
- * Utility for manually running all tests.
- */
 main() {
   defineReflectiveSuite(() {
-    get_errors_test.main();
-    get_hover_test.main();
-    get_navigation_test.main();
-    get_signature_information_test.main();
-    notification_analysis_options_test.main();
-    notification_analyzedFiles_test.main();
-    notification_closingLabels_test.main();
-    notification_folding_test.main();
-    notification_errors_test.main();
-    notification_highlights2_test.main();
-    notification_highlights_test.main();
-    notification_implemented_test.main();
-    notification_navigation_test.main();
-    notification_occurrences_test.main();
-    notification_outline_test.main();
-    notification_overrides_test.main();
-    reanalyze_test.main();
-    set_priority_files_test.main();
-    update_content_test.main();
+    get_errors.main();
+    get_hover.main();
+    get_navigation.main();
+    get_signature_information.main();
+    notification_analysis_options.main();
+    notification_analyzed_files.main();
+    notification_closing_labels.main();
+    notification_folding.main();
+    notification_errors.main();
+    notification_highlights2.main();
+    notification_highlights.main();
+    notification_implemented.main();
+    notification_navigation.main();
+    notification_occurrences.main();
+    notification_outline.main();
+    notification_overrides.main();
+    reanalyze.main();
+    set_priority_files.main();
+    update_content.main();
   }, name: 'analysis');
 }
diff --git a/pkg/analysis_server/test/domain_edit_dartfix_test.dart b/pkg/analysis_server/test/domain_edit_dartfix_test.dart
index 261ada4..c3fa84f 100644
--- a/pkg/analysis_server/test/domain_edit_dartfix_test.dart
+++ b/pkg/analysis_server/test/domain_edit_dartfix_test.dart
@@ -7,7 +7,6 @@
 import 'package:analysis_server/src/edit/edit_dartfix.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
 import 'package:linter/src/rules.dart';
-import 'package:path/path.dart' as path;
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -300,10 +299,7 @@
     await performFix(
         includedFixes: ['non-nullable'], outputDir: outputDir.path);
     expect(outputDir.exists, true);
-    // TODO(https://github.com/dart-lang/sdk/issues/38574): Fix Windows.
-    if (path.style != path.Style.windows) {
-      expect(outputDir.getChildren(), isNotEmpty);
-    }
+    expect(outputDir.getChildren(), isNotEmpty);
   }
 
   test_dartfix_partFile() async {
diff --git a/pkg/analysis_server/test/edit/nnbd_migration/instrumentation_output_test.dart b/pkg/analysis_server/test/edit/nnbd_migration/instrumentation_output_test.dart
index 30e390f..7865f34 100644
--- a/pkg/analysis_server/test/edit/nnbd_migration/instrumentation_output_test.dart
+++ b/pkg/analysis_server/test/edit/nnbd_migration/instrumentation_output_test.dart
@@ -17,16 +17,26 @@
 
 @reflectiveTest
 class InstrumentationRendererTest extends AbstractAnalysisTest {
+  /// Render [libraryInfo], using a [MigrationInfo] which knows only about this
+  /// library.
+  // TODO(srawlins): Add tests for navigation links, which use multiple
+  // libraries.
+  String renderLibrary(LibraryInfo libraryInfo) {
+    MigrationInfo migrationInfo =
+        MigrationInfo([libraryInfo], resourceProvider.pathContext, '/project');
+    return InstrumentationRenderer(libraryInfo, migrationInfo).render();
+  }
+
   test_outputContainsEachPath() async {
     LibraryInfo info = LibraryInfo([
-      UnitInfo('/lib/a.dart', 'int? a = null;',
-          [RegionInfo(3, 1, 'null was assigned')]),
-      UnitInfo('/lib/part1.dart', 'int? b = null;',
-          [RegionInfo(3, 1, 'null was assigned')]),
-      UnitInfo('/lib/part2.dart', 'int? c = null;',
-          [RegionInfo(3, 1, 'null was assigned')]),
+      unit('/lib/a.dart', 'int? a = null;',
+          regions: [RegionInfo(3, 1, 'null was assigned', [])]),
+      unit('/lib/part1.dart', 'int? b = null;',
+          regions: [RegionInfo(3, 1, 'null was assigned', [])]),
+      unit('/lib/part2.dart', 'int? c = null;',
+          regions: [RegionInfo(3, 1, 'null was assigned', [])]),
     ]);
-    String output = InstrumentationRenderer(info).render();
+    String output = renderLibrary(info);
     expect(output, contains('<h2>/lib/a.dart</h2>'));
     expect(output, contains('<h2>/lib/part1.dart</h2>'));
     expect(output, contains('<h2>/lib/part2.dart</h2>'));
@@ -34,10 +44,10 @@
 
   test_outputContainsEscapedHtml() async {
     LibraryInfo info = LibraryInfo([
-      UnitInfo('/lib/a.dart', 'List<String>? a = null;',
-          [RegionInfo(12, 1, 'null was assigned')]),
+      unit('/lib/a.dart', 'List<String>? a = null;',
+          regions: [RegionInfo(12, 1, 'null was assigned', [])]),
     ]);
-    String output = InstrumentationRenderer(info).render();
+    String output = renderLibrary(info);
     expect(
         output,
         contains('List&lt;String&gt;<span class="region">?'
@@ -46,21 +56,27 @@
 
   test_outputContainsEscapedHtml_ampersand() async {
     LibraryInfo info = LibraryInfo([
-      UnitInfo('/lib/a.dart', 'bool a = true && false;', []),
+      unit('/lib/a.dart', 'bool a = true && false;', regions: []),
     ]);
-    String output = InstrumentationRenderer(info).render();
+    String output = renderLibrary(info);
     expect(output, contains('bool a = true &amp;&amp; false;'));
   }
 
   test_outputContainsModifiedAndUnmodifiedRegions() async {
     LibraryInfo info = LibraryInfo([
-      UnitInfo('/lib/a.dart', 'int? a = null;',
-          [RegionInfo(3, 1, 'null was assigned')]),
+      unit('/lib/a.dart', 'int? a = null;',
+          regions: [RegionInfo(3, 1, 'null was assigned', [])]),
     ]);
-    String output = InstrumentationRenderer(info).render();
+    String output = renderLibrary(info);
     expect(
         output,
         contains('int<span class="region">?'
             '<span class="tooltip">null was assigned</span></span> a = null;'));
   }
+
+  UnitInfo unit(String path, String content, {List<RegionInfo> regions}) {
+    return UnitInfo(path)
+      ..content = content
+      ..regions.addAll(regions);
+  }
 }
diff --git a/pkg/analysis_server/test/integration/analysis/get_errors_nonStandard_sdk_test.dart b/pkg/analysis_server/test/integration/analysis/get_errors_non_standard_sdk_test.dart
similarity index 100%
rename from pkg/analysis_server/test/integration/analysis/get_errors_nonStandard_sdk_test.dart
rename to pkg/analysis_server/test/integration/analysis/get_errors_non_standard_sdk_test.dart
diff --git a/pkg/analysis_server/test/integration/analysis/test_all.dart b/pkg/analysis_server/test/integration/analysis/test_all.dart
index a0cdc52..ea09692 100644
--- a/pkg/analysis_server/test/integration/analysis/test_all.dart
+++ b/pkg/analysis_server/test/integration/analysis/test_all.dart
@@ -6,7 +6,7 @@
 
 import 'analysis_options_test.dart' as analysis_options_test;
 import 'error_test.dart' as error_test;
-import 'get_errors_nonStandard_sdk_test.dart' as get_errors_nonStandard_sdk;
+import 'get_errors_non_standard_sdk_test.dart' as get_errors_non_standard_sdk;
 import 'get_errors_test.dart' as get_errors_test;
 import 'get_hover_test.dart' as get_hover_test;
 import 'get_imported_elements_test.dart' as get_imported_elements_test;
@@ -41,7 +41,7 @@
     analysis_options_test.main();
     error_test.main();
     get_errors_test.main();
-    get_errors_nonStandard_sdk.main();
+    get_errors_non_standard_sdk.main();
     get_library_dependencies_test.main();
     get_hover_test.main();
     get_imported_elements_test.main();
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 aac6231..e1eeec2 100644
--- a/pkg/analysis_server/test/integration/lsp_server/integration_tests.dart
+++ b/pkg/analysis_server/test/integration/lsp_server/integration_tests.dart
@@ -57,8 +57,8 @@
   @override
   Future<ResponseMessage> sendRequestToServer(RequestMessage request) {
     final completer = new Completer<ResponseMessage>();
-    final id = request.id.map(
-        (num) => num, (string) => throw 'String IDs not supported in tests');
+    final id = request.id.map((number) => number,
+        (string) => throw 'String IDs not supported in tests');
     _completers[id] = completer;
 
     client.channel.sendRequest(request);
@@ -87,7 +87,7 @@
     await client.start();
     client.serverToClient.listen((message) {
       if (message is ResponseMessage) {
-        final id = message.id.map((num) => num,
+        final id = message.id.map((number) => number,
             (string) => throw 'String IDs not supported in tests');
 
         final completer = _completers[id];
diff --git a/pkg/analysis_server/test/lsp/workspace_symbols_test.dart b/pkg/analysis_server/test/lsp/workspace_symbols_test.dart
index 8cccc13..1773c51 100644
--- a/pkg/analysis_server/test/lsp/workspace_symbols_test.dart
+++ b/pkg/analysis_server/test/lsp/workspace_symbols_test.dart
@@ -4,7 +4,6 @@
 
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
 import 'package:analysis_server/lsp_protocol/protocol_special.dart';
-import 'package:analyzer/src/dart/analysis/driver.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -12,9 +11,7 @@
 
 main() {
   defineReflectiveSuite(() {
-    if (!AnalysisDriver.useSummary2) {
-      defineReflectiveTests(WorkspaceSymbolsTest);
-    }
+    defineReflectiveTests(WorkspaceSymbolsTest);
   });
 }
 
diff --git a/pkg/analysis_server/test/search/declarations_test.dart b/pkg/analysis_server/test/search/declarations_test.dart
index 3d505be..000ba70 100644
--- a/pkg/analysis_server/test/search/declarations_test.dart
+++ b/pkg/analysis_server/test/search/declarations_test.dart
@@ -6,7 +6,6 @@
 
 import 'package:analysis_server/protocol/protocol.dart';
 import 'package:analysis_server/protocol/protocol_generated.dart';
-import 'package:analyzer/src/dart/analysis/driver.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -15,9 +14,7 @@
 
 main() {
   defineReflectiveSuite(() {
-    if (!AnalysisDriver.useSummary2) {
-      defineReflectiveTests(DeclarationsTest);
-    }
+    defineReflectiveTests(DeclarationsTest);
   });
 }
 
diff --git a/pkg/analysis_server/test/services/correction/change_test.dart b/pkg/analysis_server/test/services/correction/change_test.dart
index 1a74aa1..3568037 100644
--- a/pkg/analysis_server/test/services/correction/change_test.dart
+++ b/pkg/analysis_server/test/services/correction/change_test.dart
@@ -142,6 +142,7 @@
     SourceEdit a = new SourceEdit(1, 2, 'aaa');
     expect(a == a, isTrue);
     expect(a == new SourceEdit(1, 2, 'aaa'), isTrue);
+    // ignore: unrelated_type_equality_checks
     expect(a == this, isFalse);
     expect(a == new SourceEdit(1, 2, 'bbb'), isFalse);
     expect(a == new SourceEdit(10, 2, 'aaa'), isFalse);
@@ -259,6 +260,7 @@
     var c = new LinkedEditSuggestion('c', LinkedEditSuggestionKind.METHOD);
     expect(a == a, isTrue);
     expect(a == a2, isTrue);
+    // ignore: unrelated_type_equality_checks
     expect(a == this, isFalse);
     expect(a == b, isFalse);
     expect(a == c, isFalse);
@@ -274,6 +276,7 @@
     expect(a == a, isTrue);
     expect(a == a2, isTrue);
     expect(a == b, isFalse);
+    // ignore: unrelated_type_equality_checks
     expect(a == this, isFalse);
   }
 
diff --git a/pkg/analysis_server/test/src/computer/closingLabels_computer_test.dart b/pkg/analysis_server/test/src/computer/closing_labels_computer_test.dart
similarity index 100%
rename from pkg/analysis_server/test/src/computer/closingLabels_computer_test.dart
rename to pkg/analysis_server/test/src/computer/closing_labels_computer_test.dart
diff --git a/pkg/analysis_server/test/src/computer/test_all.dart b/pkg/analysis_server/test/src/computer/test_all.dart
index def1a36..fa0c1a9 100644
--- a/pkg/analysis_server/test/src/computer/test_all.dart
+++ b/pkg/analysis_server/test/src/computer/test_all.dart
@@ -4,23 +4,22 @@
 
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
-import 'closingLabels_computer_test.dart' as closingLabels_computer_test;
-import 'folding_computer_test.dart' as folding_computer_test;
+import 'closing_labels_computer_test.dart' as closing_labels_computer;
+import 'folding_computer_test.dart' as folding_computer;
 import 'highlights2_computer_test.dart' as highlights2_computer;
 import 'highlights_computer_test.dart' as highlights_computer;
-import 'import_elements_computer_test.dart' as import_elements_computer_test;
-import 'imported_elements_computer_test.dart'
-    as imported_elements_computer_test;
-import 'outline_computer_test.dart' as outline_computer_test;
+import 'import_elements_computer_test.dart' as import_elements_computer;
+import 'imported_elements_computer_test.dart' as imported_elements_computer;
+import 'outline_computer_test.dart' as outline_computer;
 
 main() {
   defineReflectiveSuite(() {
-    closingLabels_computer_test.main();
-    folding_computer_test.main();
+    closing_labels_computer.main();
+    folding_computer.main();
     highlights2_computer.main();
     highlights_computer.main();
-    import_elements_computer_test.main();
-    imported_elements_computer_test.main();
-    outline_computer_test.main();
+    import_elements_computer.main();
+    imported_elements_computer.main();
+    outline_computer.main();
   });
 }
diff --git a/pkg/analysis_server/test/src/edit/fix/non_nullable_fix_test.dart b/pkg/analysis_server/test/src/edit/fix/non_nullable_fix_test.dart
index 8f6487f..408a7a7 100644
--- a/pkg/analysis_server/test/src/edit/fix/non_nullable_fix_test.dart
+++ b/pkg/analysis_server/test/src/edit/fix/non_nullable_fix_test.dart
@@ -136,12 +136,11 @@
     Folder outputDir = getFolder('/outputDir');
     await performFix(included: [projectPath], outputDir: outputDir.path);
     expect(outputDir.exists, true);
-    expect(outputDir.getChildAssumingFile('bin__bin.html').exists, isTrue);
-    expect(outputDir.getChildAssumingFile('lib__lib1.html').exists, isTrue);
-    expect(outputDir.getChildAssumingFile('lib__lib2.html').exists, isTrue);
-    expect(
-        outputDir.getChildAssumingFile('lib__src__lib3.html').exists, isTrue);
-    expect(outputDir.getChildAssumingFile('test__test.html').exists, isTrue);
+    expect(getFile('/outputDir/bin/bin.html').exists, isTrue);
+    expect(getFile('/outputDir/lib/lib1.html').exists, isTrue);
+    expect(getFile('/outputDir/lib/lib2.html').exists, isTrue);
+    expect(getFile('/outputDir/lib/src/lib3.html').exists, isTrue);
+    expect(getFile('/outputDir/test/test.html').exists, isTrue);
   }
 
   test_outputDirContainsFilesRootedInASubdirectory() async {
@@ -151,9 +150,9 @@
         included: [context.join(projectPath, 'lib')],
         outputDir: outputDir.path);
     expect(outputDir.exists, true);
-    expect(outputDir.getChildAssumingFile('lib1.html').exists, isTrue);
-    expect(outputDir.getChildAssumingFile('lib2.html').exists, isTrue);
-    expect(outputDir.getChildAssumingFile('src__lib3.html').exists, isTrue);
+    expect(getFile('/outputDir/lib1.html').exists, isTrue);
+    expect(getFile('/outputDir/lib2.html').exists, isTrue);
+    expect(getFile('/outputDir/src/lib3.html').exists, isTrue);
   }
 
   test_outputDirContainsFilesRootedInParentOfSingleFile() async {
diff --git a/pkg/analysis_server/test/src/edit/nnbd_migration/info_builder_test.dart b/pkg/analysis_server/test/src/edit/nnbd_migration/info_builder_test.dart
index f300740..ca0162f 100644
--- a/pkg/analysis_server/test/src/edit/nnbd_migration/info_builder_test.dart
+++ b/pkg/analysis_server/test/src/edit/nnbd_migration/info_builder_test.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS 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.
 
@@ -48,9 +48,9 @@
     migration.processInput(result);
     migration.finish();
     // Build the migration info.
-    InfoBuilder builder = InfoBuilder(server);
     InstrumentationInformation info = instrumentationListener.data;
-    infos = await builder.explainMigration(info, listener);
+    InfoBuilder builder = InfoBuilder(info, listener);
+    infos = await builder.explainMigration();
   }
 
   test_parameter_nullableFromInvocation() async {
diff --git a/pkg/analysis_server/test/src/edit/nnbd_migration/offset_mapper_test.dart b/pkg/analysis_server/test/src/edit/nnbd_migration/offset_mapper_test.dart
new file mode 100644
index 0000000..4697e18
--- /dev/null
+++ b/pkg/analysis_server/test/src/edit/nnbd_migration/offset_mapper_test.dart
@@ -0,0 +1,51 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/edit/nnbd_migration/offset_mapper.dart';
+import 'package:analysis_server/src/protocol_server.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../../../analysis_abstract.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(OffsetMapperTest);
+  });
+}
+
+@reflectiveTest
+class OffsetMapperTest extends AbstractAnalysisTest {
+  test_identity() {
+    OffsetMapper mapper = OffsetMapper.identity;
+    expect(mapper.map(0), 0);
+    expect(mapper.map(20), 20);
+    expect(mapper.map(0xFFFFFF), 0xFFFFFF);
+  }
+
+  test_multipleEdits() {
+    OffsetMapper mapper = OffsetMapper.forEdits([
+      SourceEdit(13, 0, '?'),
+      SourceEdit(21, 0, '!'),
+      SourceEdit(32, 0, '?'),
+    ]);
+    expect(mapper.map(0), 0);
+    expect(mapper.map(13), 13);
+    expect(mapper.map(14), 15);
+    expect(mapper.map(21), 22);
+    expect(mapper.map(22), 24);
+    expect(mapper.map(32), 34);
+    expect(mapper.map(33), 36);
+    expect(mapper.map(55), 58);
+  }
+
+  test_singleEdit() {
+    OffsetMapper mapper = OffsetMapper.forEdits([
+      SourceEdit(13, 0, '?'),
+    ]);
+    expect(mapper.map(0), 0);
+    expect(mapper.map(13), 13);
+    expect(mapper.map(14), 15);
+  }
+}
diff --git a/pkg/analysis_server/test/src/edit/nnbd_migration/test_all.dart b/pkg/analysis_server/test/src/edit/nnbd_migration/test_all.dart
index b7ddf83..6dd7cab 100644
--- a/pkg/analysis_server/test/src/edit/nnbd_migration/test_all.dart
+++ b/pkg/analysis_server/test/src/edit/nnbd_migration/test_all.dart
@@ -5,9 +5,11 @@
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'info_builder_test.dart' as info_builder;
+import 'offset_mapper_test.dart' as offset_mapper;
 
 main() {
   defineReflectiveSuite(() {
     info_builder.main();
+    offset_mapper.main();
   }, name: 'nnbd_migration');
 }
diff --git a/pkg/analysis_server/test/src/services/correction/fix/create_missing_overrides_test.dart b/pkg/analysis_server/test/src/services/correction/fix/create_missing_overrides_test.dart
index e240531..7656709 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/create_missing_overrides_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/create_missing_overrides_test.dart
@@ -4,7 +4,6 @@
 
 import 'package:analysis_server/src/protocol_server.dart';
 import 'package:analysis_server/src/services/correction/fix.dart';
-import 'package:analyzer/src/dart/analysis/driver.dart' show AnalysisDriver;
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -79,8 +78,7 @@
 class B extends A {
 }
 ''');
-    if (AnalysisDriver.useSummary2) {
-      await assertHasFix('''
+    await assertHasFix('''
 abstract class A {
   void forEach(int f(double p1, String p2));
 }
@@ -92,20 +90,6 @@
   }
 }
 ''');
-    } else {
-      await assertHasFix('''
-abstract class A {
-  void forEach(int f(double p1, String p2));
-}
-
-class B extends A {
-  @override
-  void forEach(int Function(double p1, String p2) f) {
-    // TODO: implement forEach
-  }
-}
-''');
-    }
   }
 
   test_generics_typeArguments() async {
diff --git a/pkg/analysis_server/test/stress/completion/completion_runner.dart b/pkg/analysis_server/test/stress/completion/completion_runner.dart
index e29ce89..692041f 100644
--- a/pkg/analysis_server/test/stress/completion/completion_runner.dart
+++ b/pkg/analysis_server/test/stress/completion/completion_runner.dart
@@ -257,7 +257,7 @@
    */
   bool _isNamedExpressionName(SimpleIdentifier identifier) {
     AstNode parent = identifier.parent;
-    return parent is NamedExpression && parent.name == identifier;
+    return parent is NamedExpression && parent.name.label == identifier;
   }
 
   /**
diff --git a/pkg/analysis_server/tool/lsp_spec/typescript_parser.dart b/pkg/analysis_server/tool/lsp_spec/typescript_parser.dart
index 3b06fd1..3c7e5ed 100644
--- a/pkg/analysis_server/tool/lsp_spec/typescript_parser.dart
+++ b/pkg/analysis_server/tool/lsp_spec/typescript_parser.dart
@@ -539,7 +539,7 @@
         if (_match([TokenType.LESS])) {
           while (true) {
             typeArgs.add(_type(containerName, fieldName));
-            if (_peek() != TokenType.COMMA) {
+            if (_peek().type != TokenType.COMMA) {
               _consume(TokenType.GREATER, 'Expected >');
               break;
             }
diff --git a/pkg/analysis_server/tool/spec/to_html.dart b/pkg/analysis_server/tool/spec/to_html.dart
index f8b74ac..1a29203 100644
--- a/pkg/analysis_server/tool/spec/to_html.dart
+++ b/pkg/analysis_server/tool/spec/to_html.dart
@@ -286,7 +286,7 @@
     h3(() => write('Domains'));
     for (var domain in api.domains) {
       if (domain.experimental ||
-          (domain.requests.isEmpty && domain.notifications == 0)) {
+          (domain.requests.isEmpty && domain.notifications.isEmpty)) {
         continue;
       }
       generateDomainIndex(domain);
diff --git a/pkg/analyzer/CHANGELOG.md b/pkg/analyzer/CHANGELOG.md
index 274f08e..427a827 100644
--- a/pkg/analyzer/CHANGELOG.md
+++ b/pkg/analyzer/CHANGELOG.md
@@ -1,3 +1,8 @@
+## 0.38.5-dev
+* Added the interface `PromotableElement`, which representing
+  variables that can be type promoted (local variables and parameters,
+  but not fields).
+
 ## 0.38.4
 * Bug fixes: #33300, #38484, #38505.
 
diff --git a/pkg/analyzer/analysis_options.yaml b/pkg/analyzer/analysis_options.yaml
index 46298e7..3fa0592 100644
--- a/pkg/analyzer/analysis_options.yaml
+++ b/pkg/analyzer/analysis_options.yaml
@@ -1,9 +1,12 @@
 include: package:pedantic/analysis_options.1.8.0.yaml
+
 analyzer:
   # This currently finds ~4,500 implicit-casts issues when enabled.
   # strong-mode:
   #   implicit-casts: false
   errors:
+    # Increase the severity of the unused_import hint.
+    unused_import: warning
     # Ignoring "style" lint rules from pedantic for now. There are pre-existing
     # violations that need to be cleaned up. Each one can be cleaned up and
     # enabled according to the value provided.
diff --git a/pkg/analyzer/lib/dart/element/element.dart b/pkg/analyzer/lib/dart/element/element.dart
index 8ae0ba1..5637045 100644
--- a/pkg/analyzer/lib/dart/element/element.dart
+++ b/pkg/analyzer/lib/dart/element/element.dart
@@ -1423,7 +1423,7 @@
 /// A local variable.
 ///
 /// Clients may not extend, implement or mix-in this class.
-abstract class LocalVariableElement implements LocalElement, VariableElement {}
+abstract class LocalVariableElement implements PromotableElement {}
 
 /// An element that represents a method defined within a class.
 ///
@@ -1472,7 +1472,7 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 abstract class ParameterElement
-    implements LocalElement, VariableElement, ConstantEvaluationTarget {
+    implements PromotableElement, ConstantEvaluationTarget {
   /// Return the Dart code of the default value, or `null` if no default value.
   String get defaultValueCode;
 
@@ -1570,6 +1570,12 @@
   List<LibraryElement> get importedLibraries;
 }
 
+/// A variable that might be subject to type promotion.  This might be a local
+/// variable or a parameter.
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class PromotableElement implements LocalElement, VariableElement {}
+
 /// A getter or a setter. Note that explicitly defined property accessors
 /// implicitly define a synthetic field. Symmetrically, synthetic accessors are
 /// implicitly created for explicitly defined fields. The following rules apply:
diff --git a/pkg/analyzer/lib/src/dart/analysis/ddc.dart b/pkg/analyzer/lib/src/dart/analysis/ddc.dart
index f526171..c86790c 100644
--- a/pkg/analyzer/lib/src/dart/analysis/ddc.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/ddc.dart
@@ -6,7 +6,6 @@
 
 import 'package:analyzer/dart/analysis/declared_variables.dart';
 import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/src/dart/analysis/driver.dart';
 import 'package:analyzer/src/dart/analysis/file_state.dart';
 import 'package:analyzer/src/dart/analysis/restricted_analysis_context.dart';
 import 'package:analyzer/src/dart/analysis/session.dart';
@@ -14,12 +13,8 @@
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart';
-import 'package:analyzer/src/summary/format.dart';
 import 'package:analyzer/src/summary/idl.dart';
-import 'package:analyzer/src/summary/link.dart';
 import 'package:analyzer/src/summary/package_bundle_reader.dart';
-import 'package:analyzer/src/summary/resynthesize.dart';
-import 'package:analyzer/src/summary/summarize_ast.dart';
 import 'package:analyzer/src/summary/summarize_elements.dart';
 import 'package:analyzer/src/summary2/informative_data.dart';
 import 'package:analyzer/src/summary2/link.dart' as summary2;
@@ -44,7 +39,6 @@
   List<int> summaryBytes;
 
   RestrictedAnalysisContext context;
-  SummaryResynthesizer resynthesizer;
   summary2.LinkedElementFactory elementFactory;
 
   DevCompilerResynthesizerBuilder({
@@ -77,7 +71,8 @@
     );
     _fileCrawler.crawl();
 
-    _buildPackageBundleBytes();
+    _computeLinkedLibraries2();
+    summaryBytes = _assembler.assemble().toBuffer();
     var bundle = PackageBundle.fromBuffer(summaryBytes);
 
     // Create an analysis context to contain the state for this build unit.
@@ -87,46 +82,7 @@
     );
     context = RestrictedAnalysisContext(synchronousSession, _sourceFactory);
 
-    if (AnalysisDriver.useSummary2) {
-      _createElementFactory(bundle);
-    } else {
-      resynthesizer = StoreBasedSummaryResynthesizer(
-        context,
-        null,
-        context.sourceFactory,
-        /*strongMode*/ true,
-        SummaryDataStore([])
-          ..addStore(_summaryData)
-          ..addBundle(null, bundle),
-      );
-      resynthesizer.finishCoreAsyncLibraries();
-      context.typeProvider = resynthesizer.typeProvider;
-    }
-  }
-
-  void _buildPackageBundleBytes() {
-    if (AnalysisDriver.useSummary2) {
-      _computeLinkedLibraries2();
-    } else {
-      _computeLinkedLibraries1();
-    }
-    summaryBytes = _assembler.assemble().toBuffer();
-  }
-
-  void _computeLinkedLibraries1() {
-    _fileCrawler.sourceToUnlinkedUnit.forEach((source, unlinkedUnit) {
-      _assembler.addUnlinkedUnit(source, unlinkedUnit);
-    });
-
-    var linkResult = link(
-        _fileCrawler.libraryUris.toSet(),
-        (uri) => _summaryData.linkedMap[uri],
-        (uri) =>
-            _summaryData.unlinkedMap[uri] ??
-            _fileCrawler.uriToUnlinkedUnit[uri],
-        _declaredVariables,
-        _analysisOptions);
-    linkResult.forEach(_assembler.addLinkedLibrary);
+    _createElementFactory(bundle);
   }
 
   /// Link libraries, and fill [_assembler].
@@ -280,8 +236,6 @@
   /// them as units.
   final List<Source> _invalidLibrarySources = [];
 
-  final Map<Source, UnlinkedUnitBuilder> sourceToUnlinkedUnit = {};
-  final Map<String, UnlinkedUnitBuilder> uriToUnlinkedUnit = {};
   final Map<Source, CompilationUnit> sourceToUnit = {};
   final List<String> libraryUris = [];
   final List<Source> librarySources = [];
@@ -330,10 +284,6 @@
     var unit = file.parse();
     sourceToUnit[source] = unit;
 
-    var unlinkedUnit = serializeAstUnlinked(unit);
-    uriToUnlinkedUnit[uriStr] = unlinkedUnit;
-    sourceToUnlinkedUnit[source] = unlinkedUnit;
-
     void enqueueSource(String relativeUri, bool shouldBeLibrary) {
       var sourceUri = resolveRelativeUri(uri, Uri.parse(relativeUri));
       if (_knownSources.add(sourceUri)) {
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index a637158..c71d4d3 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -95,9 +95,6 @@
   /// zero, we stop writing any new exception contexts in this process.
   static int allowedNumberOfContextsToWrite = 10;
 
-  /// Whether summary2 should be used to resynthesize elements.
-  static bool useSummary2 = true;
-
   /// The scheduler that schedules analysis work in this, and possibly other
   /// analysis drivers.
   final AnalysisDriverScheduler _scheduler;
@@ -140,11 +137,11 @@
 
   /// The salt to mix into all hashes used as keys for unlinked data.
   final Uint32List _unlinkedSalt =
-      new Uint32List(3 + AnalysisOptionsImpl.unlinkedSignatureLength);
+      new Uint32List(2 + AnalysisOptionsImpl.unlinkedSignatureLength);
 
   /// The salt to mix into all hashes used as keys for linked data.
   final Uint32List _linkedSalt =
-      new Uint32List(3 + AnalysisOptions.signatureLength);
+      new Uint32List(2 + AnalysisOptions.signatureLength);
 
   /// The set of priority files, that should be analyzed sooner.
   final _priorityFiles = new LinkedHashSet<String>();
@@ -1251,7 +1248,6 @@
             sourceFactory,
             libraryContext.isLibraryUri,
             libraryContext.analysisContext,
-            libraryContext.resynthesizer,
             libraryContext.elementFactory,
             libraryContext.inheritanceManager,
             library,
@@ -1319,7 +1315,6 @@
           sourceFactory,
           libraryContext.isLibraryUri,
           libraryContext.analysisContext,
-          libraryContext.resynthesizer,
           libraryContext.elementFactory,
           libraryContext.inheritanceManager,
           library,
@@ -1446,12 +1441,9 @@
         sourceFactory: _sourceFactory,
         externalSummaries: _externalSummaries,
         targetLibrary: library,
-        useSummary2: useSummary2,
       );
-    } else if (useSummary2) {
-      _libraryContext.load2(library);
     } else {
-      _libraryContext.load(library);
+      _libraryContext.load2(library);
     }
     return _libraryContext;
   }
@@ -1474,13 +1466,11 @@
   void _fillSalt() {
     _unlinkedSalt[0] = DATA_VERSION;
     _unlinkedSalt[1] = enableIndex ? 1 : 0;
-    _unlinkedSalt[2] = useSummary2 ? 1 : 0;
-    _unlinkedSalt.setAll(3, _analysisOptions.unlinkedSignature);
+    _unlinkedSalt.setAll(2, _analysisOptions.unlinkedSignature);
 
     _linkedSalt[0] = DATA_VERSION;
     _linkedSalt[1] = enableIndex ? 1 : 0;
-    _linkedSalt[2] = useSummary2 ? 1 : 0;
-    _linkedSalt.setAll(3, _analysisOptions.signature);
+    _linkedSalt.setAll(2, _analysisOptions.signature);
   }
 
   /// Load the [AnalysisResult] for the given [file] from the [bytes]. Set
diff --git a/pkg/analyzer/lib/src/dart/analysis/file_state.dart b/pkg/analyzer/lib/src/dart/analysis/file_state.dart
index ffa3f84..ad3606f 100644
--- a/pkg/analyzer/lib/src/dart/analysis/file_state.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/file_state.dart
@@ -13,7 +13,6 @@
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/src/dart/analysis/byte_store.dart';
 import 'package:analyzer/src/dart/analysis/defined_names.dart';
-import 'package:analyzer/src/dart/analysis/driver.dart';
 import 'package:analyzer/src/dart/analysis/library_graph.dart';
 import 'package:analyzer/src/dart/analysis/performance_logger.dart';
 import 'package:analyzer/src/dart/analysis/referenced_names.dart';
@@ -30,7 +29,6 @@
 import 'package:analyzer/src/summary/idl.dart';
 import 'package:analyzer/src/summary/name_filter.dart';
 import 'package:analyzer/src/summary/package_bundle_reader.dart';
-import 'package:analyzer/src/summary/summarize_ast.dart';
 import 'package:analyzer/src/summary2/informative_data.dart';
 import 'package:convert/convert.dart';
 import 'package:crypto/crypto.dart';
@@ -397,224 +395,6 @@
   bool refresh({bool allowCached: false}) {
     counterFileStateRefresh++;
 
-    if (AnalysisDriver.useSummary2) {
-      return _refresh2(allowCached: allowCached);
-    }
-
-    var timerWasRunning = timerFileStateRefresh.isRunning;
-    if (!timerWasRunning) {
-      timerFileStateRefresh.start();
-    }
-
-    _invalidateCurrentUnresolvedData();
-
-    {
-      var rawFileState = _fsState._fileContentCache.get(path, allowCached);
-      _content = rawFileState.content;
-      _exists = rawFileState.exists;
-      _contentHash = rawFileState.contentHash;
-    }
-
-    // Prepare the unlinked bundle key.
-    {
-      var signature = new ApiSignature();
-      signature.addUint32List(_fsState._unlinkedSalt);
-      signature.addString(_contentHash);
-      _unlinkedKey = '${signature.toHex()}.unlinked';
-    }
-
-    // Prepare bytes of the unlinked bundle - existing or new.
-    List<int> bytes;
-    {
-      bytes = _fsState._byteStore.get(_unlinkedKey);
-      if (bytes == null || bytes.isEmpty) {
-        CompilationUnit unit = parse();
-        _fsState._logger.run('Create unlinked for $path', () {
-          UnlinkedUnitBuilder unlinkedUnit = serializeAstUnlinked(unit);
-          DefinedNames definedNames = computeDefinedNames(unit);
-          List<String> referencedNames = computeReferencedNames(unit).toList();
-          List<String> subtypedNames = computeSubtypedNames(unit).toList();
-          bytes = new AnalysisDriverUnlinkedUnitBuilder(
-                  unit: unlinkedUnit,
-                  definedTopLevelNames: definedNames.topLevelNames.toList(),
-                  definedClassMemberNames:
-                      definedNames.classMemberNames.toList(),
-                  referencedNames: referencedNames,
-                  subtypedNames: subtypedNames)
-              .toBuffer();
-          counterUnlinkedLinkedBytes += bytes.length;
-          _fsState._byteStore.put(_unlinkedKey, bytes);
-        });
-      }
-    }
-
-    // Read the unlinked bundle.
-    _driverUnlinkedUnit = new AnalysisDriverUnlinkedUnit.fromBuffer(bytes);
-    _unlinked = _driverUnlinkedUnit.unit;
-    _lineInfo = new LineInfo(_unlinked.lineStarts);
-
-    // Prepare API signature.
-    List<int> newApiSignature = new Uint8List.fromList(_unlinked.apiSignature);
-    bool apiSignatureChanged = _apiSignature != null &&
-        !_equalByteLists(_apiSignature, newApiSignature);
-    _apiSignature = newApiSignature;
-
-    // The API signature changed.
-    //   Flush affected library cycles.
-    //   Flush exported top-level declarations of all files.
-    if (apiSignatureChanged) {
-      _libraryCycle?.invalidate();
-
-      // If this is a part, invalidate the libraries.
-      var libraries = _fsState._partToLibraries[this];
-      if (libraries != null) {
-        for (var library in libraries) {
-          library.libraryCycle?.invalidate();
-        }
-      }
-    }
-
-    // This file is potentially not a library for its previous parts anymore.
-    if (_partedFiles != null) {
-      for (FileState part in _partedFiles) {
-        _fsState._partToLibraries[part]?.remove(this);
-      }
-    }
-
-    // Build the graph.
-    _importedFiles = <FileState>[];
-    _exportedFiles = <FileState>[];
-    _partedFiles = <FileState>[];
-    _exportFilters = <NameFilter>[];
-    for (UnlinkedImport import in _unlinked.imports) {
-      String uri = import.isImplicit ? 'dart:core' : import.uri;
-      FileState file = _fileForRelativeUri(uri);
-      _importedFiles.add(file);
-    }
-    for (UnlinkedExportPublic export in _unlinked.publicNamespace.exports) {
-      String uri = export.uri;
-      FileState file = _fileForRelativeUri(uri);
-      _exportedFiles.add(file);
-      _exportFilters
-          .add(new NameFilter.forUnlinkedCombinators(export.combinators));
-    }
-    for (String uri in _unlinked.publicNamespace.parts) {
-      FileState file = _fileForRelativeUri(uri);
-      _partedFiles.add(file);
-      // TODO(scheglov) Sort for stable results?
-      _fsState._partToLibraries
-          .putIfAbsent(file, () => <FileState>[])
-          .add(this);
-    }
-    _libraryFiles = [this]..addAll(_partedFiles);
-
-    // Compute referenced files.
-    _directReferencedFiles = new Set<FileState>()
-      ..addAll(_importedFiles)
-      ..addAll(_exportedFiles)
-      ..addAll(_partedFiles);
-    _directReferencedLibraries = Set<FileState>()
-      ..addAll(_importedFiles)
-      ..addAll(_exportedFiles);
-
-    // Update mapping from subtyped names to files.
-    for (var name in _driverUnlinkedUnit.subtypedNames) {
-      var files = _fsState._subtypedNameToFiles[name];
-      if (files == null) {
-        files = new Set<FileState>();
-        _fsState._subtypedNameToFiles[name] = files;
-      }
-      files.add(this);
-    }
-
-    if (!timerWasRunning) {
-      timerFileStateRefresh.stop();
-    }
-
-    // Return whether the API signature changed.
-    return apiSignatureChanged;
-  }
-
-  @override
-  String toString() => path ?? '<unresolved>';
-
-  CompilationUnit _createEmptyCompilationUnit(FeatureSet featureSet) {
-    var token = new Token.eof(0);
-    return astFactory.compilationUnit(
-        beginToken: token, endToken: token, featureSet: featureSet)
-      ..lineInfo = new LineInfo(const <int>[0]);
-  }
-
-  /**
-   * Return the [FileState] for the given [relativeUri], maybe "unresolved"
-   * file if the URI cannot be parsed, cannot correspond any file, etc.
-   */
-  FileState _fileForRelativeUri(String relativeUri) {
-    if (relativeUri.isEmpty) {
-      return _fsState.unresolvedFile;
-    }
-
-    Uri absoluteUri;
-    try {
-      absoluteUri = resolveRelativeUri(uri, Uri.parse(relativeUri));
-    } on FormatException {
-      return _fsState.unresolvedFile;
-    }
-
-    return _fsState.getFileForUri(absoluteUri);
-  }
-
-  /**
-   * Invalidate any data that depends on the current unlinked data of the file,
-   * because [refresh] is going to recompute the unlinked data.
-   */
-  void _invalidateCurrentUnresolvedData() {
-    // Invalidate unlinked information.
-    _definedTopLevelNames = null;
-    _definedClassMemberNames = null;
-    _referencedNames = null;
-
-    if (_driverUnlinkedUnit != null) {
-      for (var name in _driverUnlinkedUnit.subtypedNames) {
-        var files = _fsState._subtypedNameToFiles[name];
-        files?.remove(this);
-      }
-    }
-  }
-
-  CompilationUnit _parse(AnalysisErrorListener errorListener) {
-    AnalysisOptionsImpl analysisOptions = _fsState._analysisOptions;
-    FeatureSet featureSet = analysisOptions.contextFeatures;
-    if (source == null) {
-      return _createEmptyCompilationUnit(featureSet);
-    }
-
-    CharSequenceReader reader = new CharSequenceReader(content);
-    Scanner scanner = new Scanner(source, reader, errorListener)
-      ..configureFeatures(featureSet);
-    Token token = PerformanceStatistics.scan.makeCurrentWhile(() {
-      return scanner.tokenize(reportScannerErrors: false);
-    });
-    LineInfo lineInfo = new LineInfo(scanner.lineStarts);
-
-    bool useFasta = analysisOptions.useFastaParser;
-    // 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(source, errorListener,
-        featureSet: scanner.featureSet, useFasta: useFasta);
-    parser.enableOptionalNewAndConst = true;
-    CompilationUnit unit = parser.parseCompilationUnit(token);
-    unit.lineInfo = lineInfo;
-
-    // StringToken uses a static instance of StringCanonicalizer, so we need
-    // to clear it explicitly once we are done using it for this file.
-    StringToken.canonicalizer.clear();
-
-    return unit;
-  }
-
-  bool _refresh2({bool allowCached: false}) {
     var timerWasRunning = timerFileStateRefresh.isRunning;
     if (!timerWasRunning) {
       timerFileStateRefresh.start();
@@ -747,6 +527,85 @@
     return apiSignatureChanged;
   }
 
+  @override
+  String toString() => path ?? '<unresolved>';
+
+  CompilationUnit _createEmptyCompilationUnit(FeatureSet featureSet) {
+    var token = new Token.eof(0);
+    return astFactory.compilationUnit(
+        beginToken: token, endToken: token, featureSet: featureSet)
+      ..lineInfo = new LineInfo(const <int>[0]);
+  }
+
+  /**
+   * Return the [FileState] for the given [relativeUri], maybe "unresolved"
+   * file if the URI cannot be parsed, cannot correspond any file, etc.
+   */
+  FileState _fileForRelativeUri(String relativeUri) {
+    if (relativeUri.isEmpty) {
+      return _fsState.unresolvedFile;
+    }
+
+    Uri absoluteUri;
+    try {
+      absoluteUri = resolveRelativeUri(uri, Uri.parse(relativeUri));
+    } on FormatException {
+      return _fsState.unresolvedFile;
+    }
+
+    return _fsState.getFileForUri(absoluteUri);
+  }
+
+  /**
+   * Invalidate any data that depends on the current unlinked data of the file,
+   * because [refresh] is going to recompute the unlinked data.
+   */
+  void _invalidateCurrentUnresolvedData() {
+    // Invalidate unlinked information.
+    _definedTopLevelNames = null;
+    _definedClassMemberNames = null;
+    _referencedNames = null;
+
+    if (_driverUnlinkedUnit != null) {
+      for (var name in _driverUnlinkedUnit.subtypedNames) {
+        var files = _fsState._subtypedNameToFiles[name];
+        files?.remove(this);
+      }
+    }
+  }
+
+  CompilationUnit _parse(AnalysisErrorListener errorListener) {
+    AnalysisOptionsImpl analysisOptions = _fsState._analysisOptions;
+    FeatureSet featureSet = analysisOptions.contextFeatures;
+    if (source == null) {
+      return _createEmptyCompilationUnit(featureSet);
+    }
+
+    CharSequenceReader reader = new CharSequenceReader(content);
+    Scanner scanner = new Scanner(source, reader, errorListener)
+      ..configureFeatures(featureSet);
+    Token token = PerformanceStatistics.scan.makeCurrentWhile(() {
+      return scanner.tokenize(reportScannerErrors: false);
+    });
+    LineInfo lineInfo = new LineInfo(scanner.lineStarts);
+
+    bool useFasta = analysisOptions.useFastaParser;
+    // 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(source, errorListener,
+        featureSet: scanner.featureSet, useFasta: useFasta);
+    parser.enableOptionalNewAndConst = true;
+    CompilationUnit unit = parser.parseCompilationUnit(token);
+    unit.lineInfo = lineInfo;
+
+    // StringToken uses a static instance of StringCanonicalizer, so we need
+    // to clear it explicitly once we are done using it for this file.
+    StringToken.canonicalizer.clear();
+
+    return unit;
+  }
+
   static UnlinkedUnit2Builder serializeAstUnlinked2(CompilationUnit unit) {
     var exports = <String>[];
     var imports = <String>[];
diff --git a/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart b/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
index 013e122..80d34b3 100644
--- a/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
@@ -11,7 +11,6 @@
 import 'package:analyzer/error/error.dart';
 import 'package:analyzer/error/listener.dart';
 import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/src/dart/analysis/driver.dart';
 import 'package:analyzer/src/dart/analysis/file_state.dart';
 import 'package:analyzer/src/dart/analysis/testing_data.dart';
 import 'package:analyzer/src/dart/ast/ast.dart';
@@ -21,7 +20,6 @@
 import 'package:analyzer/src/dart/constant/evaluation.dart';
 import 'package:analyzer/src/dart/constant/utilities.dart';
 import 'package:analyzer/src/dart/element/element.dart';
-import 'package:analyzer/src/dart/element/handle.dart';
 import 'package:analyzer/src/dart/element/inheritance_manager3.dart';
 import 'package:analyzer/src/dart/element/type_provider.dart';
 import 'package:analyzer/src/dart/resolver/ast_rewrite.dart';
@@ -68,7 +66,6 @@
   final InheritanceManager3 _inheritance;
   final bool Function(Uri) _isLibraryUri;
   final AnalysisContext _context;
-  final ElementResynthesizer _resynthesizer;
   final LinkedElementFactory _elementFactory;
   TypeProviderImpl _typeProvider;
 
@@ -100,7 +97,6 @@
       this._sourceFactory,
       this._isLibraryUri,
       this._context,
-      this._resynthesizer,
       this._elementFactory,
       this._inheritance,
       this._library,
@@ -145,12 +141,7 @@
       _resolveUriBasedDirectives(file, unit);
     });
 
-    if (_elementFactory != null) {
-      _libraryElement = _elementFactory.libraryOfUri(_library.uriStr);
-    } else {
-      _libraryElement = _resynthesizer
-          .getElement(new ElementLocationImpl.con3([_library.uriStr]));
-    }
+    _libraryElement = _elementFactory.libraryOfUri(_library.uriStr);
     _libraryScope = new LibraryScope(_libraryElement);
 
     timerLibraryAnalyzerResolve.start();
@@ -511,11 +502,7 @@
     definingCompilationUnit.element = _libraryElement.definingCompilationUnit;
 
     bool matchNodeElement(Directive node, Element element) {
-      if (AnalysisDriver.useSummary2) {
-        return node.keyword.offset == element.nameOffset;
-      } else {
-        return node.offset == element.nameOffset;
-      }
+      return node.keyword.offset == element.nameOffset;
     }
 
     ErrorReporter libraryErrorReporter = _getErrorReporter(_library);
diff --git a/pkg/analyzer/lib/src/dart/analysis/library_context.dart b/pkg/analyzer/lib/src/dart/analysis/library_context.dart
index 56a3aed..ab1168e 100644
--- a/pkg/analyzer/lib/src/dart/analysis/library_context.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/library_context.dart
@@ -13,18 +13,14 @@
 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_manager3.dart';
 import 'package:analyzer/src/dart/element/type_provider.dart';
 import 'package:analyzer/src/generated/engine.dart'
     show AnalysisContext, AnalysisOptions;
 import 'package:analyzer/src/generated/resolver.dart' show TypeProvider;
 import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/summary/format.dart';
 import 'package:analyzer/src/summary/idl.dart';
-import 'package:analyzer/src/summary/link.dart';
 import 'package:analyzer/src/summary/package_bundle_reader.dart';
-import 'package:analyzer/src/summary/resynthesize.dart';
 import 'package:analyzer/src/summary2/link.dart' as link2;
 import 'package:analyzer/src/summary2/linked_bundle_context.dart';
 import 'package:analyzer/src/summary2/linked_element_factory.dart';
@@ -59,7 +55,6 @@
   int _linkedDataInBytes = 0;
 
   RestrictedAnalysisContext analysisContext;
-  SummaryResynthesizer resynthesizer;
   LinkedElementFactory elementFactory;
   InheritanceManager3 inheritanceManager;
 
@@ -75,7 +70,6 @@
     @required SourceFactory sourceFactory,
     @required this.externalSummaries,
     @required FileState targetLibrary,
-    @required bool useSummary2,
   })  : this.logger = logger,
         this.byteStore = byteStore,
         this.analysisSession = session {
@@ -90,18 +84,8 @@
       sourceFactory,
     );
 
-    if (useSummary2) {
-      _createElementFactory();
-      load2(targetLibrary);
-    } else {
-      // Fill the store with summaries required for the initial library.
-      load(targetLibrary);
-
-      resynthesizer = new StoreBasedSummaryResynthesizer(
-          analysisContext, session, sourceFactory, true, store);
-      analysisContext.typeProvider = resynthesizer.typeProvider;
-      resynthesizer.finishCoreAsyncLibraries();
-    }
+    _createElementFactory();
+    load2(targetLibrary);
 
     inheritanceManager = new InheritanceManager3(analysisContext.typeSystem);
   }
@@ -115,28 +99,18 @@
    * Computes a [CompilationUnitElement] for the given library/unit pair.
    */
   CompilationUnitElement computeUnitElement(FileState library, FileState unit) {
-    if (elementFactory != null) {
-      var reference = elementFactory.rootReference
-          .getChild(library.uriStr)
-          .getChild('@unit')
-          .getChild(unit.uriStr);
-      return elementFactory.elementOfReference(reference);
-    } else {
-      return resynthesizer.getElement(new ElementLocationImpl.con3(<String>[
-        library.uriStr,
-        unit.uriStr,
-      ]));
-    }
+    var reference = elementFactory.rootReference
+        .getChild(library.uriStr)
+        .getChild('@unit')
+        .getChild(unit.uriStr);
+    return elementFactory.elementOfReference(reference);
   }
 
   /**
    * Get the [LibraryElement] for the given library.
    */
   LibraryElement getLibraryElement(FileState library) {
-    if (elementFactory != null) {
-      return elementFactory.libraryOfUri(library.uriStr);
-    }
-    return resynthesizer.getLibraryElement(library.uriStr);
+    return elementFactory.libraryOfUri(library.uriStr);
   }
 
   /**
@@ -144,112 +118,7 @@
    */
   bool isLibraryUri(Uri uri) {
     String uriStr = uri.toString();
-    if (elementFactory != null) {
-      return elementFactory.isLibraryUri(uriStr);
-    } else {
-      return store.unlinkedMap[uriStr]?.isPartOf == false;
-    }
-  }
-
-  /// Load data required to access elements of the given [targetLibrary].
-  void load(FileState targetLibrary) {
-    if (AnalysisDriver.useSummary2) {
-      throw StateError('Unexpected with summary2.');
-    }
-
-    // The library is already a part of the context, nothing to do.
-    if (store.linkedMap.containsKey(targetLibrary.uriStr)) {
-      return;
-    }
-
-    timerLoad2.start();
-
-    var libraries = <String, FileState>{};
-    void appendLibraryFiles(FileState library) {
-      // Stop if this library is already a part of the context.
-      // Libraries from external summaries are also covered by this.
-      if (store.linkedMap.containsKey(library.uriStr)) {
-        return;
-      }
-
-      // Stop if we have already scheduled loading of this library.
-      if (libraries.containsKey(library.uriStr)) {
-        return;
-      }
-
-      // Schedule the library for loading or linking.
-      libraries[library.uriStr] = library;
-
-      // Append library units.
-      for (FileState part in library.libraryFiles) {
-        store.addUnlinkedUnit(part.uriStr, part.unlinked);
-      }
-
-      // Append referenced libraries.
-      library.importedFiles.forEach(appendLibraryFiles);
-      library.exportedFiles.forEach(appendLibraryFiles);
-    }
-
-    logger.run('Append library files', () {
-      appendLibraryFiles(targetLibrary);
-    });
-
-    var libraryUrisToLink = new Set<String>();
-    logger.run('Load linked bundles', () {
-      for (FileState library in libraries.values) {
-        if (library.exists || library == targetLibrary) {
-          String key = library.transitiveSignatureLinked;
-          List<int> bytes = byteStore.get(key);
-          if (bytes != null) {
-            LinkedLibrary linked = new LinkedLibrary.fromBuffer(bytes);
-            store.addLinkedLibrary(library.uriStr, linked);
-            _linkedDataInBytes += bytes.length;
-          } else {
-            libraryUrisToLink.add(library.uriStr);
-          }
-        }
-      }
-      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) {
-        LinkedLibrary linkedLibrary = store.linkedMap[uri];
-        return linkedLibrary;
-      }, (String uri) {
-        UnlinkedUnit unlinkedUnit = store.unlinkedMap[uri];
-        return unlinkedUnit;
-      }, 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();
+    return elementFactory.isLibraryUri(uriStr);
   }
 
   /// Load data required to access elements of the given [targetLibrary].
diff --git a/pkg/analyzer/lib/src/dart/constant/evaluation.dart b/pkg/analyzer/lib/src/dart/constant/evaluation.dart
index c8395a2..0f2f144 100644
--- a/pkg/analyzer/lib/src/dart/constant/evaluation.dart
+++ b/pkg/analyzer/lib/src/dart/constant/evaluation.dart
@@ -1618,7 +1618,7 @@
   /// 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) {
+  DartObjectImpl _getConstantValue(Expression node, Element element) {
     Element variableElement =
         element is PropertyAccessorElement ? element.variable : element;
     if (variableElement is VariableElementImpl) {
@@ -1634,11 +1634,8 @@
     } else if (variableElement is ExecutableElement) {
       ExecutableElement function = element;
       if (function.isStatic) {
-        ParameterizedType functionType = function.type;
-        if (functionType == null) {
-          functionType = _typeProvider.functionType;
-        }
-        return new DartObjectImpl(functionType, new FunctionState(function));
+        var functionType = node.staticType;
+        return DartObjectImpl(functionType, FunctionState(function));
       }
     } else if (variableElement is ClassElement) {
       var type = variableElement.instantiate(
diff --git a/pkg/analyzer/lib/src/dart/constant/utilities.dart b/pkg/analyzer/lib/src/dart/constant/utilities.dart
index 225fb0a..ef993d0 100644
--- a/pkg/analyzer/lib/src/dart/constant/utilities.dart
+++ b/pkg/analyzer/lib/src/dart/constant/utilities.dart
@@ -90,6 +90,20 @@
   }
 
   @override
+  PrefixedIdentifier visitPrefixedIdentifier(PrefixedIdentifier node) {
+    PrefixedIdentifierImpl copy = super.visitPrefixedIdentifier(node);
+    copy.staticType = node.staticType;
+    return copy;
+  }
+
+  @override
+  PropertyAccess visitPropertyAccess(PropertyAccess node) {
+    PropertyAccessImpl copy = super.visitPropertyAccess(node);
+    copy.staticType = node.staticType;
+    return copy;
+  }
+
+  @override
   RedirectingConstructorInvocation visitRedirectingConstructorInvocation(
       RedirectingConstructorInvocation node) {
     RedirectingConstructorInvocation invocation =
@@ -110,9 +124,11 @@
 
   @override
   SimpleIdentifier visitSimpleIdentifier(SimpleIdentifier node) {
-    SimpleIdentifier identifier = super.visitSimpleIdentifier(node);
-    identifier.staticElement = node.staticElement;
-    return identifier;
+    SimpleIdentifierImpl copy = super.visitSimpleIdentifier(node);
+    copy.staticElement = node.staticElement;
+    copy.staticType = node.staticType;
+    copy.tearOffTypeArgumentTypes = node.tearOffTypeArgumentTypes;
+    return copy;
   }
 
   @override
diff --git a/pkg/analyzer/lib/src/dart/element/member.dart b/pkg/analyzer/lib/src/dart/element/member.dart
index fc66691..6d27b90 100644
--- a/pkg/analyzer/lib/src/dart/element/member.dart
+++ b/pkg/analyzer/lib/src/dart/element/member.dart
@@ -941,7 +941,7 @@
   TypeParameterType instantiate({
     @required NullabilitySuffix nullabilitySuffix,
   }) {
-    return baseElement.instantiate(nullabilitySuffix: nullabilitySuffix);
+    return TypeParameterTypeImpl(this, nullabilitySuffix: nullabilitySuffix);
   }
 
   @override
@@ -968,37 +968,39 @@
   }
 
   static List<TypeParameterElement> from2(
-    List<TypeParameterElement> formals,
+    List<TypeParameterElement> elements,
     MapSubstitution substitution,
   ) {
     if (substitution.map.isEmpty) {
-      return formals;
+      return elements;
     }
 
     // Create type formals with specialized bounds.
     // For example `<U extends T>` where T comes from an outer scope.
-    var newElements = formals.toList(growable: false);
-    var newTypes = List<TypeParameterType>(formals.length);
+    var newElements = List<TypeParameterElement>(elements.length);
+    var newTypes = List<TypeParameterType>(elements.length);
     for (int i = 0; i < newElements.length; i++) {
-      var formal = newElements[i];
-      DartType bound = formal?.bound;
+      var element = elements[i];
+      var bound = element?.bound;
       if (bound != null) {
         bound = substitution.substituteType(bound);
-        var member = TypeParameterMember(formal, substitution, bound);
-        newElements[i] = member;
+        element = TypeParameterMember(element, substitution, bound);
       }
-      newTypes[i] = newElements[i].type;
+      newElements[i] = element;
+      newTypes[i] = newElements[i].instantiate(
+        nullabilitySuffix: NullabilitySuffix.none,
+      );
     }
 
     // Recursive bounds are allowed too, so make sure these are updated
     // to refer to any new TypeParameterMember we just made, rather than
     // the original type parameter
-    var substitution2 = Substitution.fromPairs(formals, newTypes);
-    for (var formal in newElements) {
-      if (formal is TypeParameterMember) {
+    var substitution2 = Substitution.fromPairs(elements, newTypes);
+    for (var newElement in newElements) {
+      if (newElement is TypeParameterMember) {
         // TODO(jmesserly): this is required so substituting for the
         // type formal will work. Investigate if there's a better solution.
-        formal._bound = substitution2.substituteType(formal.bound);
+        newElement._bound = substitution2.substituteType(newElement.bound);
       }
     }
     return newElements;
diff --git a/pkg/analyzer/lib/src/dart/element/type.dart b/pkg/analyzer/lib/src/dart/element/type.dart
index f5b08f4..68a0c7c 100644
--- a/pkg/analyzer/lib/src/dart/element/type.dart
+++ b/pkg/analyzer/lib/src/dart/element/type.dart
@@ -16,8 +16,6 @@
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/type_system.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart';
-import 'package:analyzer/src/summary/resynthesize.dart'
-    show RecursiveInstantiateToBounds;
 
 /// Transforms the given [list] by applying [transform] to all its elements.
 ///
@@ -765,8 +763,9 @@
             name = e.name + subscript;
             counter++;
           }
-          TypeParameterTypeImpl t =
-              new TypeParameterTypeImpl(new TypeParameterElementImpl(name, -1));
+          TypeParameterTypeImpl t = new TypeParameterTypeImpl(
+              new TypeParameterElementImpl(name, -1),
+              nullabilitySuffix: NullabilitySuffix.none);
           t.appendTo(typeParametersBuffer, visitedTypes,
               withNullability: withNullability);
           instantiateTypeArgs.add(t);
@@ -1573,13 +1572,7 @@
   @override
   List<DartType> get typeArguments {
     if (_typeArguments == null) {
-      try {
-        _typeArguments = _typeArgumentsComputer();
-      } on RecursiveInstantiateToBounds {
-        _typeArguments = new List<DartType>.filled(
-            element.typeParameters.length,
-            element.context.typeProvider.dynamicType);
-      }
+      _typeArguments = _typeArgumentsComputer();
       _typeArgumentsComputer = null;
     }
     return _typeArguments;
diff --git a/pkg/analyzer/lib/src/dart/element/type_algebra.dart b/pkg/analyzer/lib/src/dart/element/type_algebra.dart
index 9a60696..2a0a6e3 100644
--- a/pkg/analyzer/lib/src/dart/element/type_algebra.dart
+++ b/pkg/analyzer/lib/src/dart/element/type_algebra.dart
@@ -191,17 +191,6 @@
 
   _FreshTypeParametersSubstitutor(_TypeSubstitutor outer) : super(outer);
 
-  TypeParameterElement freshTypeParameter(TypeParameterElement element) {
-    var freshElement = new TypeParameterElementImpl(element.name, -1);
-    var freshType = new TypeParameterTypeImpl(freshElement);
-    freshElement.type = freshType;
-    substitution[element] = freshType;
-    if (element.bound != null) {
-      freshElement.bound = visit(element.bound);
-    }
-    return freshElement;
-  }
-
   @override
   List<TypeParameterElement> freshTypeParameters(
       List<TypeParameterElement> elements) {
@@ -445,7 +434,8 @@
       return type;
     }
 
-    return new InterfaceTypeImpl.explicit(type.element, typeArguments);
+    return new InterfaceTypeImpl.explicit(type.element, typeArguments,
+        nullabilitySuffix: (type as TypeImpl).nullabilitySuffix);
   }
 
   @override
diff --git a/pkg/analyzer/lib/src/dart/error/hint_codes.dart b/pkg/analyzer/lib/src/dart/error/hint_codes.dart
index 4548218..281fecf 100644
--- a/pkg/analyzer/lib/src/dart/error/hint_codes.dart
+++ b/pkg/analyzer/lib/src/dart/error/hint_codes.dart
@@ -748,7 +748,8 @@
       "The class '{0}' wasn't exported from 'dart:core' until version 2.1, "
           "but this code is required to be able to run on earlier versions.",
       correction:
-          "Try either importing 'dart:async' or updating the SDK constraints.");
+          "Try either importing 'dart:async' or updating the SDK constraints.",
+      hasPublishedDocs: true);
 
   /**
    * No parameters.
@@ -804,7 +805,8 @@
       "The use of an as expression in a constant expression wasn't "
           "supported until version 2.3.2, but this code is required to be able "
           "to run on earlier versions.",
-      correction: "Try updating the SDK constraints.");
+      correction: "Try updating the SDK constraints.",
+      hasPublishedDocs: true);
 
   /**
    * No parameters.
@@ -862,7 +864,8 @@
       "The use of the operator '{0}' for 'bool' operands in a constant context "
           "wasn't supported until version 2.3.2, but this code is required to "
           "be able to run on earlier versions.",
-      correction: "Try updating the SDK constraints.");
+      correction: "Try updating the SDK constraints.",
+      hasPublishedDocs: true);
 
   /**
    * No parameters.
@@ -923,7 +926,8 @@
           "Using the operator '==' for non-primitive types wasn't supported "
               "until version 2.3.2, but this code is required to be able to "
               "run on earlier versions.",
-          correction: "Try updating the SDK constraints.");
+          correction: "Try updating the SDK constraints.",
+          hasPublishedDocs: true);
 
   /**
    * No parameters.
@@ -982,7 +986,8 @@
       'SDK_VERSION_EXTENSION_METHODS',
       "Extension methods weren't supported until version 2.6.0, "
           "but this code is required to be able to run on earlier versions.",
-      correction: "Try updating the SDK constraints.");
+      correction: "Try updating the SDK constraints.",
+      hasPublishedDocs: true);
 
   /**
    * No parameters.
@@ -1097,7 +1102,8 @@
       "The use of an is expression in a constant context wasn't supported "
           "until version 2.3.2, but this code is required to be able to run on "
           "earlier versions.",
-      correction: "Try updating the SDK constraints.");
+      correction: "Try updating the SDK constraints.",
+      hasPublishedDocs: true);
 
   /**
    * No parameters.
@@ -1259,7 +1265,8 @@
       'SDK_VERSION_UI_AS_CODE',
       "The for, if, and spread elements weren't supported until version 2.2.2, "
           "but this code is required to be able to run on earlier versions.",
-      correction: "Try updating the SDK constraints.");
+      correction: "Try updating the SDK constraints.",
+      hasPublishedDocs: true);
 
   /**
    * No parameters.
@@ -1322,7 +1329,8 @@
       "The if and spread elements weren't supported in constant expressions "
           "until version 2.5.0, but this code is required to be able to run on "
           "earlier versions.",
-      correction: "Try updating the SDK constraints.");
+      correction: "Try updating the SDK constraints.",
+      hasPublishedDocs: true);
 
   /**
    * When "strict-raw-types" is enabled, raw types must be inferred via the
diff --git a/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart b/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart
index 89c7e91..adf8e53 100644
--- a/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart
+++ b/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart
@@ -852,8 +852,11 @@
    * template. The correction associated with the error will be created from the
    * given [correction] template.
    */
-  const ParserErrorCode(String name, String message, {String correction})
-      : super.temporary(name, message, correction: correction);
+  const ParserErrorCode(String name, String message,
+      {String correction, bool hasPublishedDocs})
+      : super.temporary(name, message,
+            correction: correction,
+            hasPublishedDocs: hasPublishedDocs ?? false);
 
   @override
   ErrorSeverity get errorSeverity => ErrorSeverity.ERROR;
diff --git a/pkg/analyzer/lib/src/dart/error/syntactic_errors.g.dart b/pkg/analyzer/lib/src/dart/error/syntactic_errors.g.dart
index 8a12c18..ab50520 100644
--- a/pkg/analyzer/lib/src/dart/error/syntactic_errors.g.dart
+++ b/pkg/analyzer/lib/src/dart/error/syntactic_errors.g.dart
@@ -253,17 +253,20 @@
 const ParserErrorCode _EXTENSION_DECLARES_ABSTRACT_MEMBER =
     const ParserErrorCode('EXTENSION_DECLARES_ABSTRACT_MEMBER',
         r"Extensions can't declare abstract members.",
-        correction: "Try providing an implementation for the member.");
+        correction: "Try providing an implementation for the member.",
+        hasPublishedDocs: true);
 
 const ParserErrorCode _EXTENSION_DECLARES_CONSTRUCTOR = const ParserErrorCode(
     'EXTENSION_DECLARES_CONSTRUCTOR', r"Extensions can't declare constructors.",
-    correction: "Try removing the constructor declaration.");
+    correction: "Try removing the constructor declaration.",
+    hasPublishedDocs: true);
 
 const ParserErrorCode _EXTENSION_DECLARES_INSTANCE_FIELD =
     const ParserErrorCode('EXTENSION_DECLARES_INSTANCE_FIELD',
         r"Extensions can't declare instance fields",
         correction:
-            "Try removing the field declaration or making it a static field");
+            "Try removing the field declaration or making it a static field",
+        hasPublishedDocs: true);
 
 const ParserErrorCode _EXTERNAL_CLASS = const ParserErrorCode(
     'EXTERNAL_CLASS', r"Classes can't be declared to be 'external'.",
diff --git a/pkg/analyzer/lib/src/dart/resolver/flow_analysis_visitor.dart b/pkg/analyzer/lib/src/dart/resolver/flow_analysis_visitor.dart
index a7a4a3e..683b8c1 100644
--- a/pkg/analyzer/lib/src/dart/resolver/flow_analysis_visitor.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/flow_analysis_visitor.dart
@@ -13,18 +13,18 @@
 import 'package:meta/meta.dart';
 
 class AnalyzerFunctionBodyAccess
-    implements FunctionBodyAccess<VariableElement> {
+    implements FunctionBodyAccess<PromotableElement> {
   final FunctionBody node;
 
   AnalyzerFunctionBodyAccess(this.node);
 
   @override
-  bool isPotentiallyMutatedInClosure(VariableElement variable) {
+  bool isPotentiallyMutatedInClosure(PromotableElement variable) {
     return node.isPotentiallyMutatedInClosure(variable);
   }
 
   @override
-  bool isPotentiallyMutatedInScope(VariableElement variable) {
+  bool isPotentiallyMutatedInScope(PromotableElement variable) {
     return node.isPotentiallyMutatedInScope(variable);
   }
 }
@@ -48,16 +48,16 @@
   final NodeOperations<Expression> _nodeOperations;
 
   /// The reused instance for creating new [FlowAnalysis] instances.
-  final _TypeSystemTypeOperations _typeOperations;
+  final TypeSystemTypeOperations _typeOperations;
 
   /// Precomputed sets of potentially assigned variables.
-  final AssignedVariables<AstNode, VariableElement> assignedVariables;
+  final AssignedVariables<AstNode, PromotableElement> assignedVariables;
 
   /// The result for post-resolution stages of analysis.
   final FlowAnalysisResult result;
 
   /// The current flow, when resolving a function body, or `null` otherwise.
-  FlowAnalysis<Statement, Expression, VariableElement, DartType> flow;
+  FlowAnalysis<Statement, Expression, PromotableElement, DartType> flow;
 
   int _blockFunctionBodyLevel = 0;
 
@@ -65,7 +65,7 @@
       TypeSystem typeSystem, AstNode node, bool retainDataForTesting) {
     return FlowAnalysisHelper._(
         const AnalyzerNodeOperations(),
-        _TypeSystemTypeOperations(typeSystem),
+        TypeSystemTypeOperations(typeSystem),
         computeAssignedVariables(node),
         retainDataForTesting ? FlowAnalysisResult() : null);
   }
@@ -163,7 +163,7 @@
     if (_blockFunctionBodyLevel > 1) {
       assert(flow != null);
     } else {
-      flow = FlowAnalysis<Statement, Expression, VariableElement, DartType>(
+      flow = FlowAnalysis<Statement, Expression, PromotableElement, DartType>(
         _nodeOperations,
         _typeOperations,
         AnalyzerFunctionBodyAccess(node),
@@ -173,7 +173,7 @@
     var parameters = _enclosingExecutableParameters(node);
     if (parameters != null) {
       for (var parameter in parameters.parameters) {
-        flow.add(parameter.declaredElement, assigned: true);
+        flow.write(parameter.declaredElement);
       }
     }
   }
@@ -244,19 +244,14 @@
     return false;
   }
 
-  void loopVariable(DeclaredIdentifier declaredVariable) {
-    if (declaredVariable != null) {
-      flow.add(declaredVariable.declaredElement, assigned: false);
-    }
-  }
-
   void variableDeclarationList(VariableDeclarationList node) {
     if (flow != null) {
       var variables = node.variables;
       for (var i = 0; i < variables.length; ++i) {
         var variable = variables[i];
-        flow.add(variable.declaredElement,
-            assigned: variable.initializer != null);
+        if (variable.initializer != null) {
+          flow.write(variable.declaredElement);
+        }
       }
     }
   }
@@ -276,9 +271,9 @@
   }
 
   /// Computes the [AssignedVariables] map for the given [node].
-  static AssignedVariables<AstNode, VariableElement> computeAssignedVariables(
+  static AssignedVariables<AstNode, PromotableElement> computeAssignedVariables(
       AstNode node) {
-    var assignedVariables = AssignedVariables<AstNode, VariableElement>();
+    var assignedVariables = AssignedVariables<AstNode, PromotableElement>();
     node.accept(_AssignedVariablesVisitor(assignedVariables));
     return assignedVariables;
   }
@@ -333,6 +328,33 @@
   final List<AstNode> unassignedNodes = [];
 }
 
+class TypeSystemTypeOperations
+    implements TypeOperations<PromotableElement, DartType> {
+  final TypeSystem typeSystem;
+
+  TypeSystemTypeOperations(this.typeSystem);
+
+  @override
+  bool isSameType(covariant TypeImpl type1, covariant TypeImpl type2) {
+    return type1 == type2;
+  }
+
+  @override
+  bool isSubtypeOf(DartType leftType, DartType rightType) {
+    return typeSystem.isSubtypeOf(leftType, rightType);
+  }
+
+  @override
+  DartType promoteToNonNull(DartType type) {
+    return typeSystem.promoteToNonNull(type);
+  }
+
+  @override
+  DartType variableType(PromotableElement variable) {
+    return variable.type;
+  }
+}
+
 /// The visitor that gathers local variables that are potentially assigned
 /// in corresponding statements, such as loops, `switch` and `try`.
 class _AssignedVariablesVisitor extends RecursiveAstVisitor<void> {
@@ -458,35 +480,3 @@
     return promotedType ?? variable.type;
   }
 }
-
-class _TypeSystemTypeOperations
-    implements TypeOperations<VariableElement, DartType> {
-  final TypeSystem typeSystem;
-
-  _TypeSystemTypeOperations(this.typeSystem);
-
-  @override
-  bool isLocalVariable(VariableElement element) {
-    return element is LocalVariableElement;
-  }
-
-  @override
-  bool isSameType(covariant TypeImpl type1, covariant TypeImpl type2) {
-    return type1 == type2;
-  }
-
-  @override
-  bool isSubtypeOf(DartType leftType, DartType rightType) {
-    return typeSystem.isSubtypeOf(leftType, rightType);
-  }
-
-  @override
-  DartType promoteToNonNull(DartType type) {
-    return typeSystem.promoteToNonNull(type);
-  }
-
-  @override
-  DartType variableType(VariableElement variable) {
-    return variable.type;
-  }
-}
diff --git a/pkg/analyzer/lib/src/error/analyzer_error_code.dart b/pkg/analyzer/lib/src/error/analyzer_error_code.dart
index 29bcc8c..f8cb42d 100644
--- a/pkg/analyzer/lib/src/error/analyzer_error_code.dart
+++ b/pkg/analyzer/lib/src/error/analyzer_error_code.dart
@@ -13,11 +13,4 @@
             correction: correction,
             hasPublishedDocs: hasPublishedDocs ?? false,
             isUnresolvedIdentifier: isUnresolvedIdentifier ?? false);
-
-  String get url {
-    if (hasPublishedDocs) {
-      return 'https://dart.dev/tools/diagnostic-messages#${name.toLowerCase()}';
-    }
-    return null;
-  }
 }
diff --git a/pkg/analyzer/lib/src/error/codes.dart b/pkg/analyzer/lib/src/error/codes.dart
index d7f00f5..b8ebccc 100644
--- a/pkg/analyzer/lib/src/error/codes.dart
+++ b/pkg/analyzer/lib/src/error/codes.dart
@@ -137,7 +137,8 @@
   //  rather than '{0}') or split into multiple codes.
   static const CompileTimeErrorCode ABSTRACT_SUPER_MEMBER_REFERENCE =
       const CompileTimeErrorCode('ABSTRACT_SUPER_MEMBER_REFERENCE',
-          "The {0} '{1}' is always abstract in the supertype.");
+          "The {0} '{1}' is always abstract in the supertype.",
+          hasPublishedDocs: true);
 
   /**
    * Enum proposal: It is also a compile-time error to explicitly instantiate an
@@ -238,7 +239,8 @@
               "neither is more specific.",
           correction:
               "Try using an extension override to specify the extension "
-              "you want to to be chosen.");
+              "you want to to be chosen.",
+          hasPublishedDocs: true);
 
   /**
    * No parameters.
@@ -453,7 +455,8 @@
   static const CompileTimeErrorCode BUILT_IN_IDENTIFIER_AS_EXTENSION_NAME =
       const CompileTimeErrorCode('BUILT_IN_IDENTIFIER_AS_EXTENSION_NAME',
           "The built-in identifier '{0}' can't be used as an extension name.",
-          correction: "Try choosing a different name for the extension.");
+          correction: "Try choosing a different name for the extension.",
+          hasPublishedDocs: true);
 
   /**
    * 16.33 Identifier Reference: It is a compile-time error if a built-in
@@ -980,7 +983,8 @@
   // ```
   static const CompileTimeErrorCode CONST_SPREAD_EXPECTED_LIST_OR_SET =
       const CompileTimeErrorCode('CONST_SPREAD_EXPECTED_LIST_OR_SET',
-          "A list or a set is expected in this spread.");
+          "A list or a set is expected in this spread.",
+          hasPublishedDocs: true);
 
   /**
    * No parameters.
@@ -1009,7 +1013,8 @@
   // ```
   static const CompileTimeErrorCode CONST_SPREAD_EXPECTED_MAP =
       const CompileTimeErrorCode(
-          'CONST_SPREAD_EXPECTED_MAP', "A map is expected in this spread.");
+          'CONST_SPREAD_EXPECTED_MAP', "A map is expected in this spread.",
+          hasPublishedDocs: true);
 
   /**
    * 16.12.2 Const: If <i>T</i> is a parameterized type <i>S&lt;U<sub>1</sub>,
@@ -1081,7 +1086,8 @@
       const CompileTimeErrorCode('CONST_WITH_NON_CONSTANT_ARGUMENT',
           "Arguments of a constant creation must be constant expressions.",
           correction: "Try making the argument a valid constant, or "
-              "use 'new' to call the constructor.");
+              "use 'new' to call the constructor.",
+          hasPublishedDocs: true);
 
   /**
    * 16.12.2 Const: It is a compile-time error if <i>T</i> is not a class
@@ -1267,7 +1273,8 @@
   static const CompileTimeErrorCode DUPLICATE_DEFINITION =
       const CompileTimeErrorCode(
           'DUPLICATE_DEFINITION', "The name '{0}' is already defined.",
-          correction: "Try renaming one of the declarations.");
+          correction: "Try renaming one of the declarations.",
+          hasPublishedDocs: true);
 
   /**
    * 18.3 Parts: It's a compile-time error if the same library contains two part
@@ -1327,7 +1334,8 @@
   // returned by an iterator.
   static const CompileTimeErrorCode EQUAL_ELEMENTS_IN_CONST_SET =
       const CompileTimeErrorCode('EQUAL_ELEMENTS_IN_CONST_SET',
-          "Two values in a constant set can't be equal.");
+          "Two values in a constant set can't be equal.",
+          hasPublishedDocs: true);
 
   /**
    * No parameters.
@@ -1528,7 +1536,8 @@
   static const CompileTimeErrorCode EXTENSION_AS_EXPRESSION =
       const CompileTimeErrorCode('EXTENSION_AS_EXPRESSION',
           "Extension '{0}' can't be used as an expression.",
-          correction: "Try replacing it with a valid expression.");
+          correction: "Try replacing it with a valid expression.",
+          hasPublishedDocs: true);
 
   /**
    * Parameters:
@@ -1570,7 +1579,8 @@
           "Extension '{0}' can't define static member '{1}' and an instance "
               "member with the same name.",
           correction:
-              "Try renaming the member to a name that doesn't conflict.");
+              "Try renaming the member to a name that doesn't conflict.",
+          hasPublishedDocs: true);
 
   /**
    * No parameters.
@@ -1607,7 +1617,8 @@
           'EXTENSION_DECLARES_MEMBER_OF_OBJECT',
           "Extensions can't declare members with the same name as a member "
               "declared by 'Object'.",
-          correction: "Try specifying a different name for the member.");
+          correction: "Try specifying a different name for the member.",
+          hasPublishedDocs: true);
 
   /**
    * No parameters.
@@ -1651,7 +1662,8 @@
           'EXTENSION_OVERRIDE_ACCESS_TO_STATIC_MEMBER',
           "An extension override can't be used to access a static member from "
               "an extension.",
-          correction: "Try using just the name of the extension.");
+          correction: "Try using just the name of the extension.",
+          hasPublishedDocs: true);
 
   /**
    * Parameters:
@@ -1699,7 +1711,8 @@
       const CompileTimeErrorCode(
           'EXTENSION_OVERRIDE_ARGUMENT_NOT_ASSIGNABLE',
           "The type of the argument to the extension override '{0}' "
-              "isn't assignable to the extended type '{1}'.");
+              "isn't assignable to the extended type '{1}'.",
+          hasPublishedDocs: true);
 
   /**
    * No parameters.
@@ -1742,7 +1755,8 @@
           'EXTENSION_OVERRIDE_WITH_CASCADE',
           "Extension overrides have no value so they can't be used as the "
               "target of a cascade expression.",
-          correction: "Try using '.' instead of '..'.");
+          correction: "Try using '.' instead of '..'.",
+          hasPublishedDocs: true);
 
   /**
    * No parameters.
@@ -1797,7 +1811,8 @@
   static const CompileTimeErrorCode EXTENSION_OVERRIDE_WITHOUT_ACCESS =
       const CompileTimeErrorCode('EXTENSION_OVERRIDE_WITHOUT_ACCESS',
           "An extension override can only be used to access instance members.",
-          correction: 'Consider adding an access to an instance member.');
+          correction: "Consider adding an access to an instance member.",
+          hasPublishedDocs: true);
 
   /**
    * Parameters:
@@ -1833,7 +1848,8 @@
   static const CompileTimeErrorCode EXTRA_POSITIONAL_ARGUMENTS =
       const CompileTimeErrorCode('EXTRA_POSITIONAL_ARGUMENTS',
           "Too many positional arguments: {0} expected, but {1} found.",
-          correction: "Try removing the extra arguments.");
+          correction: "Try removing the extra arguments.",
+          hasPublishedDocs: true);
 
   /**
    * Parameters:
@@ -1882,7 +1898,8 @@
       const CompileTimeErrorCode('EXTRA_POSITIONAL_ARGUMENTS_COULD_BE_NAMED',
           "Too many positional arguments: {0} expected, but {1} found.",
           correction: "Try removing the extra positional arguments, "
-              "or specifying the name for named arguments.");
+              "or specifying the name for named arguments.",
+          hasPublishedDocs: true);
 
   /**
    * 7.6.1 Generative Constructors: Let <i>k</i> be a generative constructor. It
@@ -2092,7 +2109,8 @@
           "Classes and mixins can only implement other classes and mixins.",
           correction:
               "Try specifying a class or mixin, or remove the name from the "
-              "list.");
+              "list.",
+          hasPublishedDocs: true);
 
   /**
    * 10.10 Superinterfaces: It is a compile-time error if two elements in the
@@ -2446,7 +2464,8 @@
           'INVALID_EXTENSION_ARGUMENT_COUNT',
           "Extension overrides must have exactly one argument: "
               "the value of 'this' in the extension method.",
-          correction: "Try specifying exactly one argument.");
+          correction: "Try specifying exactly one argument.",
+          hasPublishedDocs: true);
 
   /**
    * 7.6.2 Factories: It is a compile-time error if <i>M</i> is not the name of
@@ -2608,7 +2627,8 @@
   static const CompileTimeErrorCode INVALID_USE_OF_COVARIANT_IN_EXTENSION =
       const CompileTimeErrorCode('INVALID_USE_OF_COVARIANT_IN_EXTENSION',
           "The 'covariant' keyword can't be used in an extension.",
-          correction: "Try removing the 'covariant' keyword.");
+          correction: "Try removing the 'covariant' keyword.",
+          hasPublishedDocs: true);
 
   /**
    * 14.2 Exports: It is a compile-time error if the compilation unit found at
@@ -2708,12 +2728,13 @@
   // ```dart
   // const collection = <String>{'a', 'b'};
   // ```
-  static const CompileTimeErrorCode MAP_ENTRY_NOT_IN_MAP =
-      const CompileTimeErrorCode('MAP_ENTRY_NOT_IN_MAP',
+  static const CompileTimeErrorCode
+      MAP_ENTRY_NOT_IN_MAP = const CompileTimeErrorCode('MAP_ENTRY_NOT_IN_MAP',
           "Map entries can only be used in a map literal.",
           correction:
               "Try converting the collection to a map or removing the map "
-              "entry.");
+              "entry.",
+          hasPublishedDocs: true);
 
   /**
    * 7 Classes: It is a compile time error if a class <i>C</i> declares a member
@@ -3148,7 +3169,8 @@
   // ```
   static const CompileTimeErrorCode NON_CONSTANT_CASE_EXPRESSION =
       const CompileTimeErrorCode(
-          'NON_CONSTANT_CASE_EXPRESSION', "Case expressions must be constant.");
+          'NON_CONSTANT_CASE_EXPRESSION', "Case expressions must be constant.",
+          hasPublishedDocs: true);
 
   /**
    * 13.9 Switch: Given a switch statement of the form <i>switch (e) {
@@ -3297,7 +3319,8 @@
   static const CompileTimeErrorCode NON_CONSTANT_MAP_KEY =
       const CompileTimeErrorCode('NON_CONSTANT_MAP_KEY',
           "The keys in a const map literal must be constant.",
-          correction: "Try removing the keyword 'const' from the map literal.");
+          correction: "Try removing the keyword 'const' from the map literal.",
+          hasPublishedDocs: true);
 
   /**
    * 12.7 Maps: It is a compile time error if either a key or a value of an
@@ -3349,7 +3372,8 @@
   static const CompileTimeErrorCode NON_CONSTANT_MAP_VALUE =
       const CompileTimeErrorCode('NON_CONSTANT_MAP_VALUE',
           "The values in a const map literal must be constant.",
-          correction: "Try removing the keyword 'const' from the map literal.");
+          correction: "Try removing the keyword 'const' from the map literal.",
+          hasPublishedDocs: true);
 
   /**
    * No parameters.
@@ -3398,7 +3422,8 @@
   static const CompileTimeErrorCode NON_CONSTANT_MAP_ELEMENT =
       const CompileTimeErrorCode('NON_CONSTANT_MAP_ELEMENT',
           "The elements in a const map literal must be constant.",
-          correction: "Try removing the keyword 'const' from the map literal.");
+          correction: "Try removing the keyword 'const' from the map literal.",
+          hasPublishedDocs: true);
 
   /**
    * 12.7 Maps: It is a compile time error if either a key or a value of an
@@ -3514,7 +3539,8 @@
   static const CompileTimeErrorCode NOT_ENOUGH_POSITIONAL_ARGUMENTS =
       const CompileTimeErrorCode('NOT_ENOUGH_POSITIONAL_ARGUMENTS',
           "{0} positional argument(s) expected, but {1} found.",
-          correction: "Try adding the missing arguments.");
+          correction: "Try adding the missing arguments.",
+          hasPublishedDocs: true);
 
   @Deprecated('Use CompileTimeErrorCode NOT_ENOUGH_POSITIONAL_ARGUMENTS')
   static const CompileTimeErrorCode NOT_ENOUGH_REQUIRED_ARGUMENTS =
@@ -3629,8 +3655,8 @@
   // var m = <int, String>{...l.asMap()};
   // ```
   static const CompileTimeErrorCode NOT_MAP_SPREAD = const CompileTimeErrorCode(
-      'NOT_MAP_SPREAD',
-      "Spread elements in map literals must implement 'Map'.");
+      'NOT_MAP_SPREAD', "Spread elements in map literals must implement 'Map'.",
+      hasPublishedDocs: true);
 
   static const CompileTimeErrorCode NOT_NULL_AWARE_NULL_SPREAD =
       const CompileTimeErrorCode(
@@ -4051,7 +4077,8 @@
           "Local variable '{0}' can't be referenced before it is declared.",
           correction: "Try moving the declaration to before the first use, or "
               "renaming the local variable so that it doesn't hide a name from "
-              "an enclosing scope.");
+              "an enclosing scope.",
+          hasPublishedDocs: true);
 
   /**
    * 12.8.1 Rethrow: It is a compile-time error if an expression of the form
@@ -4144,7 +4171,8 @@
       const CompileTimeErrorCode(
           'SUPER_IN_EXTENSION',
           "The 'super' keyword can't be used in an extension because an "
-              "extension doesn't have a superclass.");
+              "extension doesn't have a superclass.",
+          hasPublishedDocs: true);
 
   /**
    * 12.15.4 Super Invocation: A super method invocation <i>i</i> has the form
@@ -4269,6 +4297,7 @@
           'UNDEFINED_ANNOTATION', "Undefined name '{0}' used as an annotation.",
           correction:
               "Try defining the name or importing it from another library.",
+          hasPublishedDocs: true,
           isUnresolvedIdentifier: true);
 
   /**
@@ -4445,7 +4474,8 @@
           "The getter '{0}' isn't defined for the extension '{1}'.",
           correction:
               "Try correcting the name to the name of an existing getter, or "
-              "defining a getter named '{0}'.");
+              "defining a getter named '{0}'.",
+          hasPublishedDocs: true);
 
   /**
    * Parameters:
@@ -4545,7 +4575,8 @@
           "The method '{0}' isn't defined for the extension '{1}'.",
           correction:
               "Try correcting the name to the name of an existing method, or "
-              "defining a method named '{0}'.");
+              "defining a method named '{0}'.",
+          hasPublishedDocs: true);
 
   /**
    * Parameters:
@@ -4657,7 +4688,8 @@
           "The setter '{0}' isn't defined for the extension '{1}'.",
           correction:
               "Try correcting the name to the name of an existing setter, or "
-              "defining a setter named '{0}'.");
+              "defining a setter named '{0}'.",
+          hasPublishedDocs: true);
 
   /**
    * Parameters:
@@ -4799,7 +4831,8 @@
           'UNQUALIFIED_REFERENCE_TO_STATIC_MEMBER_OF_EXTENDED_TYPE',
           "Static members from the extended type or one of its superclasses "
               "must be qualified by the name of the defining type.",
-          correction: "Try adding '{0}.' before the name.");
+          correction: "Try adding '{0}.' before the name.",
+          hasPublishedDocs: true);
 
   /**
    * Parameters:
@@ -5133,7 +5166,8 @@
           "A value of type '{0}' can't be assigned to a variable of type "
               "'{1}'.",
           correction: "Try changing the type of the variable, or "
-              "casting the right-hand type to '{1}'.");
+              "casting the right-hand type to '{1}'.",
+          hasPublishedDocs: true);
 
   /**
    * Parameters:
@@ -5514,7 +5548,8 @@
               "isn't defined in any of the libraries imported using that "
               "prefix.",
           correction: "Try correcting the prefix or "
-              "importing the library that defines '{0}'.");
+              "importing the library that defines '{0}'.",
+          hasPublishedDocs: true);
 
   /**
    * Parameters:
@@ -5615,7 +5650,8 @@
           "The method '{0}' isn't defined in a superclass of '{1}'.",
           correction:
               "Try correcting the name to the name of an existing method, or "
-              "defining a method named '{0}' in a superclass.");
+              "defining a method named '{0}' in a superclass.",
+          hasPublishedDocs: true);
 
   /**
    * 12.18 Assignment: Evaluation of an assignment of the form
@@ -6000,7 +6036,8 @@
       'CAST_TO_NON_TYPE',
       "The name '{0}' isn't a type, so it can't be used in an 'as' expression.",
       correction: "Try changing the name to the name of an existing type, or "
-          "creating a type with the name '{0}'.");
+          "creating a type with the name '{0}'.",
+      hasPublishedDocs: true);
 
   /**
    * 7.4 Abstract Instance Members: It is a static warning if an abstract member
@@ -6170,7 +6207,8 @@
           // TODO(brianwilkerson) Split this error code so that we can suggest
           // initializing fields in constructors (FINAL_FIELD_NOT_INITIALIZED
           // and FINAL_VARIABLE_NOT_INITIALIZED).
-          correction: "Try initializing the variable.");
+          correction: "Try initializing the variable.",
+          hasPublishedDocs: true);
 
   /**
    * 7.6.1 Generative Constructors: Each final instance variable <i>f</i>
@@ -6829,7 +6867,8 @@
               "expression.",
           correction:
               "Try changing the name to the name of an existing type, or "
-              "creating a type with the name '{0}'.");
+              "creating a type with the name '{0}'.",
+          hasPublishedDocs: true);
 
   /**
    * 10 Generics: However, a type parameter is considered to be a malformed type
@@ -7300,7 +7339,8 @@
       {String correction, bool hasPublishedDocs})
       : type = type,
         super.temporary(name, message,
-            correction: correction, hasPublishedDocs: hasPublishedDocs);
+            correction: correction,
+            hasPublishedDocs: hasPublishedDocs ?? false);
 
   @override
   ErrorSeverity get errorSeverity => type.severity;
diff --git a/pkg/analyzer/lib/src/fasta/ast_builder.dart b/pkg/analyzer/lib/src/fasta/ast_builder.dart
index 078a9da..df889e0 100644
--- a/pkg/analyzer/lib/src/fasta/ast_builder.dart
+++ b/pkg/analyzer/lib/src/fasta/ast_builder.dart
@@ -2090,7 +2090,8 @@
   }
 
   @override
-  void endTypeVariable(Token token, int index, Token extendsOrSuper) {
+  void endTypeVariable(
+      Token token, int index, Token extendsOrSuper, Token variance) {
     debugEvent("TypeVariable");
     assert(extendsOrSuper == null ||
         optional('extends', extendsOrSuper) ||
diff --git a/pkg/analyzer/lib/src/generated/declaration_resolver.dart b/pkg/analyzer/lib/src/generated/declaration_resolver.dart
index b2d006f..a8dfa2e 100644
--- a/pkg/analyzer/lib/src/generated/declaration_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/declaration_resolver.dart
@@ -8,7 +8,6 @@
 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';
@@ -234,9 +233,7 @@
     _setGenericFunctionType(node.returnType, element.returnType);
     (node.functionExpression as FunctionExpressionImpl).declaredElement =
         element;
-    if (AnalysisDriver.useSummary2 && _enclosingUnit.linkedContext != null) {
-      node.returnType?.accept(this);
-    }
+    node.returnType?.accept(this);
     _walker._elementHolder?.addFunction(element);
     _walk(new ElementWalker.forExecutable(element, _enclosingUnit), () {
       super.visitFunctionDeclaration(node);
@@ -278,35 +275,13 @@
 
   @override
   void visitGenericFunctionType(GenericFunctionType node) {
-    if (AnalysisDriver.useSummary2 && _enclosingUnit.linkedContext != null) {
-      var builder = new LocalElementBuilder(ElementHolder(), _enclosingUnit);
-      node.accept(builder);
+    var builder = new LocalElementBuilder(ElementHolder(), _enclosingUnit);
+    node.accept(builder);
 
-      var nodeImpl = node as GenericFunctionTypeImpl;
-      _enclosingUnit.encloseElement(
-        nodeImpl.declaredElement as GenericFunctionTypeElementImpl,
-      );
-      return;
-    }
-    if (_walker.elementBuilder != null) {
-      _walker.elementBuilder.visitGenericFunctionType(node);
-    } else {
-      var element = node.type?.element;
-      if (element is GenericFunctionTypeElement) {
-        _setGenericFunctionType(node.returnType, element.returnType);
-        _walk(new ElementWalker.forGenericFunctionType(element), () {
-          super.visitGenericFunctionType(node);
-        });
-      } else {
-        var builder = new LocalElementBuilder(ElementHolder(), _enclosingUnit);
-        node.accept(builder);
-
-        var nodeImpl = node as GenericFunctionTypeImpl;
-        _enclosingUnit.encloseElement(
-          nodeImpl.declaredElement as GenericFunctionTypeElementImpl,
-        );
-      }
-    }
+    var nodeImpl = node as GenericFunctionTypeImpl;
+    _enclosingUnit.encloseElement(
+      nodeImpl.declaredElement as GenericFunctionTypeElementImpl,
+    );
   }
 
   @override
@@ -379,9 +354,7 @@
       }
     }
     _setGenericFunctionType(node.returnType, element.returnType);
-    if (AnalysisDriver.useSummary2 && _enclosingUnit.linkedContext != null) {
-      node.returnType?.accept(this);
-    }
+    node.returnType?.accept(this);
     _walk(new ElementWalker.forExecutable(element, _enclosingUnit), () {
       super.visitMethodDeclaration(node);
     });
@@ -456,19 +429,11 @@
 
   @override
   void visitTypeParameter(TypeParameter node) {
-    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);
-      node.name?.staticElement = element;
-    } else {
-      TypeParameterElement element =
-          _match(node.name, _walker.getTypeParameter());
-      _setGenericFunctionType(node.bound, element.bound);
-      super.visitTypeParameter(node);
-      resolveMetadata(node, node.metadata, element);
-    }
+    TypeParameterElement element =
+        _match(node.name, _walker.getTypeParameter());
+    _setGenericFunctionType(node.bound, element.bound);
+    super.visitTypeParameter(node);
+    resolveMetadata(node, node.metadata, element);
   }
 
   @override
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index 566e931..53038fc 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -9,11 +9,11 @@
 import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/dart/ast/visitor.dart';
 import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/nullability_suffix.dart';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/dart/element/visitor.dart';
 import 'package:analyzer/error/error.dart';
 import 'package:analyzer/error/listener.dart';
-import 'package:analyzer/src/dart/analysis/driver.dart';
 import 'package:analyzer/src/dart/ast/ast.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/inheritance_manager3.dart';
@@ -939,13 +939,6 @@
         }
       }
 
-      // TODO(paulberry): remove this once dartbug.com/28515 is fixed.
-      if (node.typeParameters != null && !AnalysisDriver.useSummary2) {
-        _errorReporter.reportErrorForNode(
-            CompileTimeErrorCode.GENERIC_FUNCTION_TYPED_PARAM_UNSUPPORTED,
-            node);
-      }
-
       super.visitFunctionTypedFormalParameter(node);
     } finally {
       _isInFunctionTypedFormalParameter = old;
@@ -1378,7 +1371,6 @@
   void visitTypeParameter(TypeParameter node) {
     _checkForBuiltInIdentifierAsName(node.name,
         CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_PARAMETER_NAME);
-    _checkForTypeParameterSupertypeOfItsBound(node);
     _checkForTypeAnnotationDeferredClass(node.bound);
     _checkForImplicitDynamicType(node.bound);
     _checkForGenericFunctionType(node.bound);
@@ -1389,6 +1381,7 @@
   @override
   void visitTypeParameterList(TypeParameterList node) {
     _duplicateDefinitionVerifier.checkTypeParameters(node);
+    _checkForTypeParameterBoundRecursion(node.typeParameters);
     super.visitTypeParameterList(node);
   }
 
@@ -3114,20 +3107,23 @@
     if (_enclosingFunction.isAsynchronous) {
       if (_enclosingFunction.isGenerator) {
         _checkForIllegalReturnTypeCode(
-            returnType,
-            _typeProvider.streamDynamicType,
-            StaticTypeWarningCode.ILLEGAL_ASYNC_GENERATOR_RETURN_TYPE);
+          returnType,
+          _typeProvider.streamElement,
+          StaticTypeWarningCode.ILLEGAL_ASYNC_GENERATOR_RETURN_TYPE,
+        );
       } else {
         _checkForIllegalReturnTypeCode(
-            returnType,
-            _typeProvider.futureDynamicType,
-            StaticTypeWarningCode.ILLEGAL_ASYNC_RETURN_TYPE);
+          returnType,
+          _typeProvider.futureElement,
+          StaticTypeWarningCode.ILLEGAL_ASYNC_RETURN_TYPE,
+        );
       }
     } else if (_enclosingFunction.isGenerator) {
       _checkForIllegalReturnTypeCode(
-          returnType,
-          _typeProvider.iterableDynamicType,
-          StaticTypeWarningCode.ILLEGAL_SYNC_GENERATOR_RETURN_TYPE);
+        returnType,
+        _typeProvider.iterableElement,
+        StaticTypeWarningCode.ILLEGAL_SYNC_GENERATOR_RETURN_TYPE,
+      );
     }
   }
 
@@ -3139,7 +3135,7 @@
    * and if not report [errorCode].
    */
   void _checkForIllegalReturnTypeCode(TypeAnnotation returnTypeName,
-      DartType expectedType, StaticTypeWarningCode errorCode) {
+      ClassElement expectedElement, StaticTypeWarningCode errorCode) {
     DartType returnType = _enclosingFunction.returnType;
     //
     // When checking an async/sync*/async* method, we know the exact type
@@ -3159,8 +3155,10 @@
     //
     // Similar logic applies for sync* and async*.
     //
-    InterfaceType genericType = (expectedType.element as ClassElement).type;
-    DartType lowerBound = genericType.instantiate([BottomTypeImpl.instance]);
+    var lowerBound = expectedElement.instantiate(
+      typeArguments: [BottomTypeImpl.instance],
+      nullabilitySuffix: NullabilitySuffix.star,
+    );
     if (!_typeSystem.isSubtypeOf(lowerBound, returnType)) {
       _errorReporter.reportErrorForNode(errorCode, returnTypeName);
     }
@@ -4931,6 +4929,44 @@
     }
   }
 
+  /**
+   * Check that none of the type [parameters] references itself in its bound.
+   *
+   * See [StaticTypeWarningCode.TYPE_PARAMETER_SUPERTYPE_OF_ITS_BOUND].
+   */
+  void _checkForTypeParameterBoundRecursion(List<TypeParameter> parameters) {
+    Map<TypeParameterElement, TypeParameter> elementToNode;
+    for (var parameter in parameters) {
+      if (parameter.bound != null) {
+        if (elementToNode == null) {
+          elementToNode = {};
+          for (var parameter in parameters) {
+            elementToNode[parameter.declaredElement] = parameter;
+          }
+        }
+
+        TypeParameter current = parameter;
+        for (var step = 0; current != null; step++) {
+          var bound = current.bound;
+          if (bound is TypeName) {
+            current = elementToNode[bound.name.staticElement];
+          } else {
+            current = null;
+          }
+          if (step == parameters.length) {
+            var element = parameter.declaredElement;
+            _errorReporter.reportErrorForNode(
+              StaticTypeWarningCode.TYPE_PARAMETER_SUPERTYPE_OF_ITS_BOUND,
+              parameter,
+              [element.displayName, element.bound.displayName],
+            );
+            break;
+          }
+        }
+      }
+    }
+  }
+
   void _checkForTypeParameterReferencedByStatic(SimpleIdentifier identifier) {
     if (_isInStaticMethod || _isInStaticVariableDeclaration) {
       var element = identifier.staticElement;
@@ -4946,29 +4982,6 @@
   }
 
   /**
-   * Check whether the given type [parameter] is a supertype of its bound.
-   *
-   * See [StaticTypeWarningCode.TYPE_PARAMETER_SUPERTYPE_OF_ITS_BOUND].
-   */
-  void _checkForTypeParameterSupertypeOfItsBound(TypeParameter parameter) {
-    TypeParameterElement element = parameter.declaredElement;
-    // prepare bound
-    DartType bound = element.bound;
-    if (bound == null) {
-      return;
-    }
-    // OK, type parameter is not supertype of its bound
-    if (!_typeSystem.isSubtypeOf(bound, element.type)) {
-      return;
-    }
-
-    _errorReporter.reportErrorForNode(
-        StaticTypeWarningCode.TYPE_PARAMETER_SUPERTYPE_OF_ITS_BOUND,
-        parameter,
-        [element.displayName, bound.displayName]);
-  }
-
-  /**
    * Check that if the given generative [constructor] has neither an explicit
    * super constructor invocation nor a redirecting constructor invocation, that
    * the superclass has a default generative constructor.
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 66c7f6c..16c150d 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -344,6 +344,12 @@
   }
 
   @override
+  void visitFunctionTypeAlias(FunctionTypeAlias node) {
+    _checkStrictInferenceReturnType(node.returnType, node, node.name.name);
+    super.visitFunctionTypeAlias(node);
+  }
+
+  @override
   void visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
     _checkStrictInferenceReturnType(
         node.returnType, node, node.identifier.name);
@@ -352,6 +358,25 @@
   }
 
   @override
+  void visitGenericFunctionType(GenericFunctionType node) {
+    // GenericTypeAlias is handled in [visitGenericTypeAlias], where a proper
+    // name can be reported in any message.
+    if (node.parent is! GenericTypeAlias) {
+      _checkStrictInferenceReturnType(node.returnType, node, node.toString());
+    }
+    super.visitGenericFunctionType(node);
+  }
+
+  @override
+  void visitGenericTypeAlias(GenericTypeAlias node) {
+    if (node.functionType != null) {
+      _checkStrictInferenceReturnType(
+          node.functionType.returnType, node, node.name.name);
+    }
+    super.visitGenericTypeAlias(node);
+  }
+
+  @override
   void visitImportDirective(ImportDirective node) {
     _checkForDeprecatedMemberUse(node.uriElement, node);
     ImportElement importElement = node.element;
@@ -384,6 +409,18 @@
   void visitMethodDeclaration(MethodDeclaration node) {
     bool wasInDeprecatedMember = _inDeprecatedMember;
     ExecutableElement element = node.declaredElement;
+    bool elementIsOverride() {
+      if (element is ClassMemberElement) {
+        Name name = new Name(_currentLibrary.source.uri, element.name);
+        Element enclosingElement = element.enclosingElement;
+        if (enclosingElement is ClassElement) {
+          InterfaceType classType = enclosingElement.thisType;
+          return _inheritanceManager.getOverridden(classType, name) != null;
+        }
+      }
+      return false;
+    }
+
     if (element != null && element.hasDeprecated) {
       _inDeprecatedMember = true;
     }
@@ -392,7 +429,9 @@
       //checkForOverridingPrivateMember(node);
       _checkForMissingReturn(node.returnType, node.body, element, node);
       _checkForUnnecessaryNoSuchMethod(node);
-      _checkStrictInferenceReturnType(node.returnType, node, node.name.name);
+      if (_strictInference && !node.isSetter && !elementIsOverride()) {
+        _checkStrictInferenceReturnType(node.returnType, node, node.name.name);
+      }
       _checkStrictInferenceInParameters(node.parameters);
       super.visitMethodDeclaration(node);
     } finally {
@@ -2964,7 +3003,8 @@
   const ResolverErrorCode(String name, String message,
       {String correction, bool hasPublishedDocs})
       : super.temporary(name, message,
-            correction: correction, hasPublishedDocs: hasPublishedDocs);
+            correction: correction,
+            hasPublishedDocs: hasPublishedDocs ?? false);
 
   @override
   ErrorSeverity get errorSeverity => type.severity;
@@ -2983,6 +3023,11 @@
 
   final AnalysisOptionsImpl _analysisOptions;
 
+  /**
+   * The feature set that is enabled for the current unit.
+   */
+  final FeatureSet _featureSet;
+
   final bool _uiAsCodeEnabled;
 
   /// Helper for extension method resolution.
@@ -3090,6 +3135,7 @@
       reportConstEvaluationErrors,
       this._flowAnalysis)
       : _analysisOptions = definingLibrary.context.analysisOptions,
+        _featureSet = featureSet,
         _uiAsCodeEnabled =
             featureSet.isEnabled(Feature.control_flow_collections) ||
                 featureSet.isEnabled(Feature.spread_collections),
@@ -3125,6 +3171,17 @@
     }
   }
 
+  NullabilitySuffix get _noneOrStarSuffix {
+    return _nonNullableEnabled
+        ? NullabilitySuffix.none
+        : NullabilitySuffix.star;
+  }
+
+  /**
+   * Return `true` if NNBD is enabled for this compilation unit.
+   */
+  bool get _nonNullableEnabled => _featureSet.isEnabled(Feature.non_nullable);
+
   /// Return the static element associated with the given expression whose type
   /// can be overridden, or `null` if there is no element whose type can be
   /// overridden.
@@ -3182,10 +3239,11 @@
 
     // Same number of type formals. Instantiate the function type so its
     // parameter and return type are in terms of the surrounding context.
-    return fnType.instantiate(typeParameters
-        .map((TypeParameter t) =>
-            (t.name.staticElement as TypeParameterElement).type)
-        .toList());
+    return fnType.instantiate(typeParameters.map((TypeParameter t) {
+      return t.declaredElement.instantiate(
+        nullabilitySuffix: _noneOrStarSuffix,
+      );
+    }).toList());
   }
 
   /// If it is appropriate to do so, override the current type of the static
@@ -3825,7 +3883,6 @@
       // variable cannot be in scope while visiting the iterator.
       //
       iterable?.accept(this);
-      _flowAnalysis?.loopVariable(loopVariable);
       loopVariable?.accept(this);
       _flowAnalysis?.flow?.forEach_bodyBegin(
           _flowAnalysis.assignedVariables.writtenInNode(node),
@@ -3905,7 +3962,6 @@
       // cannot be in scope while visiting the iterator.
       //
       iterable?.accept(this);
-      _flowAnalysis?.loopVariable(loopVariable);
       loopVariable?.accept(this);
 
       _flowAnalysis?.flow?.forEach_bodyBegin(
@@ -4452,10 +4508,10 @@
       var catchClause = catchClauses[i];
       flow.tryCatchStatement_catchBegin();
       if (catchClause.exceptionParameter != null) {
-        flow.add(catchClause.exceptionParameter.staticElement, assigned: true);
+        flow.write(catchClause.exceptionParameter.staticElement);
       }
       if (catchClause.stackTraceParameter != null) {
-        flow.add(catchClause.stackTraceParameter.staticElement, assigned: true);
+        flow.write(catchClause.stackTraceParameter.staticElement);
       }
       catchClause.accept(this);
       flow.tryCatchStatement_catchEnd();
@@ -5835,6 +5891,10 @@
       : dynamicType = typeProvider.dynamicType,
         analysisOptions = definingLibrary.context.analysisOptions;
 
+  NullabilitySuffix get _noneOrStarSuffix {
+    return isNonNullableUnit ? NullabilitySuffix.none : NullabilitySuffix.star;
+  }
+
   /// Report an error with the given error code and arguments.
   ///
   /// @param errorCode the error code of the error to be reported
@@ -5995,8 +6055,10 @@
         SimpleIdentifier identifier =
             (typeName as PrefixedIdentifier).identifier;
         Element prefixElement = nameScope.lookup(prefix, definingLibrary);
+        ClassElement classElement;
         ConstructorElement constructorElement;
         if (prefixElement is ClassElement) {
+          classElement = prefixElement;
           constructorElement =
               prefixElement.getNamedConstructor(identifier.name);
         }
@@ -6006,10 +6068,16 @@
               argumentList,
               [prefix.name, identifier.name]);
           prefix.staticElement = prefixElement;
-          prefix.staticType = (prefixElement as ClassElement).type;
+          prefix.staticType = classElement.instantiate(
+            typeArguments: List.filled(
+              classElement.typeParameters.length,
+              dynamicType,
+            ),
+            nullabilitySuffix: _noneOrStarSuffix,
+          );
           identifier.staticElement = constructorElement;
           identifier.staticType = constructorElement.type;
-          typeName.staticType = constructorElement.enclosingElement.type;
+          typeName.staticType = prefix.staticType;
           AstNode grandParent = node.parent.parent;
           if (grandParent is InstanceCreationExpressionImpl) {
             grandParent.staticElement = constructorElement;
@@ -6056,7 +6124,7 @@
       return;
     }
 
-    TypeImpl type = null;
+    DartType type = null;
     if (element == DynamicElementImpl.instance) {
       _setElement(typeName, element);
       type = DynamicTypeImpl.instance;
@@ -6067,13 +6135,14 @@
       );
     } else if (element is FunctionTypeAliasElement) {
       _setElement(typeName, element);
-      type = element.type as TypeImpl;
     } else if (element is TypeParameterElement) {
       _setElement(typeName, element);
-      type = element.type as TypeImpl;
+      type = element.instantiate(
+        nullabilitySuffix: _getNullability(node.question != null),
+      );
     } else if (element is MultiplyDefinedElement) {
-      List<Element> elements = element.conflictingElements;
-      type = _getTypeWhenMultiplyDefined(elements) as TypeImpl;
+      var elements = (element as MultiplyDefinedElement).conflictingElements;
+      element = _getElementWhenMultiplyDefined(elements);
     } else {
       // The name does not represent a type.
       if (_isTypeNameInCatchClause(node)) {
@@ -6116,9 +6185,15 @@
       return;
     }
     if (argumentList != null) {
+      var parameters = const <TypeParameterElement>[];
+      if (element is ClassElement) {
+        parameters = element.typeParameters;
+      } else if (element is FunctionTypeAliasElement) {
+        parameters = element.typeParameters;
+      }
+
       NodeList<TypeAnnotation> arguments = argumentList.arguments;
       int argumentCount = arguments.length;
-      List<DartType> parameters = typeSystem.typeFormalsAsTypes(type);
       int parameterCount = parameters.length;
       List<DartType> typeArguments = new List<DartType>(parameterCount);
       if (argumentCount == parameterCount) {
@@ -6139,6 +6214,9 @@
       } else {
         type = typeSystem.instantiateType(type, typeArguments);
       }
+      type = (type as TypeImpl).withNullability(
+        _getNullability(node.question != null),
+      );
     } else {
       if (element is GenericTypeAliasElementImpl) {
         List<DartType> typeArguments =
@@ -6146,18 +6224,36 @@
         type = GenericTypeAliasElementImpl.typeAfterSubstitution(
                 element, typeArguments) ??
             dynamicType;
+        type = (type as TypeImpl).withNullability(
+          _getNullability(node.question != null),
+        );
       } else {
         type = typeSystem.instantiateToBounds(type);
       }
     }
 
-    var nullability = _getNullability(node.question != null);
-    type = type.withNullability(nullability);
-
     typeName.staticType = type;
     node.type = type;
   }
 
+  /// Given the multiple elements to which a single name could potentially be
+  /// resolved, return the single [ClassElement] that should be used, or `null`
+  /// if there is no clear choice.
+  ///
+  /// @param elements the elements to which a single name could potentially be
+  ///        resolved
+  /// @return the single interface type that should be used for the type name
+  ClassElement _getElementWhenMultiplyDefined(List<Element> elements) {
+    int length = elements.length;
+    for (int i = 0; i < length; i++) {
+      Element element = elements[i];
+      if (element is ClassElement) {
+        return element;
+      }
+    }
+    return null;
+  }
+
   DartType _getInferredMixinType(
       ClassElement classElement, ClassElement mixinElement) {
     for (var candidateMixin in classElement.mixins) {
@@ -6229,28 +6325,6 @@
     }
   }
 
-  /// Given the multiple elements to which a single name could potentially be
-  /// resolved, return the single interface type that should be used, or `null`
-  /// if there is no clear choice.
-  ///
-  /// @param elements the elements to which a single name could potentially be
-  ///        resolved
-  /// @return the single interface type that should be used for the type name
-  InterfaceType _getTypeWhenMultiplyDefined(List<Element> elements) {
-    InterfaceType type = null;
-    int length = elements.length;
-    for (int i = 0; i < length; i++) {
-      Element element = elements[i];
-      if (element is ClassElement) {
-        if (type != null) {
-          return null;
-        }
-        type = element.type;
-      }
-    }
-    return type;
-  }
-
   /// If the [node] is the type name in a redirected factory constructor,
   /// infer type arguments using the enclosing class declaration. Return `null`
   /// otherwise.
@@ -6814,13 +6888,6 @@
   /// [nameScope] was computed.
   bool _localModeScopeReady = false;
 
-  /// Indicates whether the ClassElement fields interfaces, mixins, and
-  /// supertype should be set by this visitor.
-  ///
-  /// This is needed when using the old task model, but causes problems with the
-  /// new driver.
-  final bool shouldSetElementSupertypes;
-
   /// Initialize a newly created visitor to resolve the nodes in an AST node.
   ///
   /// [definingLibrary] is the element for the library containing the node being
@@ -6843,8 +6910,7 @@
       @Deprecated('Use featureSet instead') bool isNonNullableUnit: false,
       FeatureSet featureSet,
       this.mode: TypeResolverMode.everything,
-      bool shouldUseWithClauseInferredTypes: true,
-      this.shouldSetElementSupertypes: false})
+      bool shouldUseWithClauseInferredTypes: true})
       : isNonNullableUnit = featureSet?.isEnabled(Feature.non_nullable) ??
             // ignore: deprecated_member_use_from_same_package
             isNonNullableUnit,
@@ -6939,22 +7005,11 @@
     WithClause withClause = node.withClause;
     ImplementsClause implementsClause = node.implementsClause;
     ClassElementImpl classElement = _getClassElement(node.name);
-    InterfaceType superclassType = null;
     if (extendsClause != null) {
       ErrorCode errorCode = (withClause == null
           ? CompileTimeErrorCode.EXTENDS_NON_CLASS
           : CompileTimeErrorCode.MIXIN_WITH_NON_CLASS_SUPERCLASS);
-      superclassType =
-          _resolveType(extendsClause.superclass, errorCode, asClass: true);
-    }
-    if (shouldSetElementSupertypes && classElement != null) {
-      if (superclassType == null) {
-        InterfaceType objectType = typeProvider.objectType;
-        if (!identical(classElement.type, objectType)) {
-          superclassType = objectType;
-        }
-      }
-      classElement.supertype = superclassType;
+      _resolveType(extendsClause.superclass, errorCode, asClass: true);
     }
     _resolveWithClause(classElement, withClause);
     _resolveImplementsClause(classElement, implementsClause);
@@ -6988,16 +7043,12 @@
   @override
   void visitClassTypeAlias(ClassTypeAlias node) {
     super.visitClassTypeAlias(node);
-    ErrorCode errorCode = CompileTimeErrorCode.MIXIN_WITH_NON_CLASS_SUPERCLASS;
-    InterfaceType superclassType =
-        _resolveType(node.superclass, errorCode, asClass: true);
-    if (superclassType == null) {
-      superclassType = typeProvider.objectType;
-    }
+    _resolveType(
+      node.superclass,
+      CompileTimeErrorCode.MIXIN_WITH_NON_CLASS_SUPERCLASS,
+      asClass: true,
+    );
     ClassElementImpl classElement = _getClassElement(node.name);
-    if (shouldSetElementSupertypes && classElement != null) {
-      classElement.supertype = superclassType;
-    }
     _resolveWithClause(classElement, node.withClause);
     _resolveImplementsClause(classElement, node.implementsClause);
   }
@@ -7437,27 +7488,20 @@
   void _resolveImplementsClause(
       ClassElementImpl classElement, ImplementsClause clause) {
     if (clause != null) {
-      NodeList<TypeName> interfaces = clause.interfaces;
-      List<InterfaceType> interfaceTypes =
-          _resolveTypes(interfaces, CompileTimeErrorCode.IMPLEMENTS_NON_CLASS);
-      if (shouldSetElementSupertypes && classElement != null) {
-        classElement.interfaces = interfaceTypes;
-      }
+      _resolveTypes(
+          clause.interfaces, CompileTimeErrorCode.IMPLEMENTS_NON_CLASS);
     }
   }
 
   void _resolveOnClause(MixinElementImpl classElement, OnClause clause) {
     List<InterfaceType> types;
     if (clause != null) {
-      types = _resolveTypes(clause.superclassConstraints,
+      _resolveTypes(clause.superclassConstraints,
           CompileTimeErrorCode.MIXIN_SUPER_CLASS_CONSTRAINT_NON_INTERFACE);
     }
     if (types == null || types.isEmpty) {
       types = [typeProvider.objectType];
     }
-    if (shouldSetElementSupertypes) {
-      classElement.superclassConstraints = types;
-    }
   }
 
   /// Return the [InterfaceType] of the given [typeName].
@@ -7467,7 +7511,7 @@
   /// The flag [asClass] specifies if the type will be used as a class, so mixin
   /// declarations are not valid (they declare interfaces and mixins, but not
   /// classes).
-  InterfaceType _resolveType(TypeName typeName, ErrorCode errorCode,
+  void _resolveType(TypeName typeName, ErrorCode errorCode,
       {bool asClass: false}) {
     DartType type = typeName.type;
     if (type is InterfaceType) {
@@ -7475,10 +7519,10 @@
       if (element != null) {
         if (element.isEnum || element.isMixin && asClass) {
           errorReporter.reportErrorForNode(errorCode, typeName);
-          return null;
+          return;
         }
       }
-      return type;
+      return;
     }
     // If the type is not an InterfaceType, then visitTypeName() sets the type
     // to be a DynamicTypeImpl
@@ -7486,7 +7530,6 @@
     if (!nameScope.shouldIgnoreUndefined(name)) {
       errorReporter.reportErrorForNode(errorCode, name, [name.name]);
     }
-    return null;
   }
 
   /// Resolve the types in the given list of type names.
@@ -7498,25 +7541,15 @@
   ///        be an enum
   /// @param dynamicTypeError the error to produce if the type name is "dynamic"
   /// @return an array containing all of the types that were resolved.
-  List<InterfaceType> _resolveTypes(
-      NodeList<TypeName> typeNames, ErrorCode errorCode) {
-    List<InterfaceType> types = new List<InterfaceType>();
+  void _resolveTypes(NodeList<TypeName> typeNames, ErrorCode errorCode) {
     for (TypeName typeName in typeNames) {
-      InterfaceType type = _resolveType(typeName, errorCode);
-      if (type != null) {
-        types.add(type);
-      }
+      _resolveType(typeName, errorCode);
     }
-    return types;
   }
 
   void _resolveWithClause(ClassElementImpl classElement, WithClause clause) {
     if (clause != null) {
-      List<InterfaceType> mixinTypes = _resolveTypes(
-          clause.mixinTypes, CompileTimeErrorCode.MIXIN_OF_NON_CLASS);
-      if (shouldSetElementSupertypes) {
-        classElement.mixins = mixinTypes;
-      }
+      _resolveTypes(clause.mixinTypes, CompileTimeErrorCode.MIXIN_OF_NON_CLASS);
     }
   }
 
diff --git a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
index 1263674..e8108bb 100644
--- a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
+++ b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
@@ -9,7 +9,6 @@
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/nullability_suffix.dart';
 import 'package:analyzer/dart/element/type.dart';
-import 'package:analyzer/src/dart/analysis/driver.dart';
 import 'package:analyzer/src/dart/ast/ast.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/member.dart' show ConstructorMember;
@@ -2177,12 +2176,8 @@
 
   static DartType _getFreshType(DartType type) {
     if (type is FunctionType) {
-      if (AnalysisDriver.useSummary2) {
-        var parameters = getFreshTypeParameters(type.typeFormals);
-        return parameters.applyToFunctionType(type);
-      } else {
-        return new FunctionTypeImpl.fresh(type);
-      }
+      var parameters = getFreshTypeParameters(type.typeFormals);
+      return parameters.applyToFunctionType(type);
     } else {
       return type;
     }
diff --git a/pkg/analyzer/lib/src/generated/type_system.dart b/pkg/analyzer/lib/src/generated/type_system.dart
index 5f384f0..7a84adf 100644
--- a/pkg/analyzer/lib/src/generated/type_system.dart
+++ b/pkg/analyzer/lib/src/generated/type_system.dart
@@ -13,7 +13,6 @@
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/dart/element/type_system.dart' as public;
 import 'package:analyzer/error/listener.dart' show ErrorReporter;
-import 'package:analyzer/src/dart/analysis/driver.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/member.dart' show TypeParameterMember;
 import 'package:analyzer/src/dart/element/type.dart';
@@ -379,15 +378,13 @@
             parameters ??= <TypeParameterElement>[];
             parameters.add(element);
           }
-        } else if (AnalysisDriver.useSummary2) {
+        } else {
           if (type is FunctionType) {
             appendParameters(type.returnType);
             type.parameters.map((p) => p.type).forEach(appendParameters);
           } else if (type is InterfaceType) {
             type.typeArguments.forEach(appendParameters);
           }
-        } else if (type is ParameterizedType) {
-          type.typeArguments.forEach(appendParameters);
         }
       }
 
@@ -461,13 +458,9 @@
       return const <DartType>[];
     }
 
-    if (AnalysisDriver.useSummary2) {
-      return typeParameters
-          .map((p) => (p as TypeParameterElementImpl).defaultType)
-          .toList();
-    } else {
-      return instantiateTypeFormalsToBounds(typeParameters);
-    }
+    return typeParameters
+        .map((p) => (p as TypeParameterElementImpl).defaultType)
+        .toList();
   }
 
   @override
@@ -2141,7 +2134,7 @@
   static int _computeLongestInheritancePathToObject(
       ClassElement element, int depth, Set<ClassElement> visitedElements) {
     // Object case
-    if (element.supertype == null || visitedElements.contains(element)) {
+    if (element.isDartCoreObject || visitedElements.contains(element)) {
       return depth;
     }
     int longestPath = 1;
@@ -2790,13 +2783,7 @@
     // Calculate the LUB of the return type.
     DartType returnType = getLeastUpperBound(f.returnType, g.returnType);
 
-    if (AnalysisDriver.useSummary2) {
-      return FunctionTypeImpl.synthetic(returnType, typeFormals, parameters);
-    }
-
-    var element = FunctionElementImpl.synthetic(parameters, returnType);
-    element.typeParameters = typeFormals;
-    return element.type;
+    return FunctionTypeImpl.synthetic(returnType, typeFormals, parameters);
   }
 
   /**
diff --git a/pkg/analyzer/lib/src/summary/expr_builder.dart b/pkg/analyzer/lib/src/summary/expr_builder.dart
deleted file mode 100644
index ed9493b..0000000
--- a/pkg/analyzer/lib/src/summary/expr_builder.dart
+++ /dev/null
@@ -1,1127 +0,0 @@
-// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/ast/standard_ast_factory.dart';
-import 'package:analyzer/dart/ast/token.dart';
-import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/dart/element/type.dart';
-import 'package:analyzer/src/dart/analysis/experiments.dart';
-import 'package:analyzer/src/dart/ast/ast.dart';
-import 'package:analyzer/src/dart/element/element.dart';
-import 'package:analyzer/src/dart/resolver/ast_rewrite.dart';
-import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/testing/ast_test_factory.dart';
-import 'package:analyzer/src/generated/testing/token_factory.dart';
-import 'package:analyzer/src/summary/idl.dart';
-import 'package:analyzer/src/summary/resynthesize.dart';
-
-bool _isSpreadOrControlFlowEnabled(ExperimentStatus experimentStatus) =>
-    experimentStatus.spread_collections ||
-    experimentStatus.control_flow_collections;
-
-/**
- * Builder of [Expression]s from [UnlinkedExpr]s.
- */
-class ExprBuilder {
-  static const ARGUMENT_LIST = 'ARGUMENT_LIST';
-
-  final UnitResynthesizer resynthesizer;
-  final ElementImpl context;
-  final UnlinkedExpr _uc;
-  final bool requireValidConst;
-  final bool isSpreadOrControlFlowEnabled;
-  final bool becomeSetOrMap;
-
-  int intPtr = 0;
-  int doublePtr = 0;
-  int stringPtr = 0;
-  int refPtr = 0;
-  int assignmentOperatorPtr = 0;
-
-  // The stack of values. Note that they are usually [Expression]s, but may be
-  // any [CollectionElement] to support map/set/list literals.
-  final List<AstNode> stack = <AstNode>[];
-
-  final List<UnlinkedExecutable> localFunctions;
-
-  final _VariablesInScope variablesInScope;
-
-  ExprBuilder(
-    this.resynthesizer,
-    this.context,
-    this._uc, {
-    this.requireValidConst: true,
-    this.localFunctions,
-    _VariablesInScope variablesInScope,
-    this.becomeSetOrMap: true,
-  })  : this.variablesInScope = variablesInScope ?? _parametersInScope(context),
-        this.isSpreadOrControlFlowEnabled = _isSpreadOrControlFlowEnabled(
-            (resynthesizer.library.context.analysisOptions
-                    as AnalysisOptionsImpl)
-                .experimentStatus);
-
-  bool get hasNonEmptyExpr => _uc != null && _uc.operations.isNotEmpty;
-
-  Expression build() {
-    if (requireValidConst && !_uc.isValidConst) {
-      return null;
-    }
-    int startingVariableCount = variablesInScope.count;
-    for (UnlinkedExprOperation operation in _uc.operations) {
-      switch (operation) {
-        case UnlinkedExprOperation.pushNull:
-          _push(AstTestFactory.nullLiteral());
-          break;
-        // bool
-        case UnlinkedExprOperation.pushFalse:
-          _push(AstTestFactory.booleanLiteral(false));
-          break;
-        case UnlinkedExprOperation.pushTrue:
-          _push(AstTestFactory.booleanLiteral(true));
-          break;
-        // literals
-        case UnlinkedExprOperation.pushInt:
-          int value = _uc.ints[intPtr++];
-          _push(AstTestFactory.integer(value));
-          break;
-        case UnlinkedExprOperation.pushLongInt:
-          int value = 0;
-          int count = _uc.ints[intPtr++];
-          for (int i = 0; i < count; i++) {
-            int next = _uc.ints[intPtr++];
-            value = value << 32 | next;
-          }
-          _push(AstTestFactory.integer(value));
-          break;
-        case UnlinkedExprOperation.pushDouble:
-          double value = _uc.doubles[doublePtr++];
-          _push(AstTestFactory.doubleLiteral(value));
-          break;
-        case UnlinkedExprOperation.makeSymbol:
-          String component = _uc.strings[stringPtr++];
-          _push(AstTestFactory.symbolLiteral([component]));
-          break;
-        // String
-        case UnlinkedExprOperation.pushString:
-          String value = _uc.strings[stringPtr++];
-          _push(AstTestFactory.string2(value));
-          break;
-        case UnlinkedExprOperation.concatenate:
-          int count = _uc.ints[intPtr++];
-          List<InterpolationElement> elements = <InterpolationElement>[];
-          for (int i = 0; i < count; i++) {
-            Expression expr = _pop();
-            InterpolationElement element = _newInterpolationElement(expr);
-            elements.insert(0, element);
-          }
-          _push(AstTestFactory.string(elements));
-          break;
-        // binary
-        case UnlinkedExprOperation.equal:
-          _pushBinary(TokenType.EQ_EQ);
-          break;
-        case UnlinkedExprOperation.notEqual:
-          _pushBinary(TokenType.BANG_EQ);
-          break;
-        case UnlinkedExprOperation.and:
-          _pushBinary(TokenType.AMPERSAND_AMPERSAND);
-          break;
-        case UnlinkedExprOperation.or:
-          _pushBinary(TokenType.BAR_BAR);
-          break;
-        case UnlinkedExprOperation.bitXor:
-          _pushBinary(TokenType.CARET);
-          break;
-        case UnlinkedExprOperation.bitAnd:
-          _pushBinary(TokenType.AMPERSAND);
-          break;
-        case UnlinkedExprOperation.bitOr:
-          _pushBinary(TokenType.BAR);
-          break;
-        case UnlinkedExprOperation.bitShiftLeft:
-          _pushBinary(TokenType.LT_LT);
-          break;
-        case UnlinkedExprOperation.bitShiftRight:
-          _pushBinary(TokenType.GT_GT);
-          break;
-        case UnlinkedExprOperation.bitShiftRightLogical:
-          _pushBinary(TokenType.GT_GT_GT);
-          break;
-        case UnlinkedExprOperation.add:
-          _pushBinary(TokenType.PLUS);
-          break;
-        case UnlinkedExprOperation.subtract:
-          _pushBinary(TokenType.MINUS);
-          break;
-        case UnlinkedExprOperation.multiply:
-          _pushBinary(TokenType.STAR);
-          break;
-        case UnlinkedExprOperation.divide:
-          _pushBinary(TokenType.SLASH);
-          break;
-        case UnlinkedExprOperation.floorDivide:
-          _pushBinary(TokenType.TILDE_SLASH);
-          break;
-        case UnlinkedExprOperation.modulo:
-          _pushBinary(TokenType.PERCENT);
-          break;
-        case UnlinkedExprOperation.greater:
-          _pushBinary(TokenType.GT);
-          break;
-        case UnlinkedExprOperation.greaterEqual:
-          _pushBinary(TokenType.GT_EQ);
-          break;
-        case UnlinkedExprOperation.less:
-          _pushBinary(TokenType.LT);
-          break;
-        case UnlinkedExprOperation.lessEqual:
-          _pushBinary(TokenType.LT_EQ);
-          break;
-        // prefix
-        case UnlinkedExprOperation.complement:
-          _pushPrefix(TokenType.TILDE);
-          break;
-        case UnlinkedExprOperation.negate:
-          _pushPrefix(TokenType.MINUS);
-          break;
-        case UnlinkedExprOperation.not:
-          _pushPrefix(TokenType.BANG);
-          break;
-        // conditional
-        case UnlinkedExprOperation.conditional:
-          Expression elseExpr = _pop();
-          Expression thenExpr = _pop();
-          Expression condition = _pop();
-          _push(AstTestFactory.conditionalExpression(
-              condition, thenExpr, elseExpr));
-          break;
-        case UnlinkedExprOperation.invokeMethodRef:
-          _pushInvokeMethodRef();
-          break;
-        case UnlinkedExprOperation.invokeMethod:
-          List<Expression> arguments = _buildArguments();
-          TypeArgumentList typeArguments = _buildTypeArguments();
-          Expression target = _pop();
-          String name = _uc.strings[stringPtr++];
-          _push(AstTestFactory.methodInvocation3(
-              target, name, typeArguments, arguments));
-          break;
-        // containers
-        case UnlinkedExprOperation.makeUntypedList:
-          _pushList(null);
-          break;
-        case UnlinkedExprOperation.makeTypedList:
-          TypeAnnotation itemType = _newTypeName();
-          _pushList(
-              AstTestFactory.typeArgumentList(<TypeAnnotation>[itemType]));
-          break;
-        case UnlinkedExprOperation.makeUntypedSetOrMap:
-          _pushSetOrMap(null);
-          break;
-        case UnlinkedExprOperation.makeUntypedMap:
-          _pushMap(null);
-          break;
-        case UnlinkedExprOperation.makeTypedMap:
-          TypeAnnotation keyType = _newTypeName();
-          TypeAnnotation valueType = _newTypeName();
-          _pushMap(AstTestFactory.typeArgumentList(
-              <TypeAnnotation>[keyType, valueType]));
-          break;
-        case UnlinkedExprOperation.makeMapLiteralEntry:
-          _pushMapLiteralEntry();
-          break;
-        case UnlinkedExprOperation.makeTypedMap2:
-          TypeAnnotation keyType = _newTypeName();
-          TypeAnnotation valueType = _newTypeName();
-          _pushSetOrMap(AstTestFactory.typeArgumentList(
-              <TypeAnnotation>[keyType, valueType]));
-          break;
-        case UnlinkedExprOperation.makeUntypedSet:
-          _pushSet(null);
-          break;
-        case UnlinkedExprOperation.makeTypedSet:
-          TypeAnnotation itemType = _newTypeName();
-          if (isSpreadOrControlFlowEnabled) {
-            _pushSetOrMap(
-                AstTestFactory.typeArgumentList(<TypeAnnotation>[itemType]));
-          } else {
-            _pushSet(
-                AstTestFactory.typeArgumentList(<TypeAnnotation>[itemType]));
-          }
-          break;
-        case UnlinkedExprOperation.pushReference:
-          _pushReference();
-          break;
-        case UnlinkedExprOperation.extractProperty:
-          _pushExtractProperty();
-          break;
-        case UnlinkedExprOperation.invokeConstructor:
-          _pushInstanceCreation();
-          break;
-        case UnlinkedExprOperation.pushParameter:
-          String name = _uc.strings[stringPtr++];
-          SimpleIdentifier identifier = AstTestFactory.identifier3(name);
-          identifier.staticElement = variablesInScope[name];
-          _push(identifier);
-          break;
-        case UnlinkedExprOperation.ifNull:
-          _pushBinary(TokenType.QUESTION_QUESTION);
-          break;
-        case UnlinkedExprOperation.await:
-          Expression expression = _pop();
-          _push(AstTestFactory.awaitExpression(expression));
-          break;
-        case UnlinkedExprOperation.pushLocalFunctionReference:
-          _pushLocalFunctionReference();
-          break;
-        case UnlinkedExprOperation.assignToRef:
-          var ref = _createReference();
-          _push(_createAssignment(ref));
-          break;
-        case UnlinkedExprOperation.typeCast:
-          Expression expression = _pop();
-          TypeAnnotation type = _newTypeName();
-          _push(AstTestFactory.asExpression(expression, type));
-          break;
-        case UnlinkedExprOperation.typeCheck:
-          Expression expression = _pop();
-          TypeAnnotation type = _newTypeName();
-          _push(AstTestFactory.isExpression(expression, false, type));
-          break;
-        case UnlinkedExprOperation.throwException:
-          Expression expression = _pop();
-          _push(AstTestFactory.throwExpression2(expression));
-          break;
-        case UnlinkedExprOperation.assignToProperty:
-          Expression target = _pop();
-          String name = _uc.strings[stringPtr++];
-          SimpleIdentifier propertyNode = AstTestFactory.identifier3(name);
-          PropertyAccess propertyAccess =
-              AstTestFactory.propertyAccess(target, propertyNode);
-          _push(_createAssignment(propertyAccess));
-          break;
-        case UnlinkedExprOperation.assignToIndex:
-          Expression index = _pop();
-          Expression target = _pop();
-          IndexExpression indexExpression =
-              AstTestFactory.indexExpression(target, index);
-          _push(_createAssignment(indexExpression));
-          break;
-        case UnlinkedExprOperation.extractIndex:
-          Expression index = _pop();
-          Expression target = _pop();
-          _push(AstTestFactory.indexExpression(target, index));
-          break;
-        case UnlinkedExprOperation.pushSuper:
-          _push(AstTestFactory.superExpression());
-          break;
-        case UnlinkedExprOperation.pushThis:
-          _push(AstTestFactory.thisExpression());
-          break;
-        case UnlinkedExprOperation.spreadElement:
-          _pushSpread(TokenType.PERIOD_PERIOD_PERIOD);
-          break;
-        case UnlinkedExprOperation.nullAwareSpreadElement:
-          _pushSpread(TokenType.PERIOD_PERIOD_PERIOD_QUESTION);
-          break;
-        case UnlinkedExprOperation.ifElement:
-          _pushIfElement(false);
-          break;
-        case UnlinkedExprOperation.ifElseElement:
-          _pushIfElement(true);
-          break;
-        case UnlinkedExprOperation.forParts:
-          _pushForParts();
-          break;
-        case UnlinkedExprOperation.forElement:
-          _pushForElement(false);
-          break;
-        case UnlinkedExprOperation.forElementWithAwait:
-          _pushForElement(true);
-          break;
-        case UnlinkedExprOperation.pushEmptyExpression:
-          _push(null);
-          break;
-        case UnlinkedExprOperation.variableDeclarationStart:
-          _variableDeclarationStart();
-          break;
-        case UnlinkedExprOperation.variableDeclaration:
-          _variableDeclaration();
-          break;
-        case UnlinkedExprOperation.forInitializerDeclarationsUntyped:
-          _forInitializerDeclarations(false);
-          break;
-        case UnlinkedExprOperation.forInitializerDeclarationsTyped:
-          _forInitializerDeclarations(true);
-          break;
-        case UnlinkedExprOperation.assignToParameter:
-          String name = _uc.strings[stringPtr++];
-          SimpleIdentifier identifier = AstTestFactory.identifier3(name);
-          identifier.staticElement = variablesInScope[name];
-          _push(_createAssignment(identifier));
-          break;
-        case UnlinkedExprOperation.forEachPartsWithIdentifier:
-          _forEachPartsWithIdentifier();
-          break;
-        case UnlinkedExprOperation.forEachPartsWithUntypedDeclaration:
-          _forEachPartsWithDeclaration(false);
-          break;
-        case UnlinkedExprOperation.forEachPartsWithTypedDeclaration:
-          _forEachPartsWithDeclaration(true);
-          break;
-        case UnlinkedExprOperation.cascadeSectionBegin:
-        case UnlinkedExprOperation.cascadeSectionEnd:
-        case UnlinkedExprOperation.pushLocalFunctionReference:
-        case UnlinkedExprOperation.pushError:
-        case UnlinkedExprOperation.pushTypedAbstract:
-        case UnlinkedExprOperation.pushUntypedAbstract:
-          throw new UnimplementedError(
-              'Unexpected $operation in a constant expression.');
-      }
-    }
-    assert(startingVariableCount == variablesInScope.count);
-    return stack.single;
-  }
-
-  List<Expression> _buildArguments() {
-    List<Expression> arguments;
-    {
-      int numNamedArgs = _uc.ints[intPtr++];
-      int numPositionalArgs = _uc.ints[intPtr++];
-      int numArgs = numNamedArgs + numPositionalArgs;
-      arguments = _removeTopExpressions(numArgs);
-      // add names to the named arguments
-      for (int i = 0; i < numNamedArgs; i++) {
-        String name = _uc.strings[stringPtr++];
-        int index = numPositionalArgs + i;
-        arguments[index] =
-            AstTestFactory.namedExpression2(name, arguments[index]);
-      }
-    }
-    return arguments;
-  }
-
-  /// Given the sequence of identifiers in [node], and the [classElement] or
-  /// [constructorElement] to which this sequence resolves, build the
-  /// [InstanceCreationExpression].
-  InstanceCreationExpression _buildCreation(
-    Expression node,
-    TypeArgumentList typeArguments,
-    ArgumentList argumentList, {
-    ClassElement classElement,
-    ConstructorElement constructorElement,
-  }) {
-    InstanceCreationExpression composeCreation(
-        DartType type,
-        ConstructorName constructorName,
-        ConstructorElement constructorElement,
-        ArgumentList argumentList) {
-      TypeName typeName = constructorName.type;
-      typeName.type = type;
-
-      constructorName.name?.staticElement = constructorElement;
-
-      var creation = astFactory.instanceCreationExpression(
-          _uc.isValidConst
-              ? TokenFactory.tokenFromKeyword(Keyword.CONST)
-              : TokenFactory.tokenFromKeyword(Keyword.NEW),
-          constructorName,
-          argumentList);
-
-      creation.staticElement = constructorElement;
-      creation.staticType = type;
-      return creation;
-    }
-
-    classElement ??= constructorElement?.enclosingElement;
-    var type = AstRewriteVisitor.getType(
-        resynthesizer.typeSystem, classElement, typeArguments);
-
-    // C()
-    if (node is SimpleIdentifier && classElement != null) {
-      constructorElement = type.lookUpConstructor('', resynthesizer.library);
-      node.staticType = type;
-      return composeCreation(
-        type,
-        astFactory.constructorName(
-          astFactory.typeName(node, typeArguments),
-          null,
-          null,
-        ),
-        constructorElement,
-        argumentList,
-      );
-    }
-    if (node is PrefixedIdentifier) {
-      // C.n()
-      if (constructorElement != null) {
-        constructorElement =
-            type.lookUpConstructor(node.identifier.name, resynthesizer.library);
-        node.prefix.staticType = type;
-        return composeCreation(
-          type,
-          astFactory.constructorName(
-            astFactory.typeName(node.prefix, typeArguments),
-            TokenFactory.tokenFromType(TokenType.PERIOD),
-            node.identifier,
-          ),
-          constructorElement,
-          argumentList,
-        );
-      }
-      // p.C()
-      if (classElement != null) {
-        constructorElement = type.lookUpConstructor('', resynthesizer.library);
-        node.identifier.staticType = type;
-        return composeCreation(
-          type,
-          astFactory.constructorName(
-            astFactory.typeName(node.identifier, typeArguments),
-            null,
-            null,
-          ),
-          constructorElement,
-          argumentList,
-        );
-      }
-    }
-    // p.C.n()
-    if (node is PropertyAccess && constructorElement != null) {
-      constructorElement =
-          type.lookUpConstructor(node.propertyName.name, resynthesizer.library);
-      var typeIdentifier = (node.target as PrefixedIdentifier).identifier;
-      typeIdentifier.staticType = type;
-      return composeCreation(
-        type,
-        astFactory.constructorName(
-          astFactory.typeName(typeIdentifier, typeArguments),
-          TokenFactory.tokenFromType(TokenType.PERIOD),
-          node.propertyName,
-        ),
-        constructorElement,
-        argumentList,
-      );
-    }
-
-    throw new UnimplementedError('For ${node?.runtimeType}: $node; '
-        'class: $classElement;  constructor: $constructorElement');
-  }
-
-  /**
-   * Build the identifier sequence (a single or prefixed identifier, or a
-   * property access) corresponding to the given reference [info].
-   */
-  Expression _buildIdentifierSequence(ReferenceInfo info) {
-    Expression enclosing;
-    if (info.enclosing != null) {
-      enclosing = _buildIdentifierSequence(info.enclosing);
-    }
-    Element element = info.element;
-    if (element == null && info.name == 'length') {
-      element = _getStringLengthElement();
-    }
-    if (enclosing == null) {
-      return AstTestFactory.identifier3(info.name)..staticElement = element;
-    }
-    if (enclosing is SimpleIdentifier) {
-      SimpleIdentifier identifier = AstTestFactory.identifier3(info.name)
-        ..staticElement = element;
-      return AstTestFactory.identifier(enclosing, identifier);
-    }
-    SimpleIdentifier property = AstTestFactory.identifier3(info.name)
-      ..staticElement = element;
-    return AstTestFactory.propertyAccess(enclosing, property);
-  }
-
-  TypeArgumentList _buildTypeArguments() {
-    int numTypeArguments = _uc.ints[intPtr++];
-    if (numTypeArguments == 0) {
-      return null;
-    }
-
-    var typeNames = new List<TypeAnnotation>(numTypeArguments);
-    for (int i = 0; i < numTypeArguments; i++) {
-      typeNames[i] = _newTypeName();
-    }
-    return AstTestFactory.typeArgumentList(typeNames);
-  }
-
-  TypeAnnotation _buildTypeAst(DartType type) {
-    List<TypeAnnotation> argumentNodes;
-    if (type is ParameterizedType) {
-      if (!resynthesizer.doesTypeHaveImplicitArguments(type)) {
-        List<DartType> typeArguments = type.typeArguments;
-        argumentNodes = typeArguments.every((a) => a.isDynamic)
-            ? null
-            : typeArguments.map(_buildTypeAst).toList();
-      }
-    }
-    TypeName node = AstTestFactory.typeName4(type.name, argumentNodes);
-    node.type = type;
-    (node.name as SimpleIdentifier).staticElement = type.element;
-    return node;
-  }
-
-  Expression _createAssignment(Expression lhs) {
-    Expression binary(TokenType tokenType) {
-      return AstTestFactory.assignmentExpression(lhs, tokenType, _pop());
-    }
-
-    Expression prefix(TokenType tokenType) {
-      return AstTestFactory.prefixExpression(tokenType, lhs);
-    }
-
-    Expression postfix(TokenType tokenType) {
-      return AstTestFactory.postfixExpression(lhs, tokenType);
-    }
-
-    switch (_uc.assignmentOperators[assignmentOperatorPtr++]) {
-      case UnlinkedExprAssignOperator.assign:
-        return binary(TokenType.EQ);
-      case UnlinkedExprAssignOperator.ifNull:
-        return binary(TokenType.QUESTION_QUESTION_EQ);
-      case UnlinkedExprAssignOperator.multiply:
-        return binary(TokenType.STAR_EQ);
-      case UnlinkedExprAssignOperator.divide:
-        return binary(TokenType.SLASH_EQ);
-      case UnlinkedExprAssignOperator.floorDivide:
-        return binary(TokenType.TILDE_SLASH_EQ);
-      case UnlinkedExprAssignOperator.modulo:
-        return binary(TokenType.PERCENT_EQ);
-      case UnlinkedExprAssignOperator.plus:
-        return binary(TokenType.PLUS_EQ);
-      case UnlinkedExprAssignOperator.minus:
-        return binary(TokenType.MINUS_EQ);
-      case UnlinkedExprAssignOperator.shiftLeft:
-        return binary(TokenType.LT_LT_EQ);
-      case UnlinkedExprAssignOperator.shiftRight:
-        return binary(TokenType.GT_GT_EQ);
-      case UnlinkedExprAssignOperator.bitAnd:
-        return binary(TokenType.AMPERSAND_EQ);
-      case UnlinkedExprAssignOperator.bitXor:
-        return binary(TokenType.CARET_EQ);
-      case UnlinkedExprAssignOperator.bitOr:
-        return binary(TokenType.BAR_EQ);
-      case UnlinkedExprAssignOperator.prefixIncrement:
-        return prefix(TokenType.PLUS_PLUS);
-      case UnlinkedExprAssignOperator.prefixDecrement:
-        return prefix(TokenType.MINUS_MINUS);
-      case UnlinkedExprAssignOperator.postfixIncrement:
-        return postfix(TokenType.PLUS_PLUS);
-      case UnlinkedExprAssignOperator.postfixDecrement:
-        return postfix(TokenType.MINUS_MINUS);
-      default:
-        throw new UnimplementedError('Unexpected UnlinkedExprAssignOperator');
-    }
-  }
-
-  Expression _createReference() {
-    EntityRef ref = _uc.references[refPtr++];
-    if (ref.paramReference != 0) {
-      // This is a reference to a type parameter.  For type inference purposes
-      // we don't actually need to know which type parameter it's a reference
-      // to; we just need to know that it represents a type.  So map it to
-      // `Object`.
-      return AstTestFactory.identifier3('Object')
-        ..staticElement = resynthesizer.typeProvider.objectType.element;
-    }
-    ReferenceInfo info = resynthesizer.getReferenceInfo(ref.reference);
-    return _buildIdentifierSequence(info);
-  }
-
-  void _forEachPartsWithDeclaration(bool hasType) {
-    var iterable = _pop();
-    var name = _uc.strings[stringPtr++];
-    var element = LocalVariableElementImpl(name, -1);
-    var keyword = hasType ? null : Keyword.VAR;
-    var type = hasType ? _newTypeName() : null;
-    var loopVariable = AstTestFactory.declaredIdentifier2(keyword, type, name);
-    loopVariable.identifier.staticElement = element;
-    if (hasType) {
-      element.type = type.type;
-    }
-    _pushNode(
-        AstTestFactory.forEachPartsWithDeclaration(loopVariable, iterable));
-    variablesInScope.push(element);
-  }
-
-  void _forEachPartsWithIdentifier() {
-    var iterable = _pop();
-    SimpleIdentifier identifier = _pop();
-    _pushNode(AstTestFactory.forEachPartsWithIdentifier(identifier, iterable));
-  }
-
-  void _forInitializerDeclarations(bool hasType) {
-    var count = _uc.ints[intPtr++];
-    var variables = List<VariableDeclaration>.filled(count, null);
-    for (int i = 0; i < count; i++) {
-      variables[count - 1 - i] = _popNode();
-    }
-    var type = hasType ? _newTypeName() : null;
-    var keyword = hasType ? null : Keyword.VAR;
-    _pushNode(AstTestFactory.variableDeclarationList(keyword, type, variables));
-  }
-
-  PropertyAccessorElement _getStringLengthElement() =>
-      resynthesizer.typeProvider.stringType.getGetter('length');
-
-  FormalParameter _makeParameter(ParameterElement param) {
-    SimpleFormalParameterImpl simpleParam =
-        AstTestFactory.simpleFormalParameter(null, param.name);
-    simpleParam.identifier.staticElement = param;
-    simpleParam.declaredElement = param;
-    var unlinkedParam = (param as ParameterElementImpl).unlinkedParam;
-    if (unlinkedParam.kind == UnlinkedParamKind.optionalPositional) {
-      return AstTestFactory.positionalFormalParameter(simpleParam, null);
-    } else if (unlinkedParam.kind == UnlinkedParamKind.requiredNamed ||
-        unlinkedParam.kind == UnlinkedParamKind.optionalNamed) {
-      return AstTestFactory.namedFormalParameter(simpleParam, null);
-    } else {
-      return simpleParam;
-    }
-  }
-
-  InterpolationElement _newInterpolationElement(Expression expr) {
-    if (expr is SimpleStringLiteral) {
-      return astFactory.interpolationString(expr.literal, expr.value);
-    } else {
-      return astFactory.interpolationExpression(
-          TokenFactory.tokenFromType(TokenType.STRING_INTERPOLATION_EXPRESSION),
-          expr,
-          TokenFactory.tokenFromType(TokenType.CLOSE_CURLY_BRACKET));
-    }
-  }
-
-  /**
-   * Convert the next reference to the [DartType] and return the AST
-   * corresponding to this type.
-   */
-  TypeAnnotation _newTypeName() {
-    EntityRef typeRef = _uc.references[refPtr++];
-    DartType type = resynthesizer.buildType(context, typeRef);
-    return _buildTypeAst(type);
-  }
-
-  Expression _pop() => stack.removeLast() as Expression;
-
-  CollectionElement _popCollectionElement() =>
-      stack.removeLast() as CollectionElement;
-
-  AstNode _popNode() => stack.removeLast();
-
-  void _push(Expression expr) {
-    stack.add(expr);
-  }
-
-  void _pushBinary(TokenType operator) {
-    Expression right = _pop();
-    Expression left = _pop();
-    _push(AstTestFactory.binaryExpression(left, operator, right));
-  }
-
-  void _pushCollectionElement(CollectionElement collectionElement) {
-    stack.add(collectionElement);
-  }
-
-  void _pushExtractProperty() {
-    Expression target = _pop();
-    String name = _uc.strings[stringPtr++];
-    SimpleIdentifier propertyNode = AstTestFactory.identifier3(name);
-    // Only String.length property access can be potentially resolved.
-    if (name == 'length') {
-      propertyNode.staticElement = _getStringLengthElement();
-    }
-    _push(AstTestFactory.propertyAccess(target, propertyNode));
-  }
-
-  void _pushForElement(bool hasAwait) {
-    var body = _popCollectionElement();
-    var forLoopParts = _popNode() as ForLoopParts;
-    if (forLoopParts is ForPartsWithDeclarations) {
-      variablesInScope.pop(forLoopParts.variables.variables.length);
-    } else if (forLoopParts is ForEachPartsWithDeclaration) {
-      variablesInScope.pop(1);
-    }
-    _pushCollectionElement(
-        AstTestFactory.forElement(forLoopParts, body, hasAwait: hasAwait));
-  }
-
-  void _pushForParts() {
-    var updaterCount = _uc.ints[intPtr++];
-    var updaters = <Expression>[];
-    for (int i = 0; i < updaterCount; i++) {
-      updaters.insert(0, _pop());
-    }
-    Expression condition = _pop();
-    AstNode initialization = _popNode();
-    if (initialization is Expression || initialization == null) {
-      _pushNode(AstTestFactory.forPartsWithExpression(
-          initialization, condition, updaters));
-    } else if (initialization is VariableDeclarationList) {
-      _pushNode(AstTestFactory.forPartsWithDeclarations(
-          initialization, condition, updaters));
-    } else {
-      throw StateError('Unrecognized for parts');
-    }
-  }
-
-  void _pushIfElement(bool hasElse) {
-    CollectionElement elseElement = hasElse ? _popCollectionElement() : null;
-    CollectionElement thenElement = _popCollectionElement();
-    Expression condition = _pop();
-    _pushCollectionElement(
-        AstTestFactory.ifElement(condition, thenElement, elseElement));
-  }
-
-  void _pushInstanceCreation() {
-    EntityRef ref = _uc.references[refPtr++];
-    ReferenceInfo info = resynthesizer.getReferenceInfo(ref.reference);
-    // prepare ConstructorElement
-    TypeName typeNode;
-    String constructorName;
-    ConstructorElement constructorElement;
-    if (info.element != null) {
-      if (info.element is ConstructorElement) {
-        constructorName = info.name;
-      } else if (info.element is ClassElement) {
-        constructorName = null;
-      } else {
-        // Unexpected element, consider it unresolved.
-        _buildArguments();
-        var identifier = AstTestFactory.identifier3('__unresolved__')
-          ..staticType = resynthesizer.typeProvider.dynamicType;
-        _push(identifier);
-        return;
-      }
-      InterfaceType definingType = resynthesizer.createConstructorDefiningType(
-          context, info, ref.typeArguments);
-      constructorElement =
-          resynthesizer.getConstructorForInfo(definingType, info);
-      typeNode = _buildTypeAst(definingType);
-    } else {
-      if (info.enclosing != null) {
-        if (info.enclosing.enclosing != null) {
-          PrefixedIdentifier typeName = AstTestFactory.identifier5(
-              info.enclosing.enclosing.name, info.enclosing.name);
-          typeName.prefix.staticElement = info.enclosing.enclosing.element;
-          typeName.identifier.staticElement = info.enclosing.element;
-          typeName.identifier.staticType = info.enclosing.type;
-          typeNode = AstTestFactory.typeName3(typeName);
-          typeNode.type = info.enclosing.type;
-          constructorName = info.name;
-        } else if (info.enclosing.element != null) {
-          SimpleIdentifier typeName =
-              AstTestFactory.identifier3(info.enclosing.name);
-          typeName.staticElement = info.enclosing.element;
-          typeName.staticType = info.enclosing.type;
-          typeNode = AstTestFactory.typeName3(typeName);
-          typeNode.type = info.enclosing.type;
-          constructorName = info.name;
-        } else {
-          typeNode = AstTestFactory.typeName3(
-              AstTestFactory.identifier5(info.enclosing.name, info.name));
-          constructorName = null;
-        }
-      } else {
-        typeNode = AstTestFactory.typeName4(info.name);
-      }
-    }
-    // prepare arguments
-    List<Expression> arguments = _buildArguments();
-    // create ConstructorName
-    ConstructorName constructorNode;
-    if (constructorName != null) {
-      constructorNode =
-          AstTestFactory.constructorName(typeNode, constructorName);
-      constructorNode.name.staticElement = constructorElement;
-    } else {
-      constructorNode = AstTestFactory.constructorName(typeNode, null);
-    }
-    constructorNode.staticElement = constructorElement;
-    // create InstanceCreationExpression
-    InstanceCreationExpression instanceCreation =
-        AstTestFactory.instanceCreationExpression(
-            requireValidConst ? Keyword.CONST : Keyword.NEW,
-            constructorNode,
-            arguments);
-    instanceCreation.staticElement = constructorElement;
-    _push(instanceCreation);
-  }
-
-  void _pushInvokeMethodRef() {
-    List<Expression> arguments = _buildArguments();
-    EntityRef ref = _uc.references[refPtr++];
-    ReferenceInfo info = resynthesizer.getReferenceInfo(ref.reference);
-    Expression node = _buildIdentifierSequence(info);
-    TypeArgumentList typeArguments = _buildTypeArguments();
-    var period = TokenFactory.tokenFromType(TokenType.PERIOD);
-    var argumentList = AstTestFactory.argumentList(arguments);
-
-    // Check for optional new/const.
-    if (info.element is ClassElement) {
-      _push(_buildCreation(node, typeArguments, argumentList,
-          classElement: info.element));
-      return;
-    }
-    if (info.element is ConstructorElement) {
-      _push(_buildCreation(node, typeArguments, argumentList,
-          constructorElement: info.element));
-      return;
-    }
-
-    if (node is SimpleIdentifier) {
-      _push(astFactory.methodInvocation(
-          null, period, node, typeArguments, argumentList));
-    } else if (node is PropertyAccess) {
-      _push(astFactory.methodInvocation(
-          node.target, period, node.propertyName, typeArguments, argumentList));
-    } else if (node is PrefixedIdentifier) {
-      _push(astFactory.methodInvocation(
-          node.prefix, period, node.identifier, typeArguments, argumentList));
-    } else {
-      throw new UnimplementedError('For ${node?.runtimeType}: $node');
-    }
-  }
-
-  void _pushList(TypeArgumentList typeArguments) {
-    int count = _uc.ints[intPtr++];
-    List<CollectionElement> elements =
-        isSpreadOrControlFlowEnabled ? <CollectionElement>[] : <Expression>[];
-    for (int i = 0; i < count; i++) {
-      elements.insert(0, _popCollectionElement());
-    }
-    var typeArg = typeArguments == null
-        ? resynthesizer.typeProvider.dynamicType
-        : typeArguments.arguments[0].type;
-    var staticType = resynthesizer.typeProvider.listType2(typeArg);
-    _push(AstTestFactory.listLiteral2(Keyword.CONST, typeArguments, elements)
-      ..staticType = staticType);
-  }
-
-  void _pushLocalFunctionReference() {
-    int popCount = _uc.ints[intPtr++];
-    // Note: nonzero popCount is no longer used.
-    assert(popCount == 0);
-    int functionIndex = _uc.ints[intPtr++];
-    var localFunction = localFunctions[functionIndex];
-    var functionElement =
-        new FunctionElementImpl.forSerialized(localFunction, context);
-    for (ParameterElementImpl parameter in functionElement.parameters) {
-      variablesInScope.push(parameter);
-      if (parameter.unlinkedParam.type == null) {
-        // Store a type of `dynamic` for the parameter; this prevents
-        // resynthesis from trying to read a type out of the summary (which
-        // wouldn't work anyway, since nested functions don't have their
-        // parameter types stored in the summary anyhow).
-        parameter.type = resynthesizer.typeProvider.dynamicType;
-      }
-    }
-    var parameters = functionElement.parameters.map(_makeParameter).toList();
-    var asyncKeyword = localFunction.isAsynchronous
-        ? TokenFactory.tokenFromKeyword(Keyword.ASYNC)
-        : null;
-    FunctionBody functionBody;
-    if (localFunction.bodyExpr == null) {
-      // Most likely the original source code contained a block function body
-      // here.  Block function bodies aren't supported by the summary mechanism.
-      // But they are tolerated when their presence doesn't affect inferred
-      // types.
-      functionBody = AstTestFactory.blockFunctionBody(AstTestFactory.block());
-    } else {
-      var bodyExpr = new ExprBuilder(
-              resynthesizer, functionElement, localFunction.bodyExpr,
-              requireValidConst: requireValidConst,
-              variablesInScope: variablesInScope,
-              localFunctions: localFunction.localFunctions)
-          .build();
-      functionBody = astFactory.expressionFunctionBody(asyncKeyword,
-          TokenFactory.tokenFromType(TokenType.FUNCTION), bodyExpr, null);
-    }
-    variablesInScope.pop(functionElement.parameters.length);
-    FunctionExpressionImpl functionExpression = astFactory.functionExpression(
-        null, AstTestFactory.formalParameterList(parameters), functionBody);
-    functionExpression.declaredElement = functionElement;
-    _push(functionExpression);
-  }
-
-  void _pushMap(TypeArgumentList typeArguments) {
-    int count = _uc.ints[intPtr++];
-    List<MapLiteralEntry> entries = <MapLiteralEntry>[];
-    for (int i = 0; i < count; i++) {
-      Expression value = _pop();
-      Expression key = _pop();
-      entries.insert(0, AstTestFactory.mapLiteralEntry2(key, value));
-    }
-    var keyType = typeArguments == null
-        ? resynthesizer.typeProvider.dynamicType
-        : typeArguments.arguments[0].type;
-    var valueType = typeArguments == null
-        ? resynthesizer.typeProvider.dynamicType
-        : typeArguments.arguments[1].type;
-    var staticType = resynthesizer.typeProvider.mapType2(keyType, valueType);
-    SetOrMapLiteralImpl literal =
-        AstTestFactory.setOrMapLiteral(Keyword.CONST, typeArguments, entries);
-    literal.becomeMap();
-    literal.staticType = staticType;
-    _push(literal);
-  }
-
-  void _pushMapLiteralEntry() {
-    Expression value = _pop();
-    Expression key = _pop();
-    _pushCollectionElement(AstTestFactory.mapLiteralEntry2(key, value));
-  }
-
-  void _pushNode(AstNode node) {
-    stack.add(node);
-  }
-
-  void _pushPrefix(TokenType operator) {
-    Expression operand = _pop();
-    _push(AstTestFactory.prefixExpression(operator, operand));
-  }
-
-  void _pushReference() {
-    _push(_createReference());
-  }
-
-  void _pushSet(TypeArgumentList typeArguments) {
-    int count = _uc.ints[intPtr++];
-    List<Expression> elements = <Expression>[];
-    for (int i = 0; i < count; i++) {
-      elements.insert(0, _pop());
-    }
-    SetOrMapLiteralImpl literal =
-        AstTestFactory.setOrMapLiteral(Keyword.CONST, typeArguments, elements);
-    literal.becomeSet();
-    _push(literal);
-  }
-
-  void _pushSetOrMap(TypeArgumentList typeArguments) {
-    int count = _uc.ints[intPtr++];
-    List<CollectionElement> elements = <CollectionElement>[];
-    for (int i = 0; i < count; i++) {
-      elements.insert(0, _popCollectionElement());
-    }
-
-    bool isMap = true; // assume Map unless can prove otherwise
-    DartType staticType;
-    if (typeArguments != null) {
-      if (typeArguments.arguments.length == 2) {
-        var keyType = typeArguments.arguments[0].type;
-        var valueType = typeArguments.arguments[1].type;
-        staticType = resynthesizer.typeProvider.mapType2(keyType, valueType);
-      } else if (typeArguments.arguments.length == 1) {
-        isMap = false;
-        var valueType = typeArguments == null
-            ? resynthesizer.typeProvider.dynamicType
-            : typeArguments.arguments[0].type;
-        staticType = resynthesizer.typeProvider.setType2(valueType);
-      }
-    } else {
-      for (var i = 0; i < elements.length; ++i) {
-        var element = elements[i];
-        if (element is Expression) {
-          isMap = false;
-        }
-      }
-    }
-
-    SetOrMapLiteral setOrMapLiteral = astFactory.setOrMapLiteral(
-      constKeyword: TokenFactory.tokenFromKeyword(Keyword.CONST),
-      typeArguments: typeArguments,
-      leftBracket: TokenFactory.tokenFromType(TokenType.OPEN_CURLY_BRACKET),
-      elements: elements,
-      rightBracket: TokenFactory.tokenFromType(TokenType.CLOSE_CURLY_BRACKET),
-    );
-    if (becomeSetOrMap) {
-      if (isMap) {
-        (setOrMapLiteral as SetOrMapLiteralImpl).becomeMap();
-      } else {
-        (setOrMapLiteral as SetOrMapLiteralImpl).becomeSet();
-      }
-    }
-    _push(setOrMapLiteral..staticType = staticType);
-  }
-
-  void _pushSpread(TokenType operator) {
-    Expression operand = _pop();
-    _pushCollectionElement(AstTestFactory.spreadElement(operator, operand));
-  }
-
-  List<Expression> _removeTopExpressions(int count) {
-    int start = stack.length - count;
-    int end = stack.length;
-    List<Expression> items = List<Expression>.from(stack.getRange(start, end));
-    stack.removeRange(start, end);
-    return items;
-  }
-
-  void _variableDeclaration() {
-    var index = _uc.ints[intPtr++];
-    var element = variablesInScope.recent(index);
-    var initializer = _pop();
-    var variableDeclaration =
-        AstTestFactory.variableDeclaration2(element.name, initializer);
-    variableDeclaration.name.staticElement = element;
-    _pushNode(variableDeclaration);
-  }
-
-  void _variableDeclarationStart() {
-    var name = _uc.strings[stringPtr++];
-    variablesInScope.push(LocalVariableElementImpl(name, -1));
-  }
-
-  /// Figures out the default value of [parametersInScope] based on [context].
-  ///
-  /// If [context] is (or contains) a constructor, then its parameters are used.
-  /// Otherwise, no parameters are considered to be in scope.
-  static _VariablesInScope _parametersInScope(Element context) {
-    var result = _VariablesInScope();
-    for (Element e = context; e != null; e = e.enclosingElement) {
-      if (e is ConstructorElement) {
-        for (var parameter in e.parameters) {
-          result.push(parameter);
-        }
-        return result;
-      }
-    }
-    return result;
-  }
-}
-
-/// Tracks the set of variables that are in scope while resynthesizing an
-/// expression from a summary.
-class _VariablesInScope {
-  final _variableElements = <VariableElement>[];
-
-  /// Returns the number of variables that have been pushed but not popped.
-  int get count => _variableElements.length;
-
-  /// Looks up the variable with the given [name].  Returns `null` if no
-  /// variable is found.
-  VariableElement operator [](String name) {
-    for (int i = _variableElements.length - 1; i >= 0; i--) {
-      if (_variableElements[i].name == name) return _variableElements[i];
-    }
-    return null;
-  }
-
-  /// Un-does the effect of the last [count] calls to `push`.
-  void pop(int count) {
-    _variableElements.length -= count;
-  }
-
-  /// Stores a new declaration based on the given [variableElement].  The
-  /// declaration shadows any previous declaration with the same name.
-  void push(VariableElement variableElement) {
-    _variableElements.add(variableElement);
-  }
-
-  /// Retrieves the [index]th most recently pushed element (that hasn't been
-  /// popped).  [index] counts from zero.
-  VariableElement recent(int index) =>
-      _variableElements[_variableElements.length - 1 - index];
-}
diff --git a/pkg/analyzer/lib/src/summary/link.dart b/pkg/analyzer/lib/src/summary/link.dart
index db8ae22..d0bd245 100644
--- a/pkg/analyzer/lib/src/summary/link.dart
+++ b/pkg/analyzer/lib/src/summary/link.dart
@@ -2,2153 +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.
 
-/// This library is capable of producing linked summaries from unlinked
-/// ones (or prelinked ones).  It functions by building a miniature
-/// element model to represent the contents of the summaries, and then
-/// scanning the element model to gather linked information and adding
-/// it to the summary data structures.
-///
-/// The reason we use a miniature element model to do the linking
-/// (rather than resynthesizing the full element model from the
-/// summaries) is that it is expected that we will only need to
-/// traverse a small subset of the element properties in order to link.
-/// Resynthesizing only those properties that we need should save
-/// substantial CPU time.
-///
-/// The element model implements the same interfaces as the full
-/// element model, so we can re-use code elsewhere in the analysis
-/// engine to do the linking.  However, only a small subset of the
-/// methods and getters defined in the full element model are
-/// implemented here.  To avoid static warnings, each element model
-/// class contains an implementation of `noSuchMethod`.
-///
-/// The miniature element model follows the following design
-/// principles:
-///
-/// - With few exceptions, resynthesis is done incrementally on demand,
-///   so that we don't pay the cost of resynthesizing elements (or
-///   properties of elements) that aren't referenced from a part of the
-///   element model that is relevant to linking.
-///
-/// - Computation of values in the miniature element model is similar
-///   to the task model, but much lighter weight.  Instead of declaring
-///   tasks and their relationships using classes, each task is simply
-///   a method (frequently a getter) that computes a value.  Instead of
-///   using a general purpose cache, values are cached by the methods
-///   themselves in private fields (with `null` typically representing
-///   "not yet cached").
-///
-/// - No attempt is made to detect cyclic dependencies due to bugs in
-///   the analyzer.  This saves time because dependency evaluation
-///   doesn't have to be a separate step from evaluating a value; we
-///   can simply call the getter.
-///
-/// - However, for cases where cyclic dependencies may occur in the
-///   absence of analyzer bugs (e.g. because of errors in the code
-///   being analyzed, or cycles between top level and static variables
-///   undergoing type inference), we do precompute dependencies, and we
-///   use Tarjan's strongly connected components algorithm to detect
-///   cycles.
-///
-/// - As much as possible, bookkeeping data is pointed to directly by
-///   the element objects, rather than being stored in maps.
-///
-/// - Where possible, we favor method dispatch instead of "is" and "as"
-///   checks.  E.g. see [ReferenceableElementForLink.asConstructor].
-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';
-import 'package:analyzer/dart/ast/standard_ast_factory.dart';
-import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/dart/element/nullability_suffix.dart';
-import 'package:analyzer/dart/element/type.dart';
-import 'package:analyzer/error/listener.dart';
-import 'package:analyzer/src/dart/ast/ast.dart';
-import 'package:analyzer/src/dart/ast/utilities.dart';
-import 'package:analyzer/src/dart/constant/value.dart';
-import 'package:analyzer/src/dart/element/builder.dart';
-import 'package:analyzer/src/dart/element/element.dart';
-import 'package:analyzer/src/dart/element/inheritance_manager3.dart';
-import 'package:analyzer/src/dart/element/type.dart';
-import 'package:analyzer/src/dart/element/type_provider.dart';
-import 'package:analyzer/src/dart/resolver/ast_rewrite.dart';
-import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/java_engine.dart';
-import 'package:analyzer/src/generated/resolver.dart';
-import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/generated/utilities_dart.dart';
-import 'package:analyzer/src/summary/expr_builder.dart';
-import 'package:analyzer/src/summary/format.dart';
-import 'package:analyzer/src/summary/idl.dart';
-import 'package:analyzer/src/summary/package_bundle_reader.dart';
-import 'package:analyzer/src/summary/prelink.dart';
-import 'package:analyzer/src/summary/resynthesize.dart';
-import 'package:analyzer/src/task/strong_mode.dart';
-import 'package:meta/meta.dart';
-
-final _typesWithImplicitArguments = new Expando();
-
-bool isIncrementOrDecrement(UnlinkedExprAssignOperator operator) {
-  switch (operator) {
-    case UnlinkedExprAssignOperator.prefixDecrement:
-    case UnlinkedExprAssignOperator.prefixIncrement:
-    case UnlinkedExprAssignOperator.postfixDecrement:
-    case UnlinkedExprAssignOperator.postfixIncrement:
-      return true;
-    default:
-      return false;
-  }
-}
-
-/// Link together the build unit consisting of [libraryUris], using
-/// [getDependency] to fetch the [LinkedLibrary] objects from other
-/// build units, and [getUnit] to fetch the [UnlinkedUnit] objects from
-/// both this build unit and other build units.
-///
-/// The [strong] flag controls whether type inference is performed in strong
-/// mode or spec mode.  Note that in spec mode, the only types that are inferred
-/// are the types of initializing formals, which are inferred from the types of
-/// the corresponding fields.
-///
-/// If [getAst] is provided, it is used to obtain ASTs of source files in this
-/// build unit, and these ASTs are used for type inference.
-///
-/// A map is returned whose keys are the URIs of the libraries in this
-/// build unit, and whose values are the corresponding
-/// [LinkedLibraryBuilder]s.
-Map<String, LinkedLibraryBuilder> link(
-    Set<String> libraryUris,
-    GetDependencyCallback getDependency,
-    GetUnitCallback getUnit,
-    DeclaredVariables declaredVariables,
-    AnalysisOptions analysisOptions,
-    [GetAstCallback getAst]) {
-  Map<String, LinkedLibraryBuilder> linkedLibraries =
-      setupForLink(libraryUris, getUnit, declaredVariables);
-  _relink(linkedLibraries, getDependency, getUnit, getAst, analysisOptions);
-  return linkedLibraries;
-}
-
-/// Prepare to link together the build unit consisting of [libraryUris], using
-/// [getUnit] to fetch the [UnlinkedUnit] objects from both this build unit and
-/// other build units.
-///
-/// The libraries are prelinked, and a map is returned whose keys are the URIs
-/// of the libraries in this build unit, and whose values are the corresponding
-/// [LinkedLibraryBuilder]s.
-Map<String, LinkedLibraryBuilder> setupForLink(Set<String> libraryUris,
-    GetUnitCallback getUnit, DeclaredVariables declaredVariables) {
-  Map<String, LinkedLibraryBuilder> linkedLibraries =
-      <String, LinkedLibraryBuilder>{};
-  for (String absoluteUri in libraryUris) {
-    linkedLibraries[absoluteUri] = prelink(
-        absoluteUri,
-        getUnit(absoluteUri),
-        getUnit,
-        (String absoluteUri) => getUnit(absoluteUri)?.publicNamespace,
-        declaredVariables);
-  }
-  return linkedLibraries;
-}
-
-/// Collects all the type references appearing on the "right hand side" of a
-/// typedef.
-///
-/// The "right hand side" of a typedef is the type appearing after the "=" in a
-/// new style typedef declaration, or for an old style typedef declaration, the
-/// type that *would* appear after the "=" if it were converted to a new style
-/// typedef declaration.  This means that type parameter declarations and their
-/// bounds are not included.
-List<EntityRef> _collectTypedefRhsTypes(UnlinkedTypedef unlinkedTypedef) {
-  var types = <EntityRef>[];
-  void visitParams(List<UnlinkedParam> params) {
-    for (var param in params) {
-      var type = param.type;
-      if (type != null) {
-        types.add(type);
-      }
-      if (param.isFunctionTyped) {
-        visitParams(param.parameters);
-      }
-    }
-  }
-
-  var returnType = unlinkedTypedef.returnType;
-  if (returnType != null) {
-    types.add(returnType);
-  }
-  visitParams(unlinkedTypedef.parameters);
-  return types;
-}
-
-/// Create an [EntityRefBuilder] representing the given [type], in a form
-/// suitable for inclusion in [LinkedUnit.types].  [compilationUnit] is the
-/// compilation unit in which the type will be used.  If [slot] is provided, it
-/// is stored in [EntityRefBuilder.slot].
-EntityRefBuilder _createLinkedType(
-    DartType type,
-    CompilationUnitElementInBuildUnit compilationUnit,
-    TypeParameterSerializationContext typeParameterContext,
-    {int 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);
-    _storeTypeArguments(
-        type.typeArguments, result, compilationUnit, typeParameterContext);
-    return result;
-  } else if (type.isDynamic) {
-    result.reference = compilationUnit.addRawReference('dynamic');
-    return result;
-  } else if (type is VoidTypeImpl) {
-    result.reference = compilationUnit.addRawReference('void');
-    return result;
-  } else if (type is BottomTypeImpl) {
-    result.reference = compilationUnit.addRawReference('*bottom*');
-    return result;
-  } else if (type is TypeParameterType) {
-    TypeParameterElement element = type.element;
-    var deBruijnIndex = typeParameterContext?.computeDeBruijnIndex(element);
-    if (deBruijnIndex != null) {
-      result.paramReference = deBruijnIndex;
-    } else {
-      throw new StateError('The type parameter $type (in ${element?.location}) '
-          'is out of scope.');
-    }
-    return result;
-  } else if (type is FunctionType) {
-    Element element = type.element;
-    if (element is FunctionElementForLink_FunctionTypedParam) {
-      result.reference =
-          compilationUnit.addReference(element.typeParameterContext);
-      result.implicitFunctionTypeIndices = element.implicitFunctionTypeIndices;
-      _storeTypeArguments(
-          type.typeArguments, result, compilationUnit, typeParameterContext);
-      return result;
-    }
-    if (element is TopLevelFunctionElementForLink) {
-      result.reference = compilationUnit.addReference(element);
-      _storeTypeArguments(
-          type.typeArguments, result, compilationUnit, typeParameterContext);
-      return result;
-    }
-    if (element is MethodElementForLink) {
-      result.reference = compilationUnit.addReference(element);
-      _storeTypeArguments(
-          type.typeArguments, result, compilationUnit, typeParameterContext);
-      return result;
-    }
-    if (element is FunctionTypeAliasElementForLink) {
-      result.reference = compilationUnit.addReference(element);
-      _storeTypeArguments(
-          type.typeArguments, result, compilationUnit, typeParameterContext);
-      return result;
-    }
-    if (element is FunctionElement) {
-      // We store all function elements by value.  Synthetic elements, e.g.
-      // created for LUB, don't have actual elements; and local functions
-      // are not exposed from element model.
-      _storeFunctionElementByValue(result, element, compilationUnit);
-      // TODO(paulberry): do I need to store type arguments?
-      return result;
-    }
-    if (element is GenericFunctionTypeElementImpl) {
-      // Function types are their own type parameter context
-      typeParameterContext =
-          new InlineFunctionTypeParameterContext(element, typeParameterContext);
-      result.entityKind = EntityRefKind.genericFunctionType;
-      result.syntheticReturnType = _createLinkedType(
-          type.returnType, compilationUnit, typeParameterContext);
-      result.syntheticParams = type.parameters
-          .map((ParameterElement param) => _serializeSyntheticParam(
-              param, compilationUnit, typeParameterContext))
-          .toList();
-      _storeTypeArguments(
-          type.typeArguments, result, compilationUnit, typeParameterContext);
-      return result;
-    }
-    // TODO(paulberry): implement other cases.
-    throw new UnimplementedError('${element.runtimeType}');
-  }
-  // TODO(paulberry): implement other cases.
-  throw new UnimplementedError('${type.runtimeType}');
-}
-
-DartType _dynamicIfBottom(DartType type) {
-  if (type == null || type.isBottom) {
-    return DynamicTypeImpl.instance;
-  }
-  return type;
-}
-
-DartType _dynamicIfNull(DartType type) {
-  if (type == null || type.isBottom || type.isDartCoreNull) {
-    return DynamicTypeImpl.instance;
-  }
-  return type;
-}
-
-/// Given [libraries] (a map from URI to [LinkedLibraryBuilder]
-/// containing correct prelinked information), rebuild linked
-/// information, using [getDependency] to fetch the [LinkedLibrary]
-/// objects from other build units, and [getUnit] to fetch the
-/// [UnlinkedUnit] objects from both this build unit and other build
-/// units.
-///
-/// If a non-null [getAst] is provided, it is used to obtain ASTs of source
-/// files in this build unit, and these ASTs are used for type inference.
-///
-/// The [strong] flag controls whether type inference is performed in strong
-/// mode or spec mode.  Note that in spec mode, the only types that are inferred
-/// are the types of initializing formals, which are inferred from the types of
-/// the corresponding fields.
-void _relink(
-    Map<String, LinkedLibraryBuilder> libraries,
-    GetDependencyCallback getDependency,
-    GetUnitCallback getUnit,
-    GetAstCallback getAst,
-    AnalysisOptions analysisOptions) {
-  new Linker(libraries, getDependency, getUnit, getAst, analysisOptions).link();
-}
-
-/// Create an [UnlinkedParam] representing the given [parameter], which should
-/// be a parameter of a synthetic function type (e.g. one produced during type
-/// inference as a result of computing the least upper bound of two function
-/// types).
-UnlinkedParamBuilder _serializeSyntheticParam(
-    ParameterElement parameter,
-    CompilationUnitElementInBuildUnit compilationUnit,
-    TypeParameterSerializationContext typeParameterContext) {
-  UnlinkedParamBuilder b = new UnlinkedParamBuilder();
-  b.name = parameter.name;
-  if (parameter.isRequiredPositional) {
-    b.kind = UnlinkedParamKind.requiredPositional;
-  } else if (parameter.isRequiredNamed) {
-    b.kind = UnlinkedParamKind.requiredNamed;
-  } else if (parameter.isOptionalPositional) {
-    b.kind = UnlinkedParamKind.optionalPositional;
-  } else if (parameter.isOptionalNamed) {
-    b.kind = UnlinkedParamKind.optionalNamed;
-  }
-  DartType type = parameter.type;
-  if (!parameter.hasImplicitType) {
-    if (type is FunctionType && type.element.isSynthetic) {
-      b.isFunctionTyped = true;
-      b.type = _createLinkedType(
-          type.returnType, compilationUnit, typeParameterContext);
-      b.parameters = type.parameters
-          .map((parameter) => _serializeSyntheticParam(
-              parameter, compilationUnit, typeParameterContext))
-          .toList();
-    } else {
-      b.type = _createLinkedType(type, compilationUnit, typeParameterContext);
-    }
-  }
-  return b;
-}
-
-/// Create an [UnlinkedTypeParamBuilder] representing the given [typeParameter],
-/// which should be a type parameter of a synthetic function type (e.g. one
-/// produced during type inference as a result of computing the least upper
-/// bound of two function types).
-UnlinkedTypeParamBuilder _serializeSyntheticTypeParameter(
-    TypeParameterElement typeParameter,
-    CompilationUnitElementInBuildUnit compilationUnit,
-    TypeParameterSerializationContext typeParameterContext) {
-  TypeParameterElementImpl impl = typeParameter as TypeParameterElementImpl;
-  EntityRefBuilder boundBuilder = typeParameter.bound != null
-      ? _createLinkedType(
-          typeParameter.bound, compilationUnit, typeParameterContext)
-      : null;
-  CodeRangeBuilder codeRangeBuilder =
-      new CodeRangeBuilder(offset: impl.codeOffset, length: impl.codeLength);
-  return new UnlinkedTypeParamBuilder(
-      name: typeParameter.name,
-      nameOffset: typeParameter.nameOffset,
-      bound: boundBuilder,
-      codeRange: codeRangeBuilder);
-}
-
-/// Store the given function [element] into the [entity] by value.
-void _storeFunctionElementByValue(
-    EntityRefBuilder entity,
-    FunctionElement element,
-    CompilationUnitElementInBuildUnit compilationUnit) {
-  // Element is a local function, or a synthetic function element that was
-  // generated on the fly to represent a type that has no associated source
-  // code location. Store it as value.
-  if (element is FunctionElementImpl) {
-    entity.syntheticReturnType =
-        _createLinkedType(element.returnType, compilationUnit, element);
-    entity.entityKind = EntityRefKind.syntheticFunction;
-    entity.syntheticParams = element.parameters
-        .map((ParameterElement param) =>
-            _serializeSyntheticParam(param, compilationUnit, element))
-        .toList();
-    entity.typeParameters = element.typeParameters
-        .map((TypeParameterElement e) =>
-            _serializeSyntheticTypeParameter(e, compilationUnit, element))
-        .toList();
-  }
-}
-
-/// Store the given [typeArguments] in [encodedType], using [compilationUnit]
-/// and [typeParameterContext] to serialize them.
-void _storeTypeArguments(
-    List<DartType> typeArguments,
-    EntityRefBuilder encodedType,
-    CompilationUnitElementInBuildUnit compilationUnit,
-    TypeParameterSerializationContext typeParameterContext) {
-  int count = typeArguments.length;
-  List<EntityRefBuilder> encodedTypeArguments =
-      new List<EntityRefBuilder>(count);
-  for (int i = 0; i < count; i++) {
-    encodedTypeArguments[i] = _createLinkedType(
-        typeArguments[i], compilationUnit, typeParameterContext);
-  }
-  encodedType.typeArguments = encodedTypeArguments;
-}
-
-/// Type of the callback used by [link] to request [CompilationUnit] objects.
-typedef CompilationUnit GetAstCallback(String absoluteUri);
-
-/// Type of the callback used by [link] and [relink] to request
-/// [LinkedLibrary] objects from other build units.
-typedef LinkedLibrary GetDependencyCallback(String absoluteUri);
-
-/// Type of the callback used by [link] and [relink] to request
-/// [UnlinkedUnit] objects.
-typedef UnlinkedUnit GetUnitCallback(String absoluteUri);
-
-class AnalysisSessionForLink implements AnalysisSession {
-  @override
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
-
-/// Element representing a class or enum resynthesized from a summary
-/// during linking.
-abstract class ClassElementForLink
-    with ReferenceableElementForLink
-    implements AbstractClassElementImpl {
-  Map<String, ReferenceableElementForLink> _containedNames;
-
-  @override
-  final CompilationUnitElementForLink enclosingElement;
-
-  /// TODO(brianwilkerson) This appears to be unused and might be removable.
-  bool hasBeenInferred;
-
-  DartType _typeWithDefaultBounds;
-
-  ClassElementForLink(CompilationUnitElementForLink enclosingElement)
-      : enclosingElement = enclosingElement,
-        hasBeenInferred = !enclosingElement.isInBuildUnit;
-
-  @override
-  List<PropertyAccessorElementForLink> get accessors;
-
-  @override
-  ClassElementForLink get asClass => this;
-
-  @override
-  ConstructorElementForLink get asConstructor => unnamedConstructor;
-
-  @override
-  DartType get asStaticType =>
-      enclosingElement.enclosingElement._linker.typeProvider.typeType;
-
-  @override
-  List<ConstructorElementForLink> get constructors;
-
-  @override
-  CompilationUnitElementForLink get enclosingUnit => enclosingElement;
-
-  @override
-  List<FieldElementForLink> get fields;
-
-  /// Indicates whether this is the core class `Object`.
-  bool get isObject;
-
-  @override
-  LibraryElementForLink get library => enclosingElement.library;
-
-  @override
-  Source get librarySource => library.source;
-
-  @override
-  get linkedNode => null;
-
-  @override
-  List<MethodElementForLink> get methods;
-
-  @override
-  String get name;
-
-  @override
-  InterfaceType get thisType {
-    return type;
-  }
-
-  DartType get typeWithDefaultBounds => _typeWithDefaultBounds ??=
-      enclosingElement.library._linker.typeSystem.instantiateToBounds(type);
-
-  @override
-  ConstructorElementForLink get unnamedConstructor;
-
-  @override
-  ReferenceableElementForLink getContainedName(String name) {
-    if (_containedNames == null) {
-      _containedNames = <String, ReferenceableElementForLink>{};
-      // TODO(paulberry): what's the correct way to handle name conflicts?
-      for (ConstructorElementForLink constructor in constructors) {
-        _containedNames[constructor.name] = constructor;
-      }
-      for (PropertyAccessorElementForLink accessor in accessors) {
-        _containedNames[accessor.name] = accessor;
-      }
-      for (MethodElementForLink method in methods) {
-        _containedNames[method.name] = method;
-      }
-    }
-    return _containedNames.putIfAbsent(
-        name, () => UndefinedElementForLink.instance);
-  }
-
-  @override
-  FieldElement getField(String name) {
-    for (FieldElement fieldElement in fields) {
-      if (name == fieldElement.name) {
-        return fieldElement;
-      }
-    }
-    return null;
-  }
-
-  @override
-  PropertyAccessorElement getGetter(String getterName) {
-    for (PropertyAccessorElement accessor in accessors) {
-      if (accessor.isGetter && accessor.name == getterName) {
-        return accessor;
-      }
-    }
-    return null;
-  }
-
-  @override
-  MethodElement getMethod(String methodName) {
-    for (MethodElement method in methods) {
-      if (method.name == methodName) {
-        return method;
-      }
-    }
-    return null;
-  }
-
-  @override
-  InterfaceType instantiate({
-    @required List<DartType> typeArguments,
-    @required NullabilitySuffix nullabilitySuffix,
-  }) {
-    if (typeArguments.length != typeParameters.length) {
-      var ta = 'typeArguments.length (${typeArguments.length})';
-      var tp = 'typeParameters.length (${typeParameters.length})';
-      throw ArgumentError('$ta != $tp');
-    }
-    return InterfaceTypeImpl.explicit(
-      this,
-      typeArguments,
-      nullabilitySuffix: nullabilitySuffix,
-    );
-  }
-
-  /// Perform type inference and cycle detection on this class and
-  /// store the resulting information in [compilationUnit].
-  void link(CompilationUnitElementInBuildUnit compilationUnit);
-
-  @override
-  MethodElement lookUpMethod(String methodName, LibraryElement library) {
-    return AbstractClassElementImpl.lookUpMethodInClass(
-        this, methodName, library);
-  }
-
-  @override
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
-
-/// Element representing a class resynthesized from a summary during
-/// linking.
-class ClassElementForLink_Class extends ClassElementForLink
-    with TypeParameterizedElementMixin, SimplyBoundableForLinkMixin
-    implements ClassElementImpl, ClassMemberContainerForLink {
-  /// The unlinked representation of the class in the summary.
-  final UnlinkedClass _unlinkedClass;
-
-  @override
-  final bool isMixin;
-
-  /// If non-null, the AST for the class or mixin declaration; this is used to
-  /// obtain initializer expressions for type inference.
-  final ClassOrMixinDeclaration _astForInference;
-
-  List<ConstructorElementForLink> _constructors;
-  ConstructorElementForLink _unnamedConstructor;
-  bool _unnamedConstructorComputed = false;
-  List<FieldElementForLink_ClassField> _fields;
-  InterfaceType _supertype;
-  InterfaceType _type;
-  List<MethodElementForLink> _methods;
-  List<InterfaceType> _mixins;
-  List<InterfaceType> _interfaces;
-  List<InterfaceType> _superclassConstraints;
-  List<PropertyAccessorElementForLink> _accessors;
-
-  ClassElementForLink_Class(CompilationUnitElementForLink enclosingElement,
-      this._unlinkedClass, this.isMixin, this._astForInference)
-      : super(enclosingElement) {
-    _initSimplyBoundable();
-  }
-
-  @override
-  List<PropertyAccessorElementForLink> get accessors {
-    if (_accessors == null) {
-      _accessors = <PropertyAccessorElementForLink>[];
-      Map<String, SyntheticVariableElementForLink> syntheticVariables =
-          <String, SyntheticVariableElementForLink>{};
-      for (UnlinkedExecutable unlinkedExecutable
-          in _unlinkedClass.executables) {
-        if (unlinkedExecutable.kind == UnlinkedExecutableKind.getter ||
-            unlinkedExecutable.kind == UnlinkedExecutableKind.setter) {
-          String name = unlinkedExecutable.name;
-          if (unlinkedExecutable.kind == UnlinkedExecutableKind.setter) {
-            assert(name.endsWith('='));
-            name = name.substring(0, name.length - 1);
-          }
-          SyntheticVariableElementForLink syntheticVariable = syntheticVariables
-              .putIfAbsent(name, () => new SyntheticVariableElementForLink());
-          PropertyAccessorElementForLink_Executable accessor =
-              new PropertyAccessorElementForLink_Executable(enclosingElement,
-                  this, unlinkedExecutable, syntheticVariable);
-          _accessors.add(accessor);
-          if (unlinkedExecutable.kind == UnlinkedExecutableKind.getter) {
-            syntheticVariable._getter = accessor;
-          } else {
-            syntheticVariable._setter = accessor;
-          }
-        }
-      }
-      for (FieldElementForLink_ClassField field in fields) {
-        _accessors.add(field.getter);
-        if (!field.isConst && !field.isFinal) {
-          _accessors.add(field.setter);
-        }
-      }
-    }
-    return _accessors;
-  }
-
-  @override
-  List<ConstructorElementForLink> get constructors {
-    if (_constructors == null) {
-      _constructors = <ConstructorElementForLink>[];
-      for (UnlinkedExecutable unlinkedExecutable
-          in _unlinkedClass.executables) {
-        if (unlinkedExecutable.kind == UnlinkedExecutableKind.constructor) {
-          _constructors
-              .add(new ConstructorElementForLink(this, unlinkedExecutable));
-        }
-      }
-      if (_constructors.isEmpty) {
-        _unnamedConstructorComputed = true;
-        _unnamedConstructor = new ConstructorElementForLink_Synthetic(this);
-        _constructors.add(_unnamedConstructor);
-      }
-    }
-    return _constructors;
-  }
-
-  @override
-  ContextForLink get context => enclosingUnit.context;
-
-  @override
-  String get displayName => _unlinkedClass.name;
-
-  @override
-  TypeParameterizedElementMixin get enclosingTypeParameterContext => null;
-
-  @override
-  List<FieldElementForLink_ClassField> get fields {
-    if (_fields == null) {
-      _fields = <FieldElementForLink_ClassField>[];
-      List<Expression> initializerExpressionsForInference;
-      if (_astForInference != null) {
-        initializerExpressionsForInference = [];
-        for (var member in _astForInference.members) {
-          if (member is FieldDeclaration) {
-            for (var variable in member.fields.variables) {
-              initializerExpressionsForInference.add(variable.initializer);
-            }
-          }
-        }
-        assert(initializerExpressionsForInference.length ==
-            _unlinkedClass.fields.length);
-      }
-      for (int i = 0; i < _unlinkedClass.fields.length; i++) {
-        var field = _unlinkedClass.fields[i];
-        _fields.add(new FieldElementForLink_ClassField(
-            this,
-            field,
-            initializerExpressionsForInference == null
-                ? null
-                : initializerExpressionsForInference[i]));
-      }
-    }
-    return _fields;
-  }
-
-  @override
-  String get identifier => name;
-
-  @override
-  List<InterfaceType> get interfaces => _interfaces ??=
-      _unlinkedClass.interfaces.map(_computeInterfaceType).toList();
-
-  @override
-  bool get isAbstract => _unlinkedClass.isAbstract;
-
-  @override
-  bool get isEnum => false;
-
-  @override
-  bool get isMixinApplication => _unlinkedClass.isMixinApplication;
-
-  @override
-  bool get isObject => _unlinkedClass.hasNoSupertype;
-
-  @override
-  LibraryElementForLink get library => enclosingElement.library;
-
-  @override
-  List<MethodElementForLink> get methods {
-    if (_methods == null) {
-      _methods = <MethodElementForLink>[];
-      for (UnlinkedExecutable unlinkedExecutable
-          in _unlinkedClass.executables) {
-        if (unlinkedExecutable.kind ==
-            UnlinkedExecutableKind.functionOrMethod) {
-          _methods.add(new MethodElementForLink(this, unlinkedExecutable));
-        }
-      }
-    }
-    return _methods;
-  }
-
-  @override
-  List<InterfaceType> get mixins {
-    if (_mixins == null) {
-      // Note: in the event of a loop in the class hierarchy, the calls to
-      // collectAllSupertypes below will wind up reentrantly calling
-      // this.mixins.  So to prevent infinite recursion we need to set _mixins
-      // to non-null now.  It's ok that we populate it gradually; in the event
-      // of a reentrant call, the user's code is known to have errors, so it's
-      // ok if the reentrant call doesn't return the complete set of mixins; we
-      // just need to ensure that analysis terminates.
-      _mixins = <InterfaceType>[];
-      List<InterfaceType> supertypesForMixinInference; // populated lazily
-      for (var entity in _unlinkedClass.mixins) {
-        var mixin = _computeInterfaceType(entity);
-        var mixinElement = mixin.element;
-        var slot = entity.refinedSlot;
-        if (slot != 0 && mixinElement.typeParameters.isNotEmpty) {
-          CompilationUnitElementForLink enclosingElement =
-              this.enclosingElement;
-          if (enclosingElement is CompilationUnitElementInBuildUnit) {
-            var mixinSupertypeConstraints = context.typeSystem
-                .gatherMixinSupertypeConstraintsForInference(mixinElement);
-            if (mixinSupertypeConstraints.isNotEmpty) {
-              if (supertypesForMixinInference == null) {
-                supertypesForMixinInference = <InterfaceType>[];
-                ClassElementImpl.collectAllSupertypes(
-                    supertypesForMixinInference, supertype, type);
-                for (var previousMixin in _mixins) {
-                  ClassElementImpl.collectAllSupertypes(
-                      supertypesForMixinInference, previousMixin, type);
-                }
-              }
-              var matchingInterfaceTypes = _findInterfaceTypesForConstraints(
-                  mixinSupertypeConstraints, supertypesForMixinInference);
-              // Note: if matchingInterfaceType is null, that's an error.  Also,
-              // if there are multiple matching interface types that use
-              // different type parameters, that's also an error.  But we can't
-              // report errors from the linker, so we just use the
-              // first matching interface type (if there is one).  The error
-              // detection logic is implemented in the ErrorVerifier.
-              if (matchingInterfaceTypes != null) {
-                // Try to pattern match matchingInterfaceTypes against
-                // mixinSupertypeConstraints to find the correct set of type
-                // parameters to apply to the mixin.
-                var inferredMixin = context.typeSystem
-                    .matchSupertypeConstraints(mixinElement,
-                        mixinSupertypeConstraints, matchingInterfaceTypes);
-                if (inferredMixin != null) {
-                  mixin = inferredMixin;
-                  enclosingElement._storeLinkedType(slot, mixin, this);
-                }
-              }
-            }
-          } else {
-            var refinedMixin = enclosingElement.getLinkedType(this, slot);
-            if (refinedMixin is InterfaceType) {
-              mixin = refinedMixin;
-            }
-          }
-        }
-        _mixins.add(mixin);
-        if (supertypesForMixinInference != null) {
-          ClassElementImpl.collectAllSupertypes(
-              supertypesForMixinInference, mixin, type);
-        }
-      }
-    }
-    return _mixins;
-  }
-
-  @override
-  String get name => _unlinkedClass.name;
-
-  @override
-  AnalysisSession get session => enclosingUnit.session;
-
-  @override
-  List<InterfaceType> get superclassConstraints {
-    if (_superclassConstraints == null) {
-      if (isMixin) {
-        _superclassConstraints = _unlinkedClass.superclassConstraints
-            .map(_computeInterfaceType)
-            .toList();
-        if (_superclassConstraints.isEmpty) {
-          _superclassConstraints = [
-            enclosingElement.enclosingElement._linker.typeProvider.objectType
-          ];
-        }
-      } else {
-        _superclassConstraints = const <InterfaceType>[];
-      }
-    }
-    return _superclassConstraints;
-  }
-
-  @override
-  InterfaceType get supertype {
-    if (isObject) {
-      return null;
-    }
-    return _supertype ??= _computeInterfaceType(_unlinkedClass.supertype);
-  }
-
-  @override
-  InterfaceType get type =>
-      _type ??= buildType((int i) => typeParameterTypes[i], null);
-
-  @override
-  List<UnlinkedTypeParam> get unlinkedTypeParams =>
-      _unlinkedClass.typeParameters;
-
-  @override
-  ConstructorElementForLink get unnamedConstructor {
-    if (!_unnamedConstructorComputed) {
-      for (ConstructorElementForLink constructor in constructors) {
-        if (constructor.name.isEmpty) {
-          _unnamedConstructor = constructor;
-          break;
-        }
-      }
-      _unnamedConstructorComputed = true;
-    }
-    return _unnamedConstructor;
-  }
-
-  @override
-  int get version => 0;
-
-  @override
-  int get _notSimplyBoundedSlot => _unlinkedClass.notSimplyBoundedSlot;
-
-  @override
-  List<EntityRef> get _rhsTypesForSimplyBoundable => const [];
-
-  @override
-  List<UnlinkedTypeParam> get _typeParametersForSimplyBoundable {
-    return _unlinkedClass.typeParameters;
-  }
-
-  @override
-  DartType buildType(
-      DartType getTypeArgument(int i), List<int> implicitFunctionTypeIndices) {
-    int numTypeParameters = _unlinkedClass.typeParameters.length;
-    if (numTypeParameters != 0) {
-      List<DartType> typeArguments =
-          new List<DartType>.generate(numTypeParameters, getTypeArgument);
-      if (typeArguments.contains(null)) {
-        return context.typeSystem.instantiateToBounds(this.type);
-      } else {
-        return new InterfaceTypeImpl.elementWithNameAndArgs(
-            this, name, () => typeArguments);
-      }
-    } else {
-      return _type ??= new InterfaceTypeImpl(this);
-    }
-  }
-
-  @override
-  ConstructorElement getNamedConstructor(String name) =>
-      ClassElementImpl.getNamedConstructorFromList(name, constructors);
-
-  @override
-  PropertyAccessorElement getSetter(String setterName) =>
-      AbstractClassElementImpl.getSetterFromAccessors(setterName, accessors);
-
-  @override
-  void link(CompilationUnitElementInBuildUnit compilationUnit) {
-    // Force mixins to be inferred by calling this.mixins.  We don't need the
-    // return value from the getter; we just need it to execute and record the
-    // mixin inference results as a side effect.
-    this.mixins;
-
-    _linkSimplyBoundable();
-
-    for (ConstructorElementForLink constructorElement in constructors) {
-      constructorElement.link(compilationUnit);
-    }
-    for (MethodElementForLink methodElement in methods) {
-      methodElement.link(compilationUnit);
-    }
-    for (PropertyAccessorElementForLink propertyAccessorElement in accessors) {
-      propertyAccessorElement.link(compilationUnit);
-    }
-    for (FieldElementForLink_ClassField fieldElement in fields) {
-      fieldElement.link(compilationUnit);
-    }
-  }
-
-  @override
-  String toString() => '$enclosingElement.$name';
-
-  /// Convert [typeRef] into an [InterfaceType].
-  InterfaceType _computeInterfaceType(EntityRef typeRef) {
-    if (typeRef != null) {
-      DartType type = enclosingElement.resolveTypeRef(this, typeRef);
-      if (type is InterfaceType && !type.element.isEnum) {
-        return type;
-      }
-      // In the event that the `typeRef` isn't an interface type (which may
-      // happen in the event of erroneous code) just fall through and pretend
-      // the supertype is `Object`.
-    }
-    return enclosingElement.enclosingElement._linker.typeProvider.objectType;
-  }
-
-  InterfaceType _findInterfaceTypeForElement(
-      ClassElement element, List<InterfaceType> interfaceTypes) {
-    for (var interfaceType in interfaceTypes) {
-      if (interfaceType.element == element) return interfaceType;
-    }
-    return null;
-  }
-
-  List<InterfaceType> _findInterfaceTypesForConstraints(
-      List<InterfaceType> constraints, List<InterfaceType> interfaceTypes) {
-    var result = <InterfaceType>[];
-    for (var constraint in constraints) {
-      var interfaceType =
-          _findInterfaceTypeForElement(constraint.element, interfaceTypes);
-      if (interfaceType == null) {
-        // No matching interface type found, so inference fails.
-        return null;
-      }
-      result.add(interfaceType);
-    }
-    return result;
-  }
-}
-
-/// Element representing an enum resynthesized from a summary during
-/// linking.
-class ClassElementForLink_Enum extends ClassElementForLink
-    implements EnumElementImpl {
-  /// The unlinked representation of the enum in the summary.
-  final UnlinkedEnum _unlinkedEnum;
-
-  InterfaceType _type;
-  List<FieldElementForLink> _fields;
-  List<PropertyAccessorElementForLink> _accessors;
-  DartType _valuesType;
-
-  ClassElementForLink_Enum(
-      CompilationUnitElementForLink enclosingElement, this._unlinkedEnum)
-      : super(enclosingElement);
-
-  @override
-  List<PropertyAccessorElementForLink> get accessors {
-    if (_accessors == null) {
-      _accessors = <PropertyAccessorElementForLink>[];
-      for (FieldElementForLink field in fields) {
-        _accessors.add(field.getter);
-      }
-    }
-    return _accessors;
-  }
-
-  @override
-  List<ConstructorElementForLink> get constructors => const [];
-
-  @override
-  String get displayName => _unlinkedEnum.name;
-
-  @override
-  List<FieldElementForLink> get fields {
-    if (_fields == null) {
-      _fields = <FieldElementForLink>[];
-      _fields.add(new FieldElementForLink_EnumField_values(this));
-      for (UnlinkedEnumValue value in _unlinkedEnum.values) {
-        _fields.add(new FieldElementForLink_EnumField_value(this, value));
-      }
-      _fields.add(new FieldElementForLink_EnumField_index(this));
-    }
-    return _fields;
-  }
-
-  @override
-  List<InterfaceType> get interfaces => const [];
-
-  @override
-  bool get isAbstract => false;
-
-  @override
-  bool get isEnum => true;
-
-  @override
-  bool get isMixin => false;
-
-  @override
-  bool get isObject => false;
-
-  @override
-  List<MethodElementForLink> get methods => const [];
-
-  @override
-  List<InterfaceType> get mixins => const [];
-
-  @override
-  String get name => _unlinkedEnum.name;
-
-  @override
-  List<InterfaceType> get superclassConstraints => const [];
-
-  @override
-  InterfaceType get supertype => library._linker.typeProvider.objectType;
-
-  @override
-  InterfaceType get type => _type ??= new InterfaceTypeImpl(this);
-
-  @override
-  List<TypeParameterElement> get typeParameters => const [];
-
-  @override
-  ConstructorElementForLink get unnamedConstructor => null;
-
-  /// Get the type of the enum's static member `values`.
-  DartType get valuesType =>
-      _valuesType ??= library._linker.typeProvider.listType.instantiate([type]);
-
-  @override
-  DartType buildType(DartType getTypeArgument(int i),
-          List<int> implicitFunctionTypeIndices) =>
-      type;
-
-  @override
-  ConstructorElement getNamedConstructor(String name) => null;
-
-  @override
-  void link(CompilationUnitElementInBuildUnit compilationUnit) {}
-
-  @override
-  String toString() => '$enclosingElement.$name';
-}
-
-abstract class ClassMemberContainerForLink
-    implements ReferenceableElementForLink, TypeParameterizedElementMixin {}
-
-/// Element representing a compilation unit resynthesized from a
-/// summary during linking.
-abstract class CompilationUnitElementForLink
-    implements CompilationUnitElementImpl, ResynthesizerContext {
-  final _UnitResynthesizer _unitResynthesizer;
-
-  /// The unlinked representation of the compilation unit in the
-  /// summary.
-  final UnlinkedUnit _unlinkedUnit;
-
-  /// For each entry in [UnlinkedUnit.references], the element referred
-  /// to by the reference, or `null` if it hasn't been located yet.
-  final List<_ReferenceInfo> _references;
-
-  /// The absolute URI of this compilation unit.
-  final String _absoluteUri;
-
-  List<ClassElementForLink_Class> _mixins;
-  List<ClassElementForLink_Class> _types;
-  Map<String, ReferenceableElementForLink> _containedNames;
-  List<TopLevelVariableElementForLink> _topLevelVariables;
-  List<ClassElementForLink_Enum> _enums;
-  List<ExtensionElementForLink> _extensions;
-  List<TopLevelFunctionElementForLink> _functions;
-  List<PropertyAccessorElementForLink> _accessors;
-  List<FunctionTypeAliasElementForLink> _functionTypeAliases;
-
-  /// Index of this unit in the list of units in the enclosing library.
-  final int unitNum;
-
-  @override
-  final Source source;
-
-  /// If non-null, the AST for the compilation unit; this is used to obtain
-  /// initializer expressions for type inference.
-  final CompilationUnit _astForInference;
-
-  CompilationUnitElementForLink(UnlinkedUnit unlinkedUnit, this.unitNum,
-      int numReferences, this._absoluteUri, this._astForInference)
-      : _references = new List<_ReferenceInfo>(numReferences),
-        _unlinkedUnit = unlinkedUnit,
-        source = new InSummarySource(Uri.parse(_absoluteUri), null),
-        _unitResynthesizer = new _UnitResynthesizer() {
-    _unitResynthesizer._unit = this;
-  }
-
-  @override
-  List<PropertyAccessorElementForLink> get accessors {
-    if (_accessors == null) {
-      _accessors = <PropertyAccessorElementForLink>[];
-      Map<String, SyntheticVariableElementForLink> syntheticVariables =
-          <String, SyntheticVariableElementForLink>{};
-      for (UnlinkedExecutable unlinkedExecutable in _unlinkedUnit.executables) {
-        if (unlinkedExecutable.kind == UnlinkedExecutableKind.getter ||
-            unlinkedExecutable.kind == UnlinkedExecutableKind.setter) {
-          String name = unlinkedExecutable.name;
-          if (unlinkedExecutable.kind == UnlinkedExecutableKind.setter) {
-            assert(name.endsWith('='));
-            name = name.substring(0, name.length - 1);
-          }
-          SyntheticVariableElementForLink syntheticVariable = syntheticVariables
-              .putIfAbsent(name, () => new SyntheticVariableElementForLink());
-          PropertyAccessorElementForLink_Executable accessor =
-              new PropertyAccessorElementForLink_Executable(
-                  this, null, unlinkedExecutable, syntheticVariable);
-          _accessors.add(accessor);
-          if (unlinkedExecutable.kind == UnlinkedExecutableKind.getter) {
-            syntheticVariable._getter = accessor;
-          } else {
-            syntheticVariable._setter = accessor;
-          }
-        }
-      }
-      for (TopLevelVariableElementForLink variable in topLevelVariables) {
-        _accessors.add(variable.getter);
-        if (!variable.isConst && !variable.isFinal) {
-          _accessors.add(variable.setter);
-        }
-      }
-    }
-    return _accessors;
-  }
-
-  @override
-  ContextForLink get context => library.context;
-
-  @override
-  LibraryElementForLink get enclosingElement;
-
-  @override
-  List<ClassElementForLink_Enum> get enums {
-    if (_enums == null) {
-      _enums = <ClassElementForLink_Enum>[];
-      for (UnlinkedEnum unlinkedEnum in _unlinkedUnit.enums) {
-        _enums.add(new ClassElementForLink_Enum(this, unlinkedEnum));
-      }
-    }
-    return _enums;
-  }
-
-  @override
-  List<ExtensionElementForLink> get extensions {
-    if (_extensions == null) {
-      _extensions = <ExtensionElementForLink>[];
-      for (UnlinkedExtension unlinkedExtension in _unlinkedUnit.extensions) {
-        _extensions.add(ExtensionElementForLink(this, unlinkedExtension));
-      }
-    }
-    return _extensions;
-  }
-
-  @override
-  List<TopLevelFunctionElementForLink> get functions {
-    if (_functions == null) {
-      _functions = <TopLevelFunctionElementForLink>[];
-      for (UnlinkedExecutable executable in _unlinkedUnit.executables) {
-        if (executable.kind == UnlinkedExecutableKind.functionOrMethod) {
-          _functions.add(new TopLevelFunctionElementForLink(this, executable));
-        }
-      }
-    }
-    return _functions;
-  }
-
-  @override
-  List<FunctionTypeAliasElementForLink> get functionTypeAliases =>
-      _functionTypeAliases ??= _unlinkedUnit.typedefs.map((UnlinkedTypedef t) {
-        if (t.style == TypedefStyle.functionType) {
-          return new FunctionTypeAliasElementForLink(this, t);
-        } else if (t.style == TypedefStyle.genericFunctionType) {
-          return new GenericTypeAliasElementForLink(this, t);
-        } else {
-          throw new StateError('Unhandled style of typedef: ${t.style}');
-        }
-      }).toList();
-
-  @override
-  String get identifier => _absoluteUri;
-
-  /// Indicates whether this compilation element is part of the build unit
-  /// currently being linked.
-  bool get isInBuildUnit;
-
-  /// Determine whether type inference is complete in this compilation unit.
-  bool get isTypeInferenceComplete {
-    LibraryCycleForLink libraryCycleForLink = library.libraryCycleForLink;
-    if (libraryCycleForLink == null) {
-      return true;
-    } else {
-      return libraryCycleForLink._node.isEvaluated;
-    }
-  }
-
-  @override
-  LibraryElementForLink get library => enclosingElement;
-
-  @override
-  List<ClassElementForLink_Class> get mixins {
-    if (_mixins == null) {
-      List<MixinDeclaration> declarationsForInference;
-      if (_astForInference != null) {
-        declarationsForInference = [];
-        for (var declaration in _astForInference.declarations) {
-          if (declaration is MixinDeclaration) {
-            declarationsForInference.add(declaration);
-          }
-        }
-        assert(declarationsForInference.length == _unlinkedUnit.mixins.length);
-      }
-      _mixins = <ClassElementForLink_Class>[];
-      for (int i = 0; i < _unlinkedUnit.mixins.length; i++) {
-        var unlinkedClass = _unlinkedUnit.mixins[i];
-        _mixins.add(new ClassElementForLink_Class(
-            this,
-            unlinkedClass,
-            true,
-            declarationsForInference == null
-                ? null
-                : declarationsForInference[i]));
-      }
-    }
-    return _mixins;
-  }
-
-  @override
-  ResynthesizerContext get resynthesizerContext => this;
-
-  @override
-  AnalysisSession get session => library.session;
-
-  @override
-  List<TopLevelVariableElementForLink> get topLevelVariables {
-    if (_topLevelVariables == null) {
-      List<Expression> initializerExpressionsForInference;
-      if (_astForInference != null) {
-        initializerExpressionsForInference = [];
-        for (var declaration in _astForInference.declarations) {
-          if (declaration is TopLevelVariableDeclaration) {
-            for (var variable in declaration.variables.variables) {
-              initializerExpressionsForInference.add(variable.initializer);
-            }
-          }
-        }
-        assert(initializerExpressionsForInference.length ==
-            _unlinkedUnit.variables.length);
-      }
-      _topLevelVariables = <TopLevelVariableElementForLink>[];
-      for (int i = 0; i < _unlinkedUnit.variables.length; i++) {
-        var unlinkedVariable = _unlinkedUnit.variables[i];
-        _topLevelVariables.add(new TopLevelVariableElementForLink(
-            this,
-            unlinkedVariable,
-            initializerExpressionsForInference == null
-                ? null
-                : initializerExpressionsForInference[i]));
-      }
-    }
-    return _topLevelVariables;
-  }
-
-  @override
-  List<ClassElementForLink_Class> get types {
-    if (_types == null) {
-      List<ClassDeclaration> declarationsForInference;
-      if (_astForInference != null) {
-        declarationsForInference = [];
-        for (var declaration in _astForInference.declarations) {
-          if (declaration is ClassDeclaration) {
-            declarationsForInference.add(declaration);
-          } else if (declaration is ClassTypeAlias) {
-            declarationsForInference.add(null);
-          }
-        }
-        assert(declarationsForInference.length == _unlinkedUnit.classes.length);
-      }
-      _types = <ClassElementForLink_Class>[];
-      for (int i = 0; i < _unlinkedUnit.classes.length; i++) {
-        var unlinkedClass = _unlinkedUnit.classes[i];
-        _types.add(new ClassElementForLink_Class(
-            this,
-            unlinkedClass,
-            false,
-            declarationsForInference == null
-                ? null
-                : declarationsForInference[i]));
-      }
-    }
-    return _types;
-  }
-
-  /// The linked representation of the compilation unit in the summary.
-  LinkedUnit get _linkedUnit;
-
-  /// Search the unit for a top level element with the given [name].
-  /// If no name is found, return the singleton instance of
-  /// [UndefinedElementForLink].
-  ReferenceableElementForLink getContainedName(name) {
-    if (_containedNames == null) {
-      _containedNames = <String, ReferenceableElementForLink>{};
-      // TODO(paulberry): what's the correct way to handle name conflicts?
-      for (ClassElementForLink_Class type in types) {
-        _containedNames[type.name] = type;
-      }
-      for (ClassElementForLink_Class mixin in mixins) {
-        _containedNames[mixin.name] = mixin;
-      }
-      for (ClassElementForLink_Enum enm in enums) {
-        _containedNames[enm.name] = enm;
-      }
-      for (TopLevelFunctionElementForLink function in functions) {
-        _containedNames[function.name] = function;
-      }
-      for (PropertyAccessorElementForLink accessor in accessors) {
-        _containedNames[accessor.name] = accessor;
-      }
-      for (FunctionTypeAliasElementForLink functionTypeAlias
-          in functionTypeAliases) {
-        _containedNames[functionTypeAlias.name] = functionTypeAlias;
-      }
-      // TODO(paulberry): fill in other top level entities (typedefs
-      // and executables).
-    }
-    return _containedNames.putIfAbsent(
-        name, () => UndefinedElementForLink.instance);
-  }
-
-  /// Compute the type referred to by the given linked type [slot] (interpreted
-  /// in [context]).  If there is no inferred type in the
-  /// given slot, `dynamic` is returned.
-  DartType getLinkedType(ElementImpl context, int slot);
-
-  @override
-  ClassElement getType(String className) =>
-      CompilationUnitElementImpl.getTypeFromTypes(className, types);
-
-  @override
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-
-  /// Return the class element for the constructor referred to by the given
-  /// [index] in [UnlinkedUnit.references].  If the reference is unresolved,
-  /// return [UndefinedElementForLink.instance].
-  ReferenceableElementForLink resolveConstructorClassRef(int index) {
-    LinkedReference linkedReference = _linkedUnit.references[index];
-    if (linkedReference.kind == ReferenceKind.classOrEnum) {
-      return resolveRef(index);
-    }
-    if (index < _unlinkedUnit.references.length) {
-      UnlinkedReference unlinkedReference = _unlinkedUnit.references[index];
-      return resolveRef(unlinkedReference.prefixReference);
-    }
-    return UndefinedElementForLink.instance;
-  }
-
-  /// Return the element referred to by the given [index] in
-  /// [UnlinkedUnit.references].  If the reference is unresolved,
-  /// return [UndefinedElementForLink.instance].
-  ReferenceableElementForLink resolveRef(int index) =>
-      resolveRefToInfo(index).element;
-
-  _ReferenceInfo resolveRefToInfo(int index) {
-    if (_references[index] == null) {
-      UnlinkedReference unlinkedReference =
-          index < _unlinkedUnit.references.length
-              ? _unlinkedUnit.references[index]
-              : null;
-      LinkedReference linkedReference = _linkedUnit.references[index];
-      String name = unlinkedReference == null
-          ? linkedReference.name
-          : unlinkedReference.name;
-      int containingReference = unlinkedReference == null
-          ? linkedReference.containingReference
-          : unlinkedReference.prefixReference;
-      _ReferenceInfo enclosingInfo = containingReference != 0
-          ? resolveRefToInfo(containingReference)
-          : null;
-      ReferenceableElementForLink element;
-      if (containingReference != 0 &&
-          _linkedUnit.references[containingReference].kind !=
-              ReferenceKind.prefix) {
-        element = enclosingInfo.element.getContainedName(name);
-      } else if (linkedReference.dependency == 0) {
-        if (linkedReference.kind == ReferenceKind.unresolved) {
-          element = UndefinedElementForLink.instance;
-        } else if (name == 'void') {
-          element = enclosingElement._linker.voidElement;
-        } else if (name == '*bottom*') {
-          element = enclosingElement._linker.bottomElement;
-        } else if (name == 'dynamic') {
-          element = enclosingElement._linker.dynamicElement;
-        } else {
-          element = enclosingElement.getContainedName(name);
-        }
-      } else {
-        LibraryElementForLink dependency =
-            enclosingElement.buildImportedLibrary(linkedReference.dependency);
-        element = dependency.getContainedName(name);
-      }
-      _references[index] = new _ReferenceInfo(
-          enclosingInfo, element, name, linkedReference.numTypeParameters != 0);
-    }
-    return _references[index];
-  }
-
-  @override
-  DartType resolveTypeRef(ElementImpl context, EntityRef entity,
-      {bool defaultVoid: false,
-      bool instantiateToBoundsAllowed: true,
-      bool declaredType: false}) {
-    if (entity == null) {
-      if (defaultVoid) {
-        return VoidTypeImpl.instance;
-      } else {
-        return DynamicTypeImpl.instance;
-      }
-    }
-    DartType result;
-    if (entity.paramReference != 0) {
-      result = context.typeParameterContext
-          .getTypeParameterType(entity.paramReference);
-    } else if (entity.entityKind == EntityRefKind.genericFunctionType) {
-      result = new GenericFunctionTypeElementForLink(
-              this,
-              context,
-              entity.typeParameters,
-              entity.syntheticReturnType,
-              entity.syntheticParams)
-          .type;
-    } else if (entity.syntheticReturnType != null) {
-      FunctionElementImpl element =
-          new FunctionElementForLink_Synthetic(this, context, entity);
-      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;
-      }
-      result = type;
-    } else {
-      ReferenceableElementForLink element = resolveRef(entity.reference);
-      bool implicitTypeArgumentsInUse = false;
-
-      DartType getTypeArgument(int i) {
-        if (i < entity.typeArguments.length) {
-          return resolveTypeRef(context, entity.typeArguments[i]);
-        } else {
-          implicitTypeArgumentsInUse = true;
-          if (!instantiateToBoundsAllowed) {
-            // Do not allow buildType to instantiate the bounds; force dynamic.
-            return DynamicTypeImpl.instance;
-          } else {
-            return null;
-          }
-        }
-      }
-
-      result = element.buildType(
-          getTypeArgument, entity.implicitFunctionTypeIndices);
-      if (implicitTypeArgumentsInUse) {
-        _typesWithImplicitArguments[result] = true;
-      }
-    }
-    var nullabilitySuffix = decodeNullabilitySuffix(entity.nullabilitySuffix);
-    return (result as TypeImpl).withNullability(nullabilitySuffix);
-  }
-
-  @override
-  String toString() => enclosingElement.toString();
-}
-
-/// Element representing a compilation unit which is part of the build
-/// unit being linked.
-class CompilationUnitElementInBuildUnit extends CompilationUnitElementForLink {
-  @override
-  final LinkedUnitBuilder _linkedUnit;
-
-  @override
-  final LibraryElementInBuildUnit enclosingElement;
-
-  CompilationUnitElementInBuildUnit(
-      this.enclosingElement,
-      UnlinkedUnit unlinkedUnit,
-      this._linkedUnit,
-      int unitNum,
-      String absoluteUri,
-      CompilationUnit astForInference)
-      : super(unlinkedUnit, unitNum, unlinkedUnit.references.length,
-            absoluteUri, astForInference);
-
-  @override
-  bool get isInBuildUnit => true;
-
-  @override
-  LibraryElementInBuildUnit get library => enclosingElement;
-
-  /// If this compilation unit already has a reference in its references table
-  /// matching [dependency], [name], [numTypeParameters], [unitNum],
-  /// [containingReference], and [kind], return its index.  Otherwise add a new
-  /// reference to the table and return its index.
-  int addRawReference(String name,
-      {int dependency: 0,
-      int numTypeParameters: 0,
-      int unitNum: 0,
-      int containingReference: 0,
-      ReferenceKind kind: ReferenceKind.classOrEnum}) {
-    List<LinkedReferenceBuilder> linkedReferences = _linkedUnit.references;
-    List<UnlinkedReference> unlinkedReferences = _unlinkedUnit.references;
-    for (int i = 0; i < linkedReferences.length; i++) {
-      LinkedReferenceBuilder linkedReference = linkedReferences[i];
-      int candidateContainingReference = i < unlinkedReferences.length
-          ? unlinkedReferences[i].prefixReference
-          : linkedReference.containingReference;
-      if (candidateContainingReference != 0 &&
-          linkedReferences[candidateContainingReference].kind ==
-              ReferenceKind.prefix) {
-        // We don't need to match containing references when they are prefixes,
-        // since the relevant information is in linkedReference.dependency.
-        candidateContainingReference = 0;
-      }
-      if (linkedReference.dependency == dependency &&
-          (i < unlinkedReferences.length
-                  ? unlinkedReferences[i].name
-                  : linkedReference.name) ==
-              name &&
-          linkedReference.numTypeParameters == numTypeParameters &&
-          linkedReference.unit == unitNum &&
-          candidateContainingReference == containingReference &&
-          linkedReference.kind == kind) {
-        return i;
-      }
-    }
-    int result = linkedReferences.length;
-    linkedReferences.add(new LinkedReferenceBuilder(
-        dependency: dependency,
-        name: name,
-        numTypeParameters: numTypeParameters,
-        unit: unitNum,
-        containingReference: containingReference,
-        kind: kind));
-    return result;
-  }
-
-  /// If this compilation unit already has a reference in its references table
-  /// to [element], return its index.  Otherwise add a new reference to the
-  /// table and return its index.
-  int addReference(Element element) {
-    if (element is ClassElementForLink) {
-      return addRawReference(element.name,
-          dependency: library.addDependency(element.library),
-          numTypeParameters: element.typeParameters.length,
-          unitNum: element.enclosingElement.unitNum);
-    } else if (element is FunctionTypeAliasElementForLink) {
-      return addRawReference(element.name,
-          dependency: library.addDependency(element.library),
-          numTypeParameters: element.typeParameters.length,
-          unitNum: element.enclosingElement.unitNum,
-          kind: ReferenceKind.typedef);
-    } else if (element is ExecutableElementForLink_NonLocal) {
-      ClassElementForLink_Class enclosingClass = element.enclosingClass;
-      ReferenceKind kind;
-      switch (element.serializedExecutable.kind) {
-        case UnlinkedExecutableKind.functionOrMethod:
-          kind = enclosingClass != null
-              ? ReferenceKind.method
-              : ReferenceKind.topLevelFunction;
-          break;
-        case UnlinkedExecutableKind.setter:
-          kind = ReferenceKind.propertyAccessor;
-          break;
-        default:
-          // TODO(paulberry): implement other cases as necessary
-          throw new UnimplementedError('${element.serializedExecutable.kind}');
-      }
-      if (enclosingClass == null) {
-        return addRawReference(element.name,
-            numTypeParameters: element.typeParameters.length,
-            dependency:
-                library.addDependency(element.library as LibraryElementForLink),
-            unitNum: element.compilationUnit.unitNum,
-            kind: kind);
-      } else {
-        return addRawReference(element.name,
-            numTypeParameters: element.typeParameters.length,
-            containingReference: addReference(enclosingClass),
-            kind: kind);
-      }
-    } else if (element is FunctionElementForLink_Initializer) {
-      return addRawReference('',
-          containingReference: addReference(element.enclosingElement),
-          kind: ReferenceKind.function);
-    } else if (element is TopLevelVariableElementForLink) {
-      return addRawReference(element.name,
-          dependency: library.addDependency(element.library),
-          unitNum: element.compilationUnit.unitNum,
-          kind: ReferenceKind.topLevelPropertyAccessor);
-    } else if (element is FieldElementForLink_ClassField) {
-      ClassElementForLink_Class enclosingClass = element.enclosingElement;
-      // Note: even if the class has type parameters, we don't need to set
-      // numTypeParameters because numTypeParameters does not count type
-      // parameters of parent elements (see
-      // [LinkedReference.numTypeParameters]).
-      return addRawReference(element.name,
-          containingReference: addReference(enclosingClass),
-          kind: ReferenceKind.propertyAccessor);
-    }
-    // TODO(paulberry): implement other cases
-    throw new UnimplementedError('${element.runtimeType}');
-  }
-
-  @override
-  DartType getLinkedType(ElementImpl context, int slot) {
-    // This method should only be called on compilation units that come from
-    // dependencies, never on compilation units that are part of the current
-    // build unit.
-    throw new StateError(
-        'Linker tried to access linked type from current build unit');
-  }
-
-  /// Perform type inference and const cycle detection on this
-  /// compilation unit.
-  void link() {
-    new InstanceMemberInferrer(
-      library._linker.typeProvider,
-      library._linker.inheritanceManager,
-    ).inferCompilationUnit(this);
-    for (TopLevelVariableElementForLink variable in topLevelVariables) {
-      variable.link(this);
-    }
-    for (ClassElementForLink classElement in types) {
-      classElement.link(this);
-    }
-    for (ClassElementForLink classElement in mixins) {
-      classElement.link(this);
-    }
-    for (var functionTypeAlias in functionTypeAliases) {
-      functionTypeAlias.link(this);
-    }
-  }
-
-  /// Throw away any information stored in the summary by a previous call to
-  /// [link].
-  void unlink() {
-    _linkedUnit.constCycles.clear();
-    _linkedUnit.parametersInheritingCovariant.clear();
-    _linkedUnit.references.length = _unlinkedUnit.references.length;
-    _linkedUnit.types.clear();
-    _linkedUnit.notSimplyBounded.clear();
-  }
-
-  /// Store the fact that the given [slot] represents a constant constructor
-  /// that is part of a cycle.
-  void _storeConstCycle(int slot) {
-    _linkedUnit.constCycles.add(slot);
-  }
-
-  /// Store the fact that the given [slot] represents a parameter that inherits
-  /// `@covariant` behavior.
-  void _storeInheritsCovariant(int slot) {
-    _linkedUnit.parametersInheritingCovariant.add(slot);
-  }
-
-  /// Store the given [linkedType] in the given [slot] of the this compilation
-  /// unit's linked type list.
-  void _storeLinkedType(int slot, DartType linkedType,
-      TypeParameterSerializationContext typeParameterContext) {
-    if (slot != 0) {
-      if (linkedType != null && !linkedType.isDynamic) {
-        _linkedUnit.types.add(_createLinkedType(
-            linkedType, this, typeParameterContext,
-            slot: slot));
-      }
-    }
-  }
-
-  /// Store the given error [error] in the given [slot].
-  void _storeLinkedTypeError(int slot, TopLevelInferenceErrorBuilder error) {
-    if (slot != 0) {
-      if (error != null) {
-        error.slot = slot;
-        _linkedUnit.topLevelInferenceErrors.add(error);
-      }
-    }
-  }
-}
-
-/// Element representing a compilation unit which is depended upon
-/// (either directly or indirectly) by the build unit being linked.
-///
-/// TODO(paulberry): ensure that inferred types in dependencies are properly
-/// resynthesized.
-class CompilationUnitElementInDependency extends CompilationUnitElementForLink {
-  @override
-  final LinkedUnit _linkedUnit;
-
-  /// Set of slot ids corresponding to parameters that inherit `covariant`.
-  Set<int> parametersInheritingCovariant;
-
-  List<EntityRef> _linkedTypeRefs;
-
-  @override
-  final LibraryElementInDependency enclosingElement;
-
-  CompilationUnitElementInDependency(
-      this.enclosingElement,
-      UnlinkedUnit unlinkedUnit,
-      LinkedUnit linkedUnit,
-      int unitNum,
-      String absoluteUri)
-      : _linkedUnit = linkedUnit,
-        super(unlinkedUnit, unitNum, linkedUnit.references.length, absoluteUri,
-            null) {
-    parametersInheritingCovariant =
-        _linkedUnit.parametersInheritingCovariant.toSet();
-    // Make one pass through the linked types to determine the lengths for
-    // _linkedTypeRefs and _linkedTypes.  TODO(paulberry): add an int to the
-    // summary to make this unnecessary.
-    int maxLinkedTypeSlot = 0;
-    for (EntityRef ref in _linkedUnit.types) {
-      if (ref.slot > maxLinkedTypeSlot) {
-        maxLinkedTypeSlot = ref.slot;
-      }
-    }
-    // Initialize _linkedTypeRefs.
-    _linkedTypeRefs = new List<EntityRef>(maxLinkedTypeSlot + 1);
-    for (EntityRef ref in _linkedUnit.types) {
-      _linkedTypeRefs[ref.slot] = ref;
-    }
-  }
-
-  @override
-  bool get isInBuildUnit => false;
-
-  @override
-  DartType getLinkedType(ElementImpl context, int slot) {
-    if (slot < _linkedTypeRefs.length) {
-      return resolveTypeRef(context, _linkedTypeRefs[slot]);
-    } else {
-      return DynamicTypeImpl.instance;
-    }
-  }
-}
-
-/// Instance of [ConstNode] representing a constant constructor.
-class ConstConstructorNode extends ConstNode {
-  /// The [ConstructorElement] to which this node refers.
-  final ConstructorElementForLink constructorElement;
-
-  /// Once this node has been evaluated, indicates whether the
-  /// constructor is free of constant evaluation cycles.
-  bool isCycleFree = false;
-
-  ConstConstructorNode(this.constructorElement);
-
-  @override
-  List<ConstNode> computeDependencies() {
-    List<ConstNode> dependencies = <ConstNode>[];
-    void safeAddDependency(ConstNode target) {
-      if (target != null) {
-        dependencies.add(target);
-      }
-    }
-
-    UnlinkedExecutable unlinkedExecutable =
-        constructorElement.serializedExecutable;
-    ClassElementForLink_Class enclosingClass =
-        constructorElement.enclosingElement;
-    ConstructorElementForLink redirectedConstructor =
-        _getFactoryRedirectedConstructor();
-    if (redirectedConstructor != null) {
-      if (redirectedConstructor._constNode != null) {
-        safeAddDependency(redirectedConstructor._constNode);
-      }
-    } else if (unlinkedExecutable.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.
-    } else {
-      ClassElementForLink superClass = enclosingClass.supertype?.element;
-      bool defaultSuperInvocationNeeded = true;
-      for (UnlinkedConstructorInitializer constructorInitializer
-          in constructorElement.serializedExecutable.constantInitializers) {
-        if (constructorInitializer.kind ==
-            UnlinkedConstructorInitializerKind.superInvocation) {
-          defaultSuperInvocationNeeded = false;
-          if (superClass != null && !superClass.isObject) {
-            ConstructorElementForLink constructor = superClass
-                .getContainedName(constructorInitializer.name)
-                .asConstructor;
-            safeAddDependency(constructor?._constNode);
-          }
-        } else if (constructorInitializer.kind ==
-            UnlinkedConstructorInitializerKind.thisInvocation) {
-          defaultSuperInvocationNeeded = false;
-          ConstructorElementForLink constructor = constructorElement
-              .enclosingClass
-              .getContainedName(constructorInitializer.name)
-              .asConstructor;
-          safeAddDependency(constructor?._constNode);
-        }
-        CompilationUnitElementForLink compilationUnit =
-            constructorElement.enclosingElement.enclosingElement;
-        collectDependencies(
-            dependencies, constructorInitializer.expression, compilationUnit);
-        for (UnlinkedExpr unlinkedConst in constructorInitializer.arguments) {
-          collectDependencies(dependencies, unlinkedConst, compilationUnit);
-        }
-      }
-
-      if (defaultSuperInvocationNeeded) {
-        // No explicit superconstructor invocation found, so we need to
-        // manually insert a reference to the implicit superconstructor.
-        if (superClass != null && !superClass.isObject) {
-          ConstructorElementForLink unnamedConstructor =
-              superClass.unnamedConstructor;
-          safeAddDependency(unnamedConstructor?._constNode);
-        }
-      }
-      for (FieldElementForLink field in enclosingClass.fields) {
-        // Note: non-static const isn't allowed but we handle it anyway so
-        // that we won't be confused by incorrect code.
-        if ((field.isFinal || field.isConst) && !field.isStatic) {
-          safeAddDependency(field.getter.asConstVariable);
-        }
-      }
-      for (ParameterElementForLink parameterElement
-          in constructorElement.parameters) {
-        safeAddDependency(parameterElement._constNode);
-      }
-    }
-    return dependencies;
-  }
-
-  /// If [constructorElement] redirects to another constructor via a factory
-  /// redirect, return the constructor it redirects to.
-  ConstructorElementForLink _getFactoryRedirectedConstructor() {
-    EntityRef redirectedConstructor =
-        constructorElement.serializedExecutable.redirectedConstructor;
-    if (redirectedConstructor != null) {
-      return constructorElement.compilationUnit
-          .resolveRef(redirectedConstructor.reference)
-          .asConstructor;
-    } else {
-      return null;
-    }
-  }
-}
-
-/// Specialization of [DependencyWalker] for detecting constant
-/// evaluation cycles.
-class ConstDependencyWalker extends DependencyWalker<ConstNode> {
-  @override
-  void evaluate(ConstNode v) {
-    if (v is ConstConstructorNode) {
-      v.isCycleFree = true;
-    }
-    v.isEvaluated = true;
-  }
-
-  @override
-  void evaluateScc(List<ConstNode> scc) {
-    for (ConstNode v in scc) {
-      if (v is ConstConstructorNode) {
-        v.isCycleFree = false;
-      }
-      v.isEvaluated = true;
-    }
-  }
-}
-
-/// Specialization of [Node] used to construct the constant evaluation
-/// dependency graph.
-abstract class ConstNode extends Node<ConstNode> {
-  @override
-  bool isEvaluated = false;
-
-  /// Collect the dependencies in [unlinkedConst] (which should be
-  /// interpreted relative to [compilationUnit]) and store them in
-  /// [dependencies].
-  void collectDependencies(
-      List<ConstNode> dependencies,
-      UnlinkedExpr unlinkedConst,
-      CompilationUnitElementForLink compilationUnit) {
-    if (unlinkedConst == null) {
-      return;
-    }
-    int refPtr = 0;
-    int intPtr = 0;
-    for (UnlinkedExprOperation operation in unlinkedConst.operations) {
-      switch (operation) {
-        case UnlinkedExprOperation.pushInt:
-          intPtr++;
-          break;
-        case UnlinkedExprOperation.pushLongInt:
-          int numInts = unlinkedConst.ints[intPtr++];
-          intPtr += numInts;
-          break;
-        case UnlinkedExprOperation.concatenate:
-          intPtr++;
-          break;
-        case UnlinkedExprOperation.pushReference:
-          EntityRef ref = unlinkedConst.references[refPtr++];
-          ConstVariableNode variable =
-              compilationUnit.resolveRef(ref.reference).asConstVariable;
-          if (variable != null) {
-            dependencies.add(variable);
-          }
-          break;
-        case UnlinkedExprOperation.makeUntypedList:
-        case UnlinkedExprOperation.makeUntypedMap:
-        case UnlinkedExprOperation.makeUntypedSet:
-        case UnlinkedExprOperation.makeUntypedSetOrMap:
-        case UnlinkedExprOperation.forParts:
-        case UnlinkedExprOperation.variableDeclaration:
-        case UnlinkedExprOperation.forInitializerDeclarationsUntyped:
-          intPtr++;
-          break;
-        case UnlinkedExprOperation.assignToRef:
-        case UnlinkedExprOperation.forEachPartsWithTypedDeclaration:
-          refPtr++;
-          break;
-        case UnlinkedExprOperation.invokeMethodRef:
-          EntityRef ref = unlinkedConst.references[refPtr++];
-          ConstVariableNode variable =
-              compilationUnit.resolveRef(ref.reference).asConstVariable;
-          if (variable != null) {
-            dependencies.add(variable);
-          }
-          intPtr += 2;
-          int numTypeArguments = unlinkedConst.ints[intPtr++];
-          refPtr += numTypeArguments;
-          break;
-        case UnlinkedExprOperation.invokeMethod:
-          intPtr += 2;
-          int numTypeArguments = unlinkedConst.ints[intPtr++];
-          refPtr += numTypeArguments;
-          break;
-        case UnlinkedExprOperation.makeTypedList:
-        case UnlinkedExprOperation.makeTypedSet:
-        case UnlinkedExprOperation.forInitializerDeclarationsTyped:
-          refPtr++;
-          intPtr++;
-          break;
-        case UnlinkedExprOperation.makeTypedMap:
-        case UnlinkedExprOperation.makeTypedMap2:
-          refPtr += 2;
-          intPtr++;
-          break;
-        case UnlinkedExprOperation.invokeConstructor:
-          EntityRef ref = unlinkedConst.references[refPtr++];
-          ConstructorElementForLink element =
-              compilationUnit.resolveRef(ref.reference).asConstructor;
-          if (element?._constNode != null) {
-            dependencies.add(element._constNode);
-          }
-          intPtr += 2;
-          break;
-        case UnlinkedExprOperation.typeCast:
-        case UnlinkedExprOperation.typeCheck:
-          refPtr++;
-          break;
-        case UnlinkedExprOperation.pushLocalFunctionReference:
-          intPtr += 2;
-          break;
-        default:
-          break;
-      }
-    }
-    assert(refPtr == unlinkedConst.references.length);
-    assert(intPtr == unlinkedConst.ints.length);
-  }
-}
-
-/// Instance of [ConstNode] representing a parameter with a default
-/// value.
-class ConstParameterNode extends ConstNode {
-  /// The [ParameterElement] to which this node refers.
-  final ParameterElementForLink parameterElement;
-
-  ConstParameterNode(this.parameterElement);
-
-  @override
-  List<ConstNode> computeDependencies() {
-    List<ConstNode> dependencies = <ConstNode>[];
-    collectDependencies(
-        dependencies,
-        parameterElement.unlinkedParam.initializer?.bodyExpr,
-        parameterElement.compilationUnit);
-    return dependencies;
-  }
-}
-
-/// Element representing a constructor resynthesized from a summary
-/// during linking.
-class ConstructorElementForLink extends ExecutableElementForLink_NonLocal
-    with ReferenceableElementForLink
-    implements ConstructorElementImpl {
-  /// If this is a `const` constructor and the enclosing library is
-  /// part of the build unit being linked, the constructor's node in
-  /// the constant evaluation dependency graph.  Otherwise `null`.
-  ConstConstructorNode _constNode;
-
-  ConstructorElementForLink(ClassElementForLink_Class enclosingClass,
-      UnlinkedExecutable unlinkedExecutable)
-      : super(enclosingClass.enclosingElement, enclosingClass,
-            unlinkedExecutable) {
-    if (enclosingClass.enclosingElement.isInBuildUnit &&
-        serializedExecutable != null &&
-        serializedExecutable.constCycleSlot != 0) {
-      _constNode = new ConstConstructorNode(this);
-    }
-  }
-
-  @override
-  ConstructorElementForLink get asConstructor => this;
-
-  @override
-  ClassElementImpl get enclosingElement =>
-      super.enclosingClass as ClassElementImpl;
-
-  @override
-  String get identifier => name;
-
-  @override
-  bool get isConst => serializedExecutable.isConst;
-
-  @override
-  bool get isCycleFree {
-    if (!_constNode.isEvaluated) {
-      new ConstDependencyWalker().walk(_constNode);
-    }
-    return _constNode.isCycleFree;
-  }
-
-  @override
-  DartType get returnType => enclosingElement.type;
-
-  @override
-  List<TypeParameterElement> get typeParameters => const [];
-
-  /// Perform const cycle detection on this constructor.
-  void link(CompilationUnitElementInBuildUnit compilationUnit) {
-    if (_constNode != null && !isCycleFree) {
-      compilationUnit._storeConstCycle(serializedExecutable.constCycleSlot);
-    }
-    // TODO(paulberry): call super.
-  }
-
-  @override
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
-
-/// A synthetic constructor.
-class ConstructorElementForLink_Synthetic extends ConstructorElementForLink {
-  ConstructorElementForLink_Synthetic(
-      ClassElementForLink_Class enclosingElement)
-      : super(enclosingElement, null);
-
-  @override
-  String get name => '';
-
-  @override
-  List<ParameterElement> get parameters => const <ParameterElement>[];
-}
-
-/// Instance of [ConstNode] representing a constant field or constant
-/// top level variable.
-class ConstVariableNode extends ConstNode {
-  /// The [FieldElement] or [TopLevelVariableElement] to which this
-  /// node refers.
-  final VariableElementForLink variableElement;
-
-  ConstVariableNode(this.variableElement);
-
-  @override
-  List<ConstNode> computeDependencies() {
-    List<ConstNode> dependencies = <ConstNode>[];
-    collectDependencies(
-        dependencies,
-        variableElement.unlinkedVariable.initializer?.bodyExpr,
-        variableElement.compilationUnit);
-    return dependencies;
-  }
-}
-
-/// Stub implementation of [AnalysisContext] which provides just those methods
-/// needed during linking.
-class ContextForLink implements AnalysisContext {
-  final Linker _linker;
-
-  ContextForLink(this._linker);
-
-  @override
-  AnalysisOptions get analysisOptions => _linker.analysisOptions;
-
-  @override
-  TypeProvider get typeProvider => _linker.typeProvider;
-
-  @override
-  TypeSystem get typeSystem => _linker.typeSystem;
-
-  @override
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
-
 /**
  * An instance of [DependencyWalker] contains the core algorithms for
  * walking a dependency graph and evaluating nodes in a safe order.
@@ -2275,1988 +128,6 @@
   }
 }
 
-/// Base class for executable elements resynthesized from a summary during
-/// linking.
-abstract class ExecutableElementForLink
-    with TypeParameterizedElementMixin, ParameterParentElementForLink
-    implements ExecutableElementImpl {
-  /// The unlinked representation of the method in the summary.
-  final UnlinkedExecutable serializedExecutable;
-
-  DartType _declaredReturnType;
-  DartType _inferredReturnType;
-  FunctionTypeImpl _type;
-  String _name;
-  String _displayName;
-
-  final CompilationUnitElementForLink compilationUnit;
-
-  ExecutableElementForLink(this.compilationUnit, this.serializedExecutable);
-
-  @override
-  ContextForLink get context => compilationUnit.context;
-
-  /// If the executable element had an explicitly declared return type, return
-  /// it.  Otherwise return `null`.
-  DartType get declaredReturnType {
-    if (serializedExecutable.returnType == null) {
-      return null;
-    } else {
-      return _declaredReturnType ??=
-          compilationUnit.resolveTypeRef(this, serializedExecutable.returnType);
-    }
-  }
-
-  @override
-  String get displayName {
-    if (_displayName == null) {
-      _displayName = serializedExecutable.name;
-      if (serializedExecutable.kind == UnlinkedExecutableKind.setter) {
-        _displayName = _displayName.substring(0, _displayName.length - 1);
-      }
-    }
-    return _displayName;
-  }
-
-  @override
-  CompilationUnitElementImpl get enclosingUnit => compilationUnit;
-
-  /// Return a list containing all of the functions defined within this
-  /// executable element.
-  List<FunctionElement> get functions {
-    return [];
-  }
-
-  @override
-  bool get hasImplicitReturnType => serializedExecutable.returnType == null;
-
-  @override
-  List<int> get implicitFunctionTypeIndices => const <int>[];
-
-  /// Return the inferred return type of the executable element.  Should only be
-  /// called if no return type was explicitly declared.
-  DartType get inferredReturnType {
-    // We should only try to infer a return type when none is explicitly
-    // declared.
-    assert(serializedExecutable.returnType == null);
-    if (Linker._initializerTypeInferenceCycle != null &&
-        Linker._initializerTypeInferenceCycle ==
-            compilationUnit.library.libraryCycleForLink) {
-      // We are currently computing the type of an initializer expression in the
-      // current library cycle, so type inference results should be ignored.
-      return _computeDefaultReturnType();
-    }
-    if (_inferredReturnType == null) {
-      if (serializedExecutable.kind == UnlinkedExecutableKind.constructor) {
-        // TODO(paulberry): implement.
-        throw new UnimplementedError();
-      } else if (compilationUnit.isInBuildUnit) {
-        _inferredReturnType = _computeDefaultReturnType();
-      } else {
-        _inferredReturnType = compilationUnit.getLinkedType(
-            this, serializedExecutable.inferredReturnTypeSlot);
-      }
-    }
-    return _inferredReturnType;
-  }
-
-  @override
-  bool get isAbstract => serializedExecutable.isAbstract;
-
-  @override
-  bool get isGenerator => serializedExecutable.isGenerator;
-
-  @override
-  bool get isStatic => serializedExecutable.isStatic;
-
-  @override
-  bool get isSynthetic => false;
-
-  @override
-  LibraryElement get library => enclosingElement.library;
-
-  @override
-  get linkedNode => null;
-
-  @override
-  String get name {
-    if (_name == null) {
-      _name = serializedExecutable.name;
-      if (_name == '-' && serializedExecutable.parameters.isEmpty) {
-        _name = 'unary-';
-      }
-    }
-    return _name;
-  }
-
-  @override
-  DartType get returnType => declaredReturnType ?? inferredReturnType;
-
-  @override
-  void set returnType(DartType inferredType) {
-    _inferredReturnType = inferredType;
-  }
-
-  @override
-  AnalysisSession get session => compilationUnit.session;
-
-  @override
-  FunctionTypeImpl get type => _type ??= new FunctionTypeImpl(this);
-
-  @override
-  TypeParameterizedElementMixin get typeParameterContext => this;
-
-  @override
-  List<UnlinkedParam> get unlinkedParameters => serializedExecutable.parameters;
-
-  @override
-  List<UnlinkedTypeParam> get unlinkedTypeParams =>
-      serializedExecutable.typeParameters;
-
-  @override
-  bool isAccessibleIn(LibraryElement library) =>
-      !Identifier.isPrivateName(name) || identical(this.library, library);
-
-  /// Compute the default return type for this type of executable element (if no
-  /// return type is declared and strong mode type inference cannot infer a
-  /// better return type).
-  DartType _computeDefaultReturnType() {
-    var kind = serializedExecutable.kind;
-    var isMethod = kind == UnlinkedExecutableKind.functionOrMethod;
-    var isSetter = kind == UnlinkedExecutableKind.setter;
-    if ((isSetter || isMethod && serializedExecutable.name == '[]=')) {
-      // In strong mode, setters and `[]=` operators without an explicit
-      // return type are considered to return `void`.
-      return VoidTypeImpl.instance;
-    } else {
-      return DynamicTypeImpl.instance;
-    }
-  }
-}
-
-/// Base class for executable elements that are resynthesized from a summary
-/// during linking and are not local functions.
-abstract class ExecutableElementForLink_NonLocal
-    extends ExecutableElementForLink {
-  /// Return the class in which this executable appears, maybe `null` for a
-  /// top-level function.
-  final ClassMemberContainerForLink enclosingClass;
-
-  ExecutableElementForLink_NonLocal(
-      CompilationUnitElementForLink compilationUnit,
-      this.enclosingClass,
-      UnlinkedExecutable unlinkedExecutable)
-      : super(compilationUnit, unlinkedExecutable);
-
-  @override
-  Element get enclosingElement => enclosingClass ?? compilationUnit;
-
-  @override
-  TypeParameterizedElementMixin get enclosingTypeParameterContext =>
-      enclosingClass;
-
-  /// Store the results of type inference for this method in [compilationUnit].
-  void link(CompilationUnitElementInBuildUnit compilationUnit) {
-    if (serializedExecutable.returnType == null) {
-      compilationUnit._storeLinkedType(
-          serializedExecutable.inferredReturnTypeSlot,
-          inferredReturnType,
-          this);
-    }
-    for (ParameterElementForLink parameterElement in parameters) {
-      parameterElement.link(compilationUnit);
-    }
-  }
-}
-
-class ExprTypeComputer {
-  final ExprBuilder _builder;
-
-  final AstRewriteVisitor _astRewriteVisitor;
-
-  final ResolverVisitor _resolverVisitor;
-
-  final TypeResolverVisitor _typeResolverVisitor;
-
-  final VariableResolverVisitor _variableResolverVisitor;
-
-  final PartialResolverVisitor _partialResolverVisitor;
-
-  final Linker _linker;
-
-  FunctionElementForLink_Local _functionElement;
-
-  factory ExprTypeComputer(FunctionElementForLink_Local functionElement) {
-    ClassElement enclosingClass =
-        functionElement.getAncestor((e) => e is ClassElement);
-    CompilationUnitElementForLink unit = functionElement.compilationUnit;
-    LibraryElementForLink library = unit.enclosingElement;
-    Linker linker = library._linker;
-    TypeProvider typeProvider = linker.typeProvider;
-    var unlinkedExecutable = functionElement.serializedExecutable;
-    UnlinkedExpr unlinkedConst = unlinkedExecutable.bodyExpr;
-    var errorListener = AnalysisErrorListener.NULL_LISTENER;
-    var source = unit.source;
-    var astRewriteVisitor = new AstRewriteVisitor(
-        linker.typeSystem, library, source, typeProvider, errorListener);
-    EnclosedScope nameScope = new LibraryScope(library);
-    if (enclosingClass != null) {
-      nameScope = new ClassScope(
-          new TypeParameterScope(nameScope, enclosingClass), enclosingClass);
-    }
-    var inheritance = new InheritanceManager3(linker.typeSystem);
-    // Note: this is a bit of a hack; we ought to use the feature set for the
-    // compilation unit being analyzed, but that's not feasible because sumaries
-    // don't record the feature set.  This should be resolved when we switch to
-    // the "summary2" mechanism.
-    var featureSet = FeatureSet.fromEnableFlags([]);
-    var resolverVisitor = new ResolverVisitor(
-        inheritance, library, source, typeProvider, errorListener,
-        featureSet: featureSet,
-        nameScope: nameScope,
-        propagateTypes: false,
-        reportConstEvaluationErrors: false);
-    var typeResolverVisitor = new TypeResolverVisitor(
-        library, source, typeProvider, errorListener,
-        featureSet: featureSet, nameScope: nameScope);
-    var variableResolverVisitor = new VariableResolverVisitor(
-        library, source, typeProvider, errorListener,
-        nameScope: nameScope, localVariableInfo: LocalVariableInfo());
-    var partialResolverVisitor = new PartialResolverVisitor(
-        inheritance, library, source, typeProvider, errorListener, featureSet,
-        nameScope: nameScope);
-    return new ExprTypeComputer._(
-        unit._unitResynthesizer,
-        astRewriteVisitor,
-        resolverVisitor,
-        typeResolverVisitor,
-        variableResolverVisitor,
-        partialResolverVisitor,
-        linker,
-        errorListener,
-        functionElement,
-        unlinkedConst,
-        unlinkedExecutable.localFunctions);
-  }
-
-  ExprTypeComputer._(
-      UnitResynthesizer unitResynthesizer,
-      this._astRewriteVisitor,
-      this._resolverVisitor,
-      this._typeResolverVisitor,
-      this._variableResolverVisitor,
-      this._partialResolverVisitor,
-      this._linker,
-      AnalysisErrorListener _errorListener,
-      this._functionElement,
-      UnlinkedExpr unlinkedConst,
-      List<UnlinkedExecutable> localFunctions)
-      : _builder = new ExprBuilder(
-            unitResynthesizer, _functionElement, unlinkedConst,
-            requireValidConst: false,
-            localFunctions: localFunctions,
-            becomeSetOrMap: false);
-
-  TopLevelInferenceErrorKind get errorKind {
-    // TODO(paulberry): should we return TopLevelInferenceErrorKind.assignment
-    // sometimes?
-    return null;
-  }
-
-  DartType compute() {
-    Expression expression;
-    if (_linker.getAst != null) {
-      var expressionForInference = _functionElement._expressionForInference;
-      if (expressionForInference != null) {
-        expression = AstCloner().cloneNode(expressionForInference);
-        expression.accept(LocalElementBuilder(ElementHolder(), null));
-      }
-    } else if (_builder.hasNonEmptyExpr) {
-      expression = _builder.build();
-    }
-    if (expression == null) {
-      // No function body was stored for this function, so we can't infer its
-      // return type.  Assume `dynamic`.
-      return DynamicTypeImpl.instance;
-    }
-    var container =
-        astFactory.expressionFunctionBody(null, null, expression, null);
-    expression.accept(_astRewriteVisitor);
-    expression = container.expression;
-    if (_linker.getAst != null) {
-      expression.accept(_typeResolverVisitor);
-    }
-    expression.accept(_variableResolverVisitor);
-    if (_linker.getAst != null) {
-      expression.accept(_partialResolverVisitor);
-    }
-    expression.accept(_resolverVisitor);
-    return expression.staticType;
-  }
-}
-
-class ExtensionElementForLink
-    with ReferenceableElementForLink
-    implements ClassMemberContainerForLink, ExtensionElementImpl {
-  @override
-  final CompilationUnitElementForLink enclosingElement;
-
-  final UnlinkedExtension _unlinkedExtension;
-
-  Map<String, ReferenceableElementForLink> _containedNames;
-
-  List<PropertyAccessorElementForLink> _accessors;
-  List<FieldElementForLink_ClassField> _fields;
-  List<MethodElement> _methods;
-
-  ExtensionElementForLink(this.enclosingElement, this._unlinkedExtension);
-
-  @override
-  List<PropertyAccessorElementForLink> get accessors {
-    if (_accessors == null) {
-      _accessors = <PropertyAccessorElementForLink>[];
-      Map<String, SyntheticVariableElementForLink> syntheticVariables =
-          <String, SyntheticVariableElementForLink>{};
-      for (UnlinkedExecutable unlinkedExecutable
-          in _unlinkedExtension.executables) {
-        if (unlinkedExecutable.kind == UnlinkedExecutableKind.getter ||
-            unlinkedExecutable.kind == UnlinkedExecutableKind.setter) {
-          String name = unlinkedExecutable.name;
-          if (unlinkedExecutable.kind == UnlinkedExecutableKind.setter) {
-            assert(name.endsWith('='));
-            name = name.substring(0, name.length - 1);
-          }
-          SyntheticVariableElementForLink syntheticVariable = syntheticVariables
-              .putIfAbsent(name, () => new SyntheticVariableElementForLink());
-          PropertyAccessorElementForLink_Executable accessor =
-              new PropertyAccessorElementForLink_Executable(enclosingElement,
-                  this, unlinkedExecutable, syntheticVariable);
-          _accessors.add(accessor);
-          if (unlinkedExecutable.kind == UnlinkedExecutableKind.getter) {
-            syntheticVariable._getter = accessor;
-          } else {
-            syntheticVariable._setter = accessor;
-          }
-        }
-      }
-      for (FieldElementForLink_ClassField field in fields) {
-        _accessors.add(field.getter);
-        if (!field.isConst && !field.isFinal) {
-          _accessors.add(field.setter);
-        }
-      }
-    }
-    return _accessors;
-  }
-
-  @override
-  List<FieldElementForLink_ClassField> get fields {
-    if (_fields == null) {
-      _fields = <FieldElementForLink_ClassField>[];
-      for (int i = 0; i < _unlinkedExtension.fields.length; i++) {
-        var field = _unlinkedExtension.fields[i];
-        _fields.add(new FieldElementForLink_ClassField(this, field, null));
-      }
-    }
-    return _fields;
-  }
-
-  @override
-  List<MethodElement> get methods {
-    if (_methods == null) {
-      _methods = <MethodElementForLink>[];
-      for (UnlinkedExecutable unlinkedExecutable
-          in _unlinkedExtension.executables) {
-        if (unlinkedExecutable.kind ==
-            UnlinkedExecutableKind.functionOrMethod) {
-          _methods.add(new MethodElementForLink(this, unlinkedExecutable));
-        }
-      }
-    }
-    return _methods;
-  }
-
-  @override
-  String get name => _unlinkedExtension.name;
-
-  @override
-  ReferenceableElementForLink getContainedName(String name) {
-    if (_containedNames == null) {
-      _containedNames = <String, ReferenceableElementForLink>{};
-      // TODO(paulberry): what's the correct way to handle name conflicts?
-      for (PropertyAccessorElementForLink accessor in accessors) {
-        _containedNames[accessor.name] = accessor;
-      }
-      for (MethodElementForLink method in methods) {
-        _containedNames[method.name] = method;
-      }
-    }
-    return _containedNames.putIfAbsent(
-        name, () => UndefinedElementForLink.instance);
-  }
-
-  @override
-  PropertyAccessorElement getGetter(String getterName) {
-    for (PropertyAccessorElement accessor in accessors) {
-      if (accessor.isGetter && accessor.name == getterName) {
-        return accessor;
-      }
-    }
-    return null;
-  }
-
-  @override
-  MethodElement getMethod(String methodName) {
-    for (MethodElement method in methods) {
-      if (method.name == methodName) {
-        return method;
-      }
-    }
-    return null;
-  }
-
-  @override
-  PropertyAccessorElement getSetter(String setterName) =>
-      AbstractClassElementImpl.getSetterFromAccessors(setterName, accessors);
-
-  @override
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
-
-/// Element representing a field resynthesized from a summary during
-/// linking.
-abstract class FieldElementForLink implements FieldElement {
-  @override
-  PropertyAccessorElementForLink get getter;
-
-  @override
-  PropertyAccessorElementForLink get setter;
-}
-
-/// Specialization of [FieldElementForLink] for class fields.
-class FieldElementForLink_ClassField extends VariableElementForLink
-    implements FieldElementForLink {
-  @override
-  final ClassMemberContainerForLink enclosingElement;
-
-  /// If this is an instance field, the type that was computed by
-  /// [InstanceMemberInferrer] (if any).  Otherwise `null`.
-  DartType _inferredInstanceType;
-
-  TopLevelInferenceErrorBuilder _inferenceError;
-
-  FieldElementForLink_ClassField(ClassMemberContainerForLink enclosingElement,
-      UnlinkedVariable unlinkedVariable, Expression initializerForInference)
-      : enclosingElement = enclosingElement,
-        super(unlinkedVariable, enclosingElement.enclosingElement,
-            initializerForInference);
-
-  @override
-  bool get isLate => unlinkedVariable.isLate;
-
-  @override
-  bool get isStatic => unlinkedVariable.isStatic;
-
-  @override
-  DartType get type {
-    if (declaredType != null) {
-      return declaredType;
-    }
-    if (Linker._isPerformingVariableTypeInference && !isStatic) {
-      return DynamicTypeImpl.instance;
-    }
-    return inferredType;
-  }
-
-  @override
-  void set type(DartType inferredType) {
-    assert(!isStatic);
-    assert(_inferredInstanceType == null);
-    _inferredInstanceType = inferredType;
-  }
-
-  @override
-  TypeParameterizedElementMixin get _typeParameterContext => enclosingElement;
-
-  /// Store the results of type inference for this field in
-  /// [compilationUnit].
-  void link(CompilationUnitElementInBuildUnit compilationUnit) {
-    if (hasImplicitType) {
-      compilationUnit._storeLinkedType(
-          unlinkedVariable.inferredTypeSlot,
-          isStatic ? inferredType : _inferredInstanceType,
-          _typeParameterContext);
-      compilationUnit._storeLinkedTypeError(
-          unlinkedVariable.inferredTypeSlot, _inferenceError);
-      if (initializer != null) {
-        compilationUnit._storeLinkedTypeError(
-            unlinkedVariable.inferredTypeSlot, initializer._inferenceError);
-        initializer.link(compilationUnit);
-      }
-    }
-  }
-
-  void setInferenceError(TopLevelInferenceErrorBuilder error) {
-    assert(_inferenceError == null);
-    _inferenceError = error;
-  }
-
-  @override
-  String toString() => '$enclosingElement.$name';
-}
-
-/// Specialization of [FieldElementForLink] for enum fields.
-class FieldElementForLink_EnumField extends FieldElementForLink
-    implements FieldElement {
-  PropertyAccessorElementForLink_EnumField _getter;
-
-  @override
-  final ClassElementForLink_Enum enclosingElement;
-
-  FieldElementForLink_EnumField(this.enclosingElement);
-
-  @override
-  PropertyAccessorElementForLink_EnumField get getter =>
-      _getter ??= new PropertyAccessorElementForLink_EnumField(this);
-
-  @override
-  bool get isSynthetic => false;
-
-  @override
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-
-  @override
-  String toString() => '$enclosingElement.$name';
-}
-
-/// Specialization of [FieldElementForLink] for the 'index' enum field.
-class FieldElementForLink_EnumField_index
-    extends FieldElementForLink_EnumField {
-  FieldElementForLink_EnumField_index(ClassElementForLink_Enum enclosingElement)
-      : super(enclosingElement);
-
-  @override
-  bool get isStatic => false;
-
-  @override
-  String get name => 'index';
-
-  @override
-  DartType get type =>
-      enclosingElement.enclosingElement.library._linker.typeProvider.intType;
-}
-
-/// Specialization of [FieldElementForLink] for enum fields.
-class FieldElementForLink_EnumField_value
-    extends FieldElementForLink_EnumField {
-  /// The unlinked representation of the field in the summary.
-  final UnlinkedEnumValue unlinkedEnumValue;
-
-  FieldElementForLink_EnumField_value(
-      ClassElementForLink_Enum enclosingElement, this.unlinkedEnumValue)
-      : super(enclosingElement);
-
-  @override
-  bool get isStatic => true;
-
-  @override
-  String get name => unlinkedEnumValue.name;
-
-  @override
-  DartType get type => enclosingElement.type;
-}
-
-/// Specialization of [FieldElementForLink] for the 'values' enum field.
-class FieldElementForLink_EnumField_values
-    extends FieldElementForLink_EnumField {
-  FieldElementForLink_EnumField_values(
-      ClassElementForLink_Enum enclosingElement)
-      : super(enclosingElement);
-
-  @override
-  bool get isStatic => true;
-
-  @override
-  String get name => 'values';
-
-  @override
-  DartType get type => enclosingElement.valuesType;
-}
-
-class FieldFormalParameterElementForLink extends ParameterElementForLink
-    implements FieldFormalParameterElement {
-  FieldElement _field;
-  DartType _type;
-
-  FieldFormalParameterElementForLink(
-      ParameterParentElementForLink enclosingElement,
-      UnlinkedParam unlinkedParam,
-      TypeParameterizedElementMixin typeParameterContext,
-      CompilationUnitElementForLink compilationUnit,
-      int parameterIndex)
-      : super(enclosingElement, unlinkedParam, typeParameterContext,
-            compilationUnit, parameterIndex);
-
-  @override
-  FieldElement get field {
-    if (_field == null) {
-      Element enclosingConstructor = enclosingElement;
-      if (enclosingConstructor is ConstructorElement) {
-        Element enclosingClass = enclosingConstructor.enclosingElement;
-        if (enclosingClass is ClassElement) {
-          FieldElement field = enclosingClass.getField(unlinkedParam.name);
-          if (field != null && !field.isSynthetic) {
-            _field = field;
-          }
-        }
-      }
-    }
-    return _field;
-  }
-
-  @override
-  bool get isInitializingFormal => true;
-
-  @override
-  DartType get type {
-    return _type ??= field?.type ?? DynamicTypeImpl.instance;
-  }
-}
-
-/// Element representing a function-typed parameter resynthesied from a summary
-/// during linking.
-class FunctionElementForLink_FunctionTypedParam
-    with ParameterParentElementForLink
-    implements FunctionElement {
-  @override
-  final ParameterElementForLink enclosingElement;
-
-  @override
-  final TypeParameterizedElementMixin typeParameterContext;
-
-  @override
-  final List<UnlinkedParam> unlinkedParameters;
-
-  DartType _returnType;
-  List<int> _implicitFunctionTypeIndices;
-
-  FunctionElementForLink_FunctionTypedParam(this.enclosingElement,
-      this.typeParameterContext, this.unlinkedParameters);
-
-  @override
-  List<int> get implicitFunctionTypeIndices {
-    if (_implicitFunctionTypeIndices == null) {
-      _implicitFunctionTypeIndices = enclosingElement
-          .enclosingElement.implicitFunctionTypeIndices
-          .toList();
-      _implicitFunctionTypeIndices.add(enclosingElement._parameterIndex);
-    }
-    return _implicitFunctionTypeIndices;
-  }
-
-  @override
-  bool get isSynthetic => true;
-
-  @override
-  DartType get returnType {
-    if (_returnType == null) {
-      if (enclosingElement.unlinkedParam.type == null) {
-        _returnType = DynamicTypeImpl.instance;
-      } else {
-        _returnType = enclosingElement.compilationUnit.resolveTypeRef(
-            enclosingElement, enclosingElement.unlinkedParam.type);
-      }
-    }
-    return _returnType;
-  }
-
-  @override
-  List<TypeParameterElement> get typeParameters => const [];
-
-  @override
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
-
-/// Element representing the initializer expression of a variable.
-class FunctionElementForLink_Initializer
-    with ReferenceableElementForLink, TypeParameterizedElementMixin
-    implements FunctionElementForLink_Local {
-  /// The variable for which this element is the initializer.
-  final VariableElementForLink _variable;
-
-  @override
-  final Expression _expressionForInference;
-
-  /// The type inference node for this function, or `null` if it hasn't been
-  /// computed yet.
-  TypeInferenceNode _typeInferenceNode;
-
-  List<FunctionElementForLink_Local_NonSynthetic> _functions;
-  DartType _inferredReturnType;
-  TopLevelInferenceErrorBuilder _inferenceError;
-
-  FunctionElementForLink_Initializer(
-      this._variable, this._expressionForInference);
-
-  @override
-  TypeInferenceNode get asTypeInferenceNode =>
-      _typeInferenceNode ??= new TypeInferenceNode(this);
-
-  @override
-  CompilationUnitElementForLink get compilationUnit =>
-      _variable.compilationUnit;
-
-  @override
-  VariableElementForLink get enclosingElement => _variable;
-
-  TypeParameterizedElementMixin get enclosingTypeParameterContext =>
-      _variable.enclosingElement is ClassElementForLink
-          ? _variable.enclosingElement
-          : null;
-
-  @override
-  CompilationUnitElementForLink get enclosingUnit => _variable.compilationUnit;
-
-  @override
-  List<FunctionElementForLink_Local_NonSynthetic> get functions =>
-      _functions ??= _computeFunctions();
-
-  @override
-  String get identifier => '';
-
-  @override
-  bool get isAsynchronous => serializedExecutable.isAsynchronous;
-
-  @override
-  get linkedNode => null;
-
-  @override
-  DartType get returnType {
-    // If this is a variable whose type needs inferring, infer it.
-    if (_variable.hasImplicitType) {
-      return _variable.inferredType;
-    } else {
-      // There's no reason linking should need to access the type of
-      // this FunctionElement, since the variable doesn't need its
-      // type inferred.
-      assert(false);
-      // But for robustness, return the dynamic type.
-      return DynamicTypeImpl.instance;
-    }
-  }
-
-  @override
-  void set returnType(DartType newType) {
-    // InstanceMemberInferrer stores the new type both here and on the variable
-    // element.  We don't need to record both values, so we ignore it here.
-  }
-
-  @override
-  UnlinkedExecutable get serializedExecutable =>
-      _variable.unlinkedVariable.initializer;
-
-  @override
-  TypeParameterizedElementMixin get typeParameterContext => this;
-
-  @override
-  List<UnlinkedTypeParam> get unlinkedTypeParams => const [];
-
-  @override
-  bool get _hasTypeBeenInferred => _inferredReturnType != null;
-
-  @override
-  E getAncestor<E extends Element>(Predicate<Element> predicate) {
-    return ElementImpl.getAncestorStatic(enclosingElement, predicate);
-  }
-
-  @override
-  FunctionElementForLink_Local getLocalFunction(int index) {
-    List<FunctionElementForLink_Local_NonSynthetic> functions = this.functions;
-    return index < functions.length ? functions[index] : null;
-  }
-
-  /// Store the results of type inference for this initializer in
-  /// [compilationUnit].
-  void link(CompilationUnitElementInBuildUnit compilationUnit) {
-    compilationUnit._storeLinkedType(
-        serializedExecutable.inferredReturnTypeSlot,
-        _inferredReturnType,
-        typeParameterContext);
-    for (FunctionElementForLink_Local_NonSynthetic function in functions) {
-      function.link(compilationUnit);
-    }
-  }
-
-  @override
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-
-  @override
-  String toString() => _variable.toString();
-
-  List<FunctionElementForLink_Local_NonSynthetic> _computeFunctions() {
-    var localFunctionsFromSummary =
-        _variable.unlinkedVariable.initializer.localFunctions;
-    var count = localFunctionsFromSummary.length;
-    var result = List<FunctionElementForLink_Local_NonSynthetic>(count);
-    for (int i = 0; i < count; i++) {
-      result[i] = FunctionElementForLink_Local_NonSynthetic(
-          _variable.compilationUnit,
-          this,
-          localFunctionsFromSummary[i],
-          i == 0 ? _expressionForInference : null);
-    }
-    return result;
-  }
-
-  @override
-  void _setInferenceError(TopLevelInferenceErrorBuilder error) {
-    assert(!_hasTypeBeenInferred);
-    _inferenceError = error;
-  }
-
-  @override
-  void _setInferredType(DartType type) {
-    assert(!_hasTypeBeenInferred);
-    _inferredReturnType = type;
-    _variable._inferredType = _dynamicIfNull(type);
-  }
-}
-
-/// Element representing a local function (possibly a closure).
-abstract class FunctionElementForLink_Local
-    implements
-        ExecutableElementForLink,
-        FunctionElementImpl,
-        ReferenceableElementForLink {
-  /// If this function element represents the initializer of a field or a
-  /// top-level variable, returns the AST for the initializer expression; this
-  /// is used for inferring the expression type.
-  Expression get _expressionForInference;
-
-  /// Indicates whether type inference has completed for this function.
-  bool get _hasTypeBeenInferred;
-
-  /// Stores the given [error] as the type inference error for this function.
-  /// Should only be called if [_hasTypeBeenInferred] is `false`.
-  void _setInferenceError(TopLevelInferenceErrorBuilder error);
-
-  /// Stores the given [type] as the inferred return type for this function.
-  /// Should only be called if [_hasTypeBeenInferred] is `false`.
-  void _setInferredType(DartType type);
-}
-
-/// Element representing a local function (possibly a closure) inside another
-/// executable.
-class FunctionElementForLink_Local_NonSynthetic extends ExecutableElementForLink
-    with ReferenceableElementForLink
-    implements FunctionElementForLink_Local {
-  @override
-  final ExecutableElementForLink enclosingElement;
-
-  @override
-  final Expression _expressionForInference;
-
-  List<FunctionElementForLink_Local_NonSynthetic> _functions;
-
-  /// The type inference node for this function, or `null` if it hasn't been
-  /// computed yet.
-  TypeInferenceNode _typeInferenceNode;
-
-  FunctionElementForLink_Local_NonSynthetic(
-      CompilationUnitElementForLink compilationUnit,
-      this.enclosingElement,
-      UnlinkedExecutable unlinkedExecutable,
-      this._expressionForInference)
-      : super(compilationUnit, unlinkedExecutable);
-
-  @override
-  TypeInferenceNode get asTypeInferenceNode =>
-      _typeInferenceNode ??= new TypeInferenceNode(this);
-
-  @override
-  TypeParameterizedElementMixin get enclosingTypeParameterContext =>
-      enclosingElement;
-
-  @override
-  List<FunctionElementForLink_Local_NonSynthetic> get functions =>
-      _functions ??= serializedExecutable.localFunctions
-          .map((UnlinkedExecutable ex) =>
-              new FunctionElementForLink_Local_NonSynthetic(
-                  compilationUnit, this, ex, null))
-          .toList();
-
-  @override
-  String get identifier {
-    String identifier = serializedExecutable.name;
-    Element enclosing = this.enclosingElement;
-    if (enclosing is ExecutableElementForLink) {
-      int id =
-          ElementImpl.findElementIndexUsingIdentical(enclosing.functions, this);
-      identifier += "@$id";
-    }
-    return identifier;
-  }
-
-  @override
-  bool get isAsynchronous => serializedExecutable.isAsynchronous;
-
-  @override
-  bool get _hasTypeBeenInferred => _inferredReturnType != null;
-
-  @override
-  DartType buildType(
-      DartType getTypeArgument(int i), List<int> implicitFunctionTypeIndices) {
-    assert(implicitFunctionTypeIndices.isEmpty);
-    return type;
-  }
-
-  @override
-  E getAncestor<E extends Element>(Predicate<Element> predicate) {
-    return ElementImpl.getAncestorStatic(enclosingElement, predicate);
-  }
-
-  @override
-  FunctionElementForLink_Local getLocalFunction(int index) {
-    List<FunctionElementForLink_Local_NonSynthetic> functions = this.functions;
-    return index < functions.length ? functions[index] : null;
-  }
-
-  /// Store the results of type inference for this function in
-  /// [compilationUnit].
-  void link(CompilationUnitElementInBuildUnit compilationUnit) {
-    if (serializedExecutable.returnType == null) {
-      compilationUnit._storeLinkedType(
-          serializedExecutable.inferredReturnTypeSlot,
-          inferredReturnType,
-          this);
-    }
-    for (FunctionElementForLink_Local_NonSynthetic function in functions) {
-      function.link(compilationUnit);
-    }
-  }
-
-  @override
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-
-  @override
-  String toString() => enclosingElement.toString();
-
-  @override
-  void _setInferenceError(TopLevelInferenceErrorBuilder error) {}
-
-  @override
-  void _setInferredType(DartType type) {
-    // TODO(paulberry): store the inferred return type in the summary.
-    assert(!_hasTypeBeenInferred);
-    _inferredReturnType = _dynamicIfBottom(type);
-  }
-}
-
-/// Synthetic function element which is created for local functions.
-class FunctionElementForLink_Synthetic extends ExecutableElementForLink
-    with ReferenceableElementForLink
-    implements FunctionElementForLink_Local {
-  @override
-  final Element enclosingElement;
-
-  final EntityRef _entityRef;
-
-  FunctionElementForLink_Synthetic(
-      CompilationUnitElementForLink compilationUnit,
-      this.enclosingElement,
-      this._entityRef)
-      : super(compilationUnit, null);
-
-  @override
-  TypeParameterizedElementMixin get enclosingTypeParameterContext {
-    if (enclosingElement is TypeParameterizedElementMixin) {
-      return enclosingElement;
-    }
-    return null;
-  }
-
-  @override
-  DartType get returnType {
-    return _declaredReturnType ??= enclosingUnit.resynthesizerContext
-        .resolveTypeRef(this, _entityRef.syntheticReturnType);
-  }
-
-  @override
-  List<UnlinkedParam> get unlinkedParameters => _entityRef.syntheticParams;
-
-  @override
-  List<UnlinkedTypeParam> get unlinkedTypeParams => _entityRef.typeParameters;
-
-  @override
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
-
-/// Element representing a typedef resynthesized from a summary during linking.
-class FunctionTypeAliasElementForLink
-    with
-        TypeParameterizedElementMixin,
-        ParameterParentElementForLink,
-        ReferenceableElementForLink,
-        SimplyBoundableForLinkMixin
-    implements FunctionTypeAliasElement, ElementImpl {
-  @override
-  final CompilationUnitElementForLink enclosingElement;
-
-  /// The unlinked representation of the typedef in the summary.
-  final UnlinkedTypedef _unlinkedTypedef;
-
-  FunctionTypeImpl _type;
-  DartType _returnType;
-  GenericFunctionTypeElementForLink _function;
-
-  FunctionTypeAliasElementForLink(
-      this.enclosingElement, this._unlinkedTypedef) {
-    _initSimplyBoundable();
-  }
-
-  @override
-  DartType get asStaticType {
-    return enclosingElement.enclosingElement._linker.typeProvider.typeType;
-  }
-
-  @override
-  ContextForLink get context => enclosingElement.context;
-
-  @override
-  TypeParameterizedElementMixin get enclosingTypeParameterContext => null;
-
-  @override
-  CompilationUnitElementForLink get enclosingUnit => enclosingElement;
-
-  @override
-  GenericFunctionTypeElementImpl get function =>
-      _function ??= new GenericFunctionTypeElementForLink(enclosingUnit, this,
-          const [], _unlinkedTypedef.returnType, _unlinkedTypedef.parameters);
-
-  @override
-  String get identifier => _unlinkedTypedef.name;
-
-  @override
-  List<int> get implicitFunctionTypeIndices => const <int>[];
-
-  @override
-  bool get isSynthetic => false;
-
-  @override
-  LibraryElementForLink get library => enclosingElement.library;
-
-  @override
-  get linkedNode => null;
-
-  @override
-  String get name => _unlinkedTypedef.name;
-
-  @override
-  DartType get returnType => _returnType ??=
-      enclosingElement.resolveTypeRef(this, _unlinkedTypedef.returnType);
-
-  @override
-  AnalysisSession get session => enclosingElement.session;
-
-  @override
-  TypeParameterizedElementMixin get typeParameterContext => this;
-
-  @override
-  List<UnlinkedParam> get unlinkedParameters => _unlinkedTypedef.parameters;
-
-  @override
-  List<UnlinkedTypeParam> get unlinkedTypeParams =>
-      _unlinkedTypedef.typeParameters;
-
-  @override
-  int get _notSimplyBoundedSlot => _unlinkedTypedef.notSimplyBoundedSlot;
-
-  @override
-  List<EntityRef> get _rhsTypesForSimplyBoundable =>
-      _collectTypedefRhsTypes(_unlinkedTypedef);
-
-  @override
-  List<UnlinkedTypeParam> get _typeParametersForSimplyBoundable =>
-      _unlinkedTypedef.typeParameters;
-
-  @override
-  DartType buildType(
-      DartType getTypeArgument(int i), List<int> implicitFunctionTypeIndices) {
-    int numTypeParameters = _unlinkedTypedef.typeParameters.length;
-    if (numTypeParameters != 0) {
-      List<DartType> typeArguments =
-          new List<DartType>.generate(numTypeParameters, getTypeArgument);
-      if (typeArguments.contains(null)) {
-        return context.typeSystem
-            .instantiateToBounds(new FunctionTypeImpl.forTypedef(this));
-      } else {
-        return GenericTypeAliasElementImpl.doInstantiate(this, typeArguments);
-      }
-    } else {
-      return _type ??= new FunctionTypeImpl.forTypedef(this);
-    }
-  }
-
-  void link(CompilationUnitElementInBuildUnit compilationUnit) {
-    _linkSimplyBoundable();
-  }
-
-  @override
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-
-  @override
-  String toString() => '$enclosingElement.$name';
-}
-
-/// Element representing a generic function resynthesized from a summary during
-/// linking.
-class GenericFunctionTypeElementForLink
-    with
-        TypeParameterizedElementMixin,
-        ParameterParentElementForLink,
-        ReferenceableElementForLink
-    implements GenericFunctionTypeElementImpl, ElementImpl {
-  @override
-  final CompilationUnitElementForLink enclosingUnit;
-
-  @override
-  final ElementImpl enclosingElement;
-
-  @override
-  final List<UnlinkedTypeParam> unlinkedTypeParams;
-
-  /// The representation of the generic function's return type in the summary.
-  final EntityRef _unlinkedReturnType;
-
-  @override
-  final List<UnlinkedParam> unlinkedParameters;
-
-  DartType _returnType;
-  FunctionTypeImpl _type;
-
-  GenericFunctionTypeElementForLink(
-      this.enclosingUnit,
-      this.enclosingElement,
-      this.unlinkedTypeParams,
-      this._unlinkedReturnType,
-      this.unlinkedParameters);
-
-  @override
-  DartType get asStaticType {
-    return enclosingUnit.enclosingElement._linker.typeProvider.typeType;
-  }
-
-  @override
-  ContextForLink get context => enclosingElement.context;
-
-  @override
-  TypeParameterizedElementMixin get enclosingTypeParameterContext {
-    return enclosingElement.typeParameterContext;
-  }
-
-  @override
-  String get identifier => name;
-
-  @override
-  List<int> get implicitFunctionTypeIndices => const <int>[];
-
-  @override
-  bool get isSynthetic => false;
-
-  @override
-  LibraryElementForLink get library => enclosingElement.library;
-
-  @override
-  get linkedNode => null;
-
-  @override
-  String get name => '-';
-
-  @override
-  DartType get returnType =>
-      _returnType ??= enclosingUnit.resolveTypeRef(this, _unlinkedReturnType);
-
-  @override
-  AnalysisSession get session => enclosingElement.session;
-
-  @override
-  FunctionType get type {
-    return _type ??= new FunctionTypeImpl(this);
-  }
-
-  @override
-  TypeParameterizedElementMixin get typeParameterContext => this;
-
-  @override
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-
-  @override
-  String toString() => '$enclosingElement.$name';
-}
-
-/// Element representing a generic typedef resynthesized from a summary during
-/// linking.
-class GenericTypeAliasElementForLink
-    with
-        TypeParameterizedElementMixin,
-        ParameterParentElementForLink,
-        ReferenceableElementForLink,
-        SimplyBoundableForLinkMixin
-    implements FunctionTypeAliasElementForLink, GenericTypeAliasElementImpl {
-  @override
-  final CompilationUnitElementForLink enclosingElement;
-
-  /// The unlinked representation of the typedef in the summary.
-  final UnlinkedTypedef _unlinkedTypedef;
-
-  GenericFunctionTypeElementForLink _function;
-
-  GenericTypeAliasElementForLink(this.enclosingElement, this._unlinkedTypedef) {
-    _initSimplyBoundable();
-  }
-
-  @override
-  DartType get asStaticType {
-    return enclosingElement.enclosingElement._linker.typeProvider.typeType;
-  }
-
-  @override
-  ContextForLink get context => enclosingElement.context;
-
-  @override
-  TypeParameterizedElementMixin get enclosingTypeParameterContext => null;
-
-  @override
-  CompilationUnitElementForLink get enclosingUnit => enclosingElement;
-
-  @override
-  GenericFunctionTypeElementImpl get function {
-    var unlinkedType = _unlinkedTypedef.returnType;
-    return _function ??= new GenericFunctionTypeElementForLink(
-        enclosingUnit,
-        this,
-        unlinkedType.typeParameters,
-        unlinkedType.syntheticReturnType,
-        unlinkedType.syntheticParams);
-  }
-
-  @override
-  String get identifier => _unlinkedTypedef.name;
-
-  @override
-  List<int> get implicitFunctionTypeIndices => const <int>[];
-
-  @override
-  bool get isSynthetic => false;
-
-  @override
-  LibraryElementForLink get library => enclosingElement.library;
-
-  @override
-  get linkedNode => null;
-
-  @override
-  String get name => _unlinkedTypedef.name;
-
-  @override
-  DartType get returnType => enclosingElement.resolveTypeRef(
-      this, _unlinkedTypedef.returnType.syntheticReturnType);
-
-  @override
-  AnalysisSession get session => enclosingElement.session;
-
-  @override
-  TypeParameterizedElementMixin get typeParameterContext => this;
-
-  @override
-  List<UnlinkedParam> get unlinkedParameters =>
-      _unlinkedTypedef.returnType.syntheticParams;
-
-  @override
-  List<UnlinkedTypeParam> get unlinkedTypeParams {
-    var result = _unlinkedTypedef.typeParameters.toList();
-    result.addAll(_unlinkedTypedef.returnType.typeParameters);
-    return result;
-  }
-
-  @override
-  int get _notSimplyBoundedSlot => _unlinkedTypedef.notSimplyBoundedSlot;
-
-  @override
-  List<EntityRef> get _rhsTypesForSimplyBoundable =>
-      _collectTypedefRhsTypes(_unlinkedTypedef);
-
-  @override
-  List<UnlinkedTypeParam> get _typeParametersForSimplyBoundable =>
-      _unlinkedTypedef.typeParameters;
-
-  @override
-  DartType buildType(
-      DartType getTypeArgument(int i), List<int> implicitFunctionTypeIndices) {
-    int numTypeParameters = _unlinkedTypedef.typeParameters.length;
-    if (numTypeParameters != 0) {
-      List<DartType> typeArguments =
-          new List<DartType>.generate(numTypeParameters, getTypeArgument);
-      if (typeArguments.contains(null)) {
-        return context.typeSystem
-            .instantiateToBounds(new FunctionTypeImpl.forTypedef(this));
-      } else {
-        return GenericTypeAliasElementImpl.doInstantiate(this, typeArguments);
-      }
-    } else {
-      return new FunctionTypeImpl.forTypedef(this);
-    }
-  }
-
-  void link(CompilationUnitElementInBuildUnit compilationUnit) {
-    _linkSimplyBoundable();
-  }
-
-  @override
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-
-  @override
-  String toString() => '$enclosingElement.$name';
-}
-
-/// Context for serializing a possibly generic function type that is used in
-/// another context.
-class InlineFunctionTypeParameterContext
-    implements TypeParameterSerializationContext {
-  final GenericFunctionTypeElementImpl _functionTypeElement;
-
-  final TypeParameterSerializationContext _usageContext;
-
-  InlineFunctionTypeParameterContext(
-      this._functionTypeElement, this._usageContext);
-
-  @override
-  int computeDeBruijnIndex(TypeParameterElement typeParameter,
-      {int offset: 0}) {
-    var typeFormals = _functionTypeElement.typeParameters;
-    var numTypeFormals = typeFormals.length;
-    for (int i = 0; i < numTypeFormals; i++) {
-      if (typeFormals[i] == typeParameter) return i + offset + 1;
-    }
-    return _usageContext.computeDeBruijnIndex(typeParameter,
-        offset: offset + numTypeFormals);
-  }
-}
-
-/// Specialization of [DependencyWalker] for linking library cycles.
-class LibraryCycleDependencyWalker extends DependencyWalker<LibraryCycleNode> {
-  @override
-  void evaluate(LibraryCycleNode v) {
-    v.link();
-  }
-
-  @override
-  void evaluateScc(List<LibraryCycleNode> scc) {
-    // There should never be a cycle among library cycles.
-    throw new StateError('Cycle among library cycles');
-  }
-}
-
-/// An instance of [LibraryCycleForLink] represents a single library cycle
-/// discovered during linking; it consists of one or more libraries in the build
-/// unit being linked.
-class LibraryCycleForLink {
-  /// The libraries in the cycle.
-  final List<LibraryElementInBuildUnit> libraries;
-
-  /// The library cycles which this library depends on.
-  final List<LibraryCycleForLink> dependencies;
-
-  /// The [LibraryCycleNode] for this library cycle.
-  LibraryCycleNode _node;
-
-  LibraryCycleForLink(this.libraries, this.dependencies) {
-    _node = new LibraryCycleNode(this);
-  }
-
-  LibraryCycleNode get node => _node;
-
-  /// Link this library cycle and any library cycles it depends on.  Does
-  /// nothing if this library cycle has already been linked.
-  void ensureLinked() {
-    if (!node.isEvaluated) {
-      new LibraryCycleDependencyWalker().walk(node);
-    }
-  }
-}
-
-/// Specialization of [Node] used to link library cycles in proper dependency
-/// order.
-class LibraryCycleNode extends Node<LibraryCycleNode> {
-  /// The library cycle this [Node] represents.
-  final LibraryCycleForLink libraryCycle;
-
-  /// Indicates whether this library cycle has been linked yet.
-  bool _isLinked = false;
-
-  LibraryCycleNode(this.libraryCycle);
-
-  @override
-  bool get isEvaluated => _isLinked;
-
-  @override
-  List<LibraryCycleNode> computeDependencies() => libraryCycle.dependencies
-      .map((LibraryCycleForLink cycle) => cycle.node)
-      .toList();
-
-  /// Link this library cycle.
-  void link() {
-    for (LibraryElementInBuildUnit library in libraryCycle.libraries) {
-      library.link();
-    }
-    _isLinked = true;
-  }
-}
-
-/// Specialization of [DependencyWalker] for computing library cycles.
-class LibraryDependencyWalker extends DependencyWalker<LibraryNode> {
-  @override
-  void evaluate(LibraryNode v) => evaluateScc(<LibraryNode>[v]);
-
-  @override
-  void evaluateScc(List<LibraryNode> scc) {
-    Set<LibraryCycleForLink> dependentCycles = new Set<LibraryCycleForLink>();
-    for (LibraryNode node in scc) {
-      for (LibraryNode dependency in Node.getDependencies(node)) {
-        if (dependency.isEvaluated) {
-          dependentCycles.add(dependency._libraryCycle);
-        }
-      }
-    }
-    LibraryCycleForLink cycle = new LibraryCycleForLink(
-        scc.map((LibraryNode n) => n.library).toList(),
-        dependentCycles.toList());
-    for (LibraryNode node in scc) {
-      node._libraryCycle = cycle;
-    }
-  }
-}
-
-/// Element representing a library resynthesied from a summary during
-/// linking.  The type parameter, [UnitElement], represents the type
-/// that will be used for the compilation unit elements.
-abstract class LibraryElementForLink<
-        UnitElement extends CompilationUnitElementForLink>
-    extends LibraryResynthesizerContextMixin implements LibraryElementImpl {
-  final _LibraryResynthesizer resynthesizer;
-
-  /// Pointer back to the linker.
-  final Linker _linker;
-
-  /// The absolute URI of this library.
-  final Uri _absoluteUri;
-
-  List<UnitElement> _units;
-  List<UnitElement> _parts;
-  final Map<String, ReferenceableElementForLink> _containedNames =
-      <String, ReferenceableElementForLink>{};
-  final List<LibraryElementForLink> _dependencies = <LibraryElementForLink>[];
-  UnlinkedUnit _unlinkedDefiningUnit;
-  List<LibraryElementForLink> _importedLibraries;
-  List<LibraryElementForLink> _exportedLibraries;
-
-  Namespace _exportNamespace;
-
-  Namespace _publicNamespace;
-
-  FunctionElement _loadLibraryFunction;
-
-  LibraryElementForLink(this._linker, this._absoluteUri)
-      : resynthesizer = new _LibraryResynthesizer() {
-    resynthesizer._library = this;
-    if (_linkedLibrary != null) {
-      _dependencies.length = _linkedLibrary.dependencies.length;
-    }
-  }
-
-  @override
-  ContextForLink get context => _linker.context;
-
-  @override
-  UnitElement get definingCompilationUnit => units[0];
-
-  @override
-  Element get enclosingElement => null;
-
-  @override
-  List<LibraryElementForLink> get exportedLibraries =>
-      _exportedLibraries ??= _linkedLibrary.exportDependencies
-          .map(buildImportedLibrary)
-          .where((library) => library != null)
-          .toList();
-
-  @override
-  Namespace get exportNamespace =>
-      _exportNamespace ??= resynthesizerContext.buildExportNamespace();
-
-  @override
-  String get identifier => _absoluteUri.toString();
-
-  @override
-  List<LibraryElementForLink> get importedLibraries => _importedLibraries ??=
-      _linkedLibrary.importDependencies.map(buildImportedLibrary).toList();
-
-  @override
-  bool get isDartAsync => _absoluteUri.toString() == 'dart:async';
-
-  @override
-  bool get isDartCore => _absoluteUri.toString() == 'dart:core';
-
-  @override
-  bool get isInSdk => _absoluteUri.scheme == 'dart';
-
-  @override
-  bool get isNonNullableByDefault => _unlinkedDefiningUnit.isNNBD;
-
-  @override
-  bool get isSynthetic => _linkedLibrary == null;
-
-  /// If this library is part of the build unit being linked, return the library
-  /// cycle it is part of.  Otherwise return `null`.
-  LibraryCycleForLink get libraryCycleForLink;
-
-  @override
-  FunctionElement get loadLibraryFunction => _loadLibraryFunction ??=
-      LibraryElementImpl.createLoadLibraryFunctionForLibrary(
-          _linker.typeProvider, this);
-
-  @override
-  String get name {
-    return _unlinkedDefiningUnit.libraryName;
-  }
-
-  List<UnitElement> get parts => _parts ??= units.sublist(1);
-
-  @override
-  Namespace get publicNamespace =>
-      _publicNamespace ??= resynthesizerContext.buildPublicNamespace();
-
-  @override
-  LibraryResynthesizerContext get resynthesizerContext => this;
-
-  @override
-  AnalysisSession get session => _linker.session;
-
-  @override
-  Source get source => definingCompilationUnit.source;
-
-  @override
-  List<UnitElement> get units {
-    if (_units == null) {
-      UnlinkedUnit definingUnit = unlinkedDefiningUnit;
-      _units = <UnitElement>[
-        _makeUnitElement(definingUnit, 0, _absoluteUri.toString())
-      ];
-      int numParts = definingUnit.parts.length;
-      for (int i = 0; i < numParts; i++) {
-        String partRelativeUriStr = definingUnit.publicNamespace.parts[i];
-
-        if (partRelativeUriStr.isEmpty) {
-          continue;
-        }
-
-        Uri partRelativeUri;
-        try {
-          partRelativeUri = Uri.parse(partRelativeUriStr);
-        } on FormatException {
-          continue;
-        }
-
-        String partAbsoluteUri =
-            resolveRelativeUri(_absoluteUri, partRelativeUri).toString();
-        UnlinkedUnit partUnit = _linker.getUnit(partAbsoluteUri);
-        _units.add(_makeUnitElement(
-            partUnit ?? new UnlinkedUnitBuilder(), i + 1, partAbsoluteUri));
-      }
-    }
-    return _units;
-  }
-
-  @override
-  UnlinkedUnit get unlinkedDefiningUnit => _unlinkedDefiningUnit ??=
-      _linker.getUnit(_absoluteUri.toString()) ?? new UnlinkedUnitBuilder();
-
-  List<LinkedExportName> get _linkedExportNames =>
-      _linkedLibrary == null ? [] : _linkedLibrary.exportNames;
-
-  /// The linked representation of the library in the summary.
-  LinkedLibrary get _linkedLibrary;
-
-  /// Return the [LibraryElement] corresponding to the given dependency [index].
-  LibraryElementForLink buildImportedLibrary(int index) {
-    LibraryElementForLink result = _dependencies[index];
-    if (result == null) {
-      Uri uri;
-      String uriStr = _linkedLibrary.dependencies[index].uri;
-      if (uriStr.isEmpty) {
-        uri = _absoluteUri;
-      } else {
-        try {
-          uri = Uri.parse(uriStr);
-        } on FormatException {
-          return null;
-        }
-      }
-
-      result = _linker.getLibrary(uri);
-      _dependencies[index] = result;
-    }
-    return result;
-  }
-
-  /// Search all the units for a top level element with the given
-  /// [name].  If no name is found, return the singleton instance of
-  /// [UndefinedElementForLink].
-  ReferenceableElementForLink getContainedName(String name) =>
-      _containedNames.putIfAbsent(name, () {
-        for (UnitElement unit in units) {
-          ReferenceableElementForLink element = unit.getContainedName(name);
-          if (!identical(element, UndefinedElementForLink.instance)) {
-            return element;
-          }
-        }
-        return UndefinedElementForLink.instance;
-      });
-
-  @override
-  List<ImportElement> getImportsWithPrefix(PrefixElement prefixElement) =>
-      LibraryElementImpl.getImportsWithPrefixFromImports(
-          prefixElement, imports);
-
-  @override
-  ClassElement getType(String className) => LibraryElementImpl.getTypeFromParts(
-      className, definingCompilationUnit, parts);
-
-  @override
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-
-  @override
-  String toString() => _absoluteUri.toString();
-
-  /// Create a [UnitElement] for one of the library's compilation
-  /// units.
-  UnitElement _makeUnitElement(
-      UnlinkedUnit unlinkedUnit, int i, String absoluteUri);
-}
-
-/// Element representing a library which is part of the build unit
-/// being linked.
-class LibraryElementInBuildUnit
-    extends LibraryElementForLink<CompilationUnitElementInBuildUnit> {
-  @override
-  final LinkedLibraryBuilder _linkedLibrary;
-
-  /// The [LibraryNode] representing this library in the library dependency
-  /// graph.
-  LibraryNode _libraryNode;
-
-  List<ImportElement> _imports;
-
-  List<PrefixElement> _prefixes;
-
-  LibraryElementInBuildUnit(Linker linker, Uri absoluteUri, this._linkedLibrary)
-      : super(linker, absoluteUri) {
-    _libraryNode = new LibraryNode(this);
-  }
-
-  @override
-  List<ImportElement> get imports =>
-      _imports ??= LibraryElementImpl.buildImportsFromSummary(this,
-          _unlinkedDefiningUnit.imports, _linkedLibrary.importDependencies);
-
-  @override
-  LibraryCycleForLink get libraryCycleForLink {
-    if (!_libraryNode.isEvaluated) {
-      new LibraryDependencyWalker().walk(_libraryNode);
-    }
-    return _libraryNode._libraryCycle;
-  }
-
-  @override
-  List<PrefixElement> get prefixes =>
-      _prefixes ??= LibraryElementImpl.buildPrefixesFromImports(imports);
-
-  /// If this library already has a dependency in its dependencies table
-  /// matching [library], return its index.  Otherwise add a new dependency to
-  /// table and return its index.
-  int addDependency(LibraryElementForLink library) {
-    for (int i = 0; i < _linkedLibrary.dependencies.length; i++) {
-      if (identical(buildImportedLibrary(i), library)) {
-        return i;
-      }
-    }
-    int result = _linkedLibrary.dependencies.length;
-    Uri libraryUri = library._absoluteUri;
-    List<String> partsRelativeToDependency =
-        library.unlinkedDefiningUnit.publicNamespace.parts;
-    List<String> partsAbsolute = partsRelativeToDependency
-        .map((partUri) =>
-            resolveRelativeUri(libraryUri, Uri.parse(partUri)).toString())
-        .toList();
-    _linkedLibrary.dependencies.add(new LinkedDependencyBuilder(
-        parts: partsAbsolute, uri: libraryUri.toString()));
-    _dependencies.add(library);
-    return result;
-  }
-
-  /// Perform type inference and const cycle detection on this library.
-  void link() {
-    for (CompilationUnitElementInBuildUnit unit in units) {
-      unit.link();
-    }
-  }
-
-  /// Throw away any information stored in the summary by a previous call to
-  /// [link].
-  void unlink() {
-    _linkedLibrary.dependencies.length =
-        _linkedLibrary.numPrelinkedDependencies;
-    for (CompilationUnitElementInBuildUnit unit in units) {
-      unit.unlink();
-    }
-  }
-
-  @override
-  CompilationUnitElementInBuildUnit _makeUnitElement(
-      UnlinkedUnit unlinkedUnit, int i, String absoluteUri) {
-    var astNodeForInference =
-        _linker.getAst == null ? null : _linker.getAst(absoluteUri);
-    return new CompilationUnitElementInBuildUnit(this, unlinkedUnit,
-        _linkedLibrary.units[i], i, absoluteUri, astNodeForInference);
-  }
-}
-
-/// Element representing a library which is depended upon (either
-/// directly or indirectly) by the build unit being linked.
-class LibraryElementInDependency
-    extends LibraryElementForLink<CompilationUnitElementInDependency> {
-  @override
-  final LinkedLibrary _linkedLibrary;
-
-  LibraryElementInDependency(
-      Linker linker, Uri absoluteUri, this._linkedLibrary)
-      : super(linker, absoluteUri);
-
-  @override
-  LibraryCycleForLink get libraryCycleForLink => null;
-
-  @override
-  CompilationUnitElementInDependency _makeUnitElement(
-          UnlinkedUnit unlinkedUnit, int i, String absoluteUri) =>
-      new CompilationUnitElementInDependency(
-          this,
-          unlinkedUnit,
-          _linkedLibrary == null
-              ? new LinkedUnitBuilder()
-              : _linkedLibrary.units[i],
-          i,
-          absoluteUri);
-}
-
-/// Specialization of [Node] used to construct the library dependency graph.
-class LibraryNode extends Node<LibraryNode> {
-  /// The library this [Node] represents.
-  final LibraryElementInBuildUnit library;
-
-  /// The library cycle to which [library] belongs, if it has been computed.
-  /// Otherwise `null`.
-  LibraryCycleForLink _libraryCycle;
-
-  LibraryNode(this.library);
-
-  @override
-  bool get isEvaluated => _libraryCycle != null;
-
-  @override
-  List<LibraryNode> computeDependencies() {
-    // Note: we only need to consider dependencies within the build unit being
-    // linked; dependencies in other build units can't participate in library
-    // cycles with us.
-    List<LibraryNode> dependencies = <LibraryNode>[];
-    for (LibraryElement dependency in library.importedLibraries) {
-      if (dependency is LibraryElementInBuildUnit) {
-        dependencies.add(dependency._libraryNode);
-      }
-    }
-    for (LibraryElement dependency in library.exportedLibraries) {
-      if (dependency is LibraryElementInBuildUnit) {
-        dependencies.add(dependency._libraryNode);
-      }
-    }
-    return dependencies;
-  }
-}
-
-/// Instances of [Linker] contain the necessary information to link
-/// together a single build unit.
-class Linker {
-  /// During linking, if type inference is currently being performed on the
-  /// initializer of a static or instance variable, the library cycle in
-  /// which inference is being performed.  Otherwise, `null`.
-  ///
-  /// This allows us to suppress instance member type inference results from a
-  /// library cycle while doing inference on the right hand sides of static and
-  /// instance variables in that same cycle.
-  static LibraryCycleForLink _initializerTypeInferenceCycle;
-
-  /// If a top-level or an instance variable type inference is in progress,
-  /// this flag it set to `true`.  It is used to prevent type inference for
-  /// other instance variables (when they don't have declared type).
-  static bool _isPerformingVariableTypeInference = false;
-
-  /// Callback to ask the client for a [LinkedLibrary] for a
-  /// dependency.
-  final GetDependencyCallback getDependency;
-
-  /// Callback to ask the client for an [UnlinkedUnit].
-  final GetUnitCallback getUnit;
-
-  /// Callback to ask the client for a [CompilationUnit].
-  final GetAstCallback getAst;
-
-  /// Map containing all library elements accessed during linking,
-  /// whether they are part of the build unit being linked or whether
-  /// they are dependencies.
-  final Map<Uri, LibraryElementForLink> _libraries =
-      <Uri, LibraryElementForLink>{};
-
-  /// List of library elements for the libraries in the build unit
-  /// being linked.
-  final List<LibraryElementInBuildUnit> _librariesInBuildUnit =
-      <LibraryElementInBuildUnit>[];
-
-  LibraryElementForLink _coreLibrary;
-
-  LibraryElementForLink _asyncLibrary;
-  TypeProviderForLink _typeProvider;
-  TypeSystem _typeSystem;
-  SpecialTypeElementForLink _voidElement;
-  SpecialTypeElementForLink _dynamicElement;
-  SpecialTypeElementForLink _bottomElement;
-  InheritanceManager3 _inheritanceManager;
-  ContextForLink _context;
-  AnalysisSessionForLink _session;
-
-  /// Gets an instance of [AnalysisOptions] for use during linking.
-  final AnalysisOptions analysisOptions;
-
-  Linker(Map<String, LinkedLibraryBuilder> linkedLibraries, this.getDependency,
-      this.getUnit, this.getAst, this.analysisOptions) {
-    // Create elements for the libraries to be linked.  The rest of
-    // the element model will be created on demand.
-    linkedLibraries
-        .forEach((String absoluteUri, LinkedLibraryBuilder linkedLibrary) {
-      Uri uri = Uri.parse(absoluteUri);
-      _librariesInBuildUnit.add(_libraries[uri] =
-          new LibraryElementInBuildUnit(this, uri, linkedLibrary));
-    });
-  }
-
-  /// Get the library element for `dart:async`.
-  LibraryElementForLink get asyncLibrary =>
-      _asyncLibrary ??= getLibrary(Uri.parse('dart:async'));
-
-  /// Get the element representing the "bottom" type.
-  SpecialTypeElementForLink get bottomElement => _bottomElement ??=
-      new SpecialTypeElementForLink(this, BottomTypeImpl.instance);
-
-  /// Get a stub implementation of [AnalysisContext] which can be used during
-  /// linking.
-  get context => _context ??= new ContextForLink(this);
-
-  /// Get the library element for `dart:core`.
-  LibraryElementForLink get coreLibrary =>
-      _coreLibrary ??= getLibrary(Uri.parse('dart:core'));
-
-  /// Get the element representing `dynamic`.
-  SpecialTypeElementForLink get dynamicElement => _dynamicElement ??=
-      new SpecialTypeElementForLink(this, DynamicTypeImpl.instance);
-
-  /// Get an instance of [InheritanceManager3] for use during linking.
-  InheritanceManager3 get inheritanceManager =>
-      _inheritanceManager ??= new InheritanceManager3(typeSystem);
-
-  /// Get a stub implementation of [AnalysisContext] which can be used during
-  /// linking.
-  get session => _session ??= new AnalysisSessionForLink();
-
-  /// Indicates whether type inference should use strong mode rules.
-  @deprecated
-  bool get strongMode => true;
-
-  /// Get an instance of [TypeProvider] for use during linking.
-  TypeProviderForLink get typeProvider =>
-      _typeProvider ??= new TypeProviderForLink(this);
-
-  /// Get an instance of [TypeSystem] for use during linking.
-  TypeSystem get typeSystem =>
-      _typeSystem ??= new Dart2TypeSystem(typeProvider);
-
-  /// Get the element representing `void`.
-  SpecialTypeElementForLink get voidElement => _voidElement ??=
-      new SpecialTypeElementForLink(this, VoidTypeImpl.instance);
-
-  /// Get the library element for the library having the given [uri].
-  LibraryElementForLink getLibrary(Uri uri) => _libraries.putIfAbsent(
-      uri,
-      () => new LibraryElementInDependency(
-          this, uri, getDependency(uri.toString())));
-
-  /// Perform type inference and const cycle detection on all libraries
-  /// in the build unit being linked.
-  void link() {
-    // Link library cycles in appropriate dependency order.
-    for (LibraryElementInBuildUnit library in _librariesInBuildUnit) {
-      library.libraryCycleForLink.ensureLinked();
-    }
-    // TODO(paulberry): set dependencies.
-  }
-
-  /// Throw away any information stored in the summary by a previous call to
-  /// [link].
-  void unlink() {
-    for (LibraryElementInBuildUnit library in _librariesInBuildUnit) {
-      library.unlink();
-    }
-  }
-}
-
-/// Element representing a method resynthesized from a summary during linking.
-class MethodElementForLink extends ExecutableElementForLink_NonLocal
-    with ReferenceableElementForLink
-    implements MethodElementImpl {
-  MethodElementForLink(ClassMemberContainerForLink enclosingClass,
-      UnlinkedExecutable unlinkedExecutable)
-      : super(enclosingClass.enclosingElement, enclosingClass,
-            unlinkedExecutable);
-
-  @override
-  DartType get asStaticType => type;
-
-  @override
-  String get identifier => name;
-
-  @override
-  ElementKind get kind => ElementKind.METHOD;
-
-  @override
-  FunctionElementForLink_Local getLocalFunction(int index) {
-    // TODO(paulberry): implement.
-    return null;
-  }
-
-  @override
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-
-  @override
-  String toString() => '$enclosingElement.$name';
-}
-
 /**
  * Instances of [Node] represent nodes in a dependency graph.  The
  * type parameter, [NodeType], is the derived type (this affords some
@@ -4297,1728 +168,3 @@
     return node._dependencies ??= node.computeDependencies();
   }
 }
-
-/// Element used for references that result from trying to access a non-static
-/// member of an element that is not a container (e.g. accessing the "length"
-/// property of a constant).
-///
-/// Accesses to a chain of non-static members separated by '.' are handled by
-/// creating a [NonstaticMemberElementForLink] that points to another
-/// [NonstaticMemberElementForLink], to whatever nesting level is necessary.
-class NonstaticMemberElementForLink with ReferenceableElementForLink {
-  /// The [ReferenceableElementForLink] which is the target of the non-static
-  /// reference.
-  final ReferenceableElementForLink _target;
-
-  /// The name of the non-static members that is being accessed.
-  final String _name;
-
-  /// The library in which the access occurs.  This determines whether private
-  /// names are accessible.
-  final LibraryElementForLink _library;
-
-  /// Whether the [_element] was computed (even if to `null`).
-  bool _elementReady = false;
-
-  /// The cached [ExecutableElement] represented by this element.
-  ExecutableElement _element;
-
-  NonstaticMemberElementForLink(this._library, this._target, this._name);
-
-  @override
-  ConstVariableNode get asConstVariable => _target.asConstVariable;
-
-  /// Return the [ExecutableElement] represented by this element.
-  ExecutableElement get asExecutableElement {
-    if (!_elementReady) {
-      _elementReady = true;
-      DartType targetType = _target.asStaticType;
-      if (targetType.isDynamic) {
-        targetType = _library._linker.typeProvider.objectType;
-      }
-      if (targetType is InterfaceType) {
-        _element =
-            targetType.lookUpInheritedGetterOrMethod(_name, library: _library);
-      }
-      // TODO(paulberry): handle .call on function types and .toString or
-      // .hashCode on all types.
-    }
-    return _element;
-  }
-
-  @override
-  DartType get asStaticType {
-    ExecutableElement element = asExecutableElement;
-    if (element != null) {
-      if (element is PropertyAccessorElement) {
-        return element.returnType;
-      } else {
-        // Method tear-off
-        return element.type;
-      }
-    }
-    return DynamicTypeImpl.instance;
-  }
-
-  @override
-  TypeInferenceNode get asTypeInferenceNode => _target.asTypeInferenceNode;
-
-  @override
-  ReferenceableElementForLink getContainedName(String name) {
-    return new NonstaticMemberElementForLink(_library, this, name);
-  }
-
-  @override
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-
-  @override
-  String toString() => '$_target.(dynamic)$_name';
-}
-
-/// Element representing a function or method parameter resynthesized
-/// from a summary during linking.
-class ParameterElementForLink implements ParameterElementImpl {
-  /// The unlinked representation of the parameter in the summary.
-  final UnlinkedParam unlinkedParam;
-
-  /// The innermost enclosing element that can declare type parameters.
-  final TypeParameterizedElementMixin _typeParameterContext;
-
-  /// If this parameter has a default value and the enclosing library
-  /// is part of the build unit being linked, the parameter's node in
-  /// the constant evaluation dependency graph.  Otherwise `null`.
-  ConstNode _constNode;
-
-  /// The compilation unit in which this parameter appears.
-  final CompilationUnitElementForLink compilationUnit;
-
-  /// The index of this parameter within [enclosingElement]'s parameter list.
-  final int _parameterIndex;
-
-  @override
-  final ParameterParentElementForLink enclosingElement;
-
-  DartType _inferredType;
-  TopLevelInferenceErrorBuilder _inferenceError;
-  DartType _declaredType;
-  bool _inheritsCovariant = false;
-
-  ParameterElementForLink(this.enclosingElement, this.unlinkedParam,
-      this._typeParameterContext, this.compilationUnit, this._parameterIndex) {
-    if (unlinkedParam.initializer?.bodyExpr != null) {
-      _constNode = new ConstParameterNode(this);
-    }
-    if (compilationUnit is CompilationUnitElementInDependency) {
-      _inheritsCovariant =
-          (compilationUnit as CompilationUnitElementInDependency)
-              .parametersInheritingCovariant
-              .contains(unlinkedParam.inheritsCovariantSlot);
-    }
-  }
-
-  factory ParameterElementForLink.forFactory(
-      ParameterParentElementForLink enclosingElement,
-      UnlinkedParam unlinkedParameter,
-      TypeParameterizedElementMixin typeParameterContext,
-      CompilationUnitElementForLink compilationUnit,
-      int parameterIndex) {
-    if (unlinkedParameter.isInitializingFormal) {
-      return new FieldFormalParameterElementForLink(
-          enclosingElement,
-          unlinkedParameter,
-          typeParameterContext,
-          typeParameterContext.enclosingUnit.resynthesizerContext
-              as CompilationUnitElementForLink,
-          parameterIndex);
-    } else {
-      return new ParameterElementForLink(
-          enclosingElement,
-          unlinkedParameter,
-          typeParameterContext,
-          typeParameterContext.enclosingUnit.resynthesizerContext
-              as CompilationUnitElementForLink,
-          parameterIndex);
-    }
-  }
-
-  @override
-  String get displayName => unlinkedParam.name;
-
-  @override
-  bool get hasImplicitType =>
-      !unlinkedParam.isFunctionTyped && unlinkedParam.type == null;
-
-  @override
-  String get identifier => name;
-
-  @override
-  bool get inheritsCovariant => _inheritsCovariant;
-
-  @override
-  void set inheritsCovariant(bool value) {
-    _inheritsCovariant = value;
-  }
-
-  @override
-  FunctionElement get initializer => null;
-
-  @override
-  bool get isCovariant {
-    if (isExplicitlyCovariant || inheritsCovariant) {
-      return true;
-    }
-    return false;
-  }
-
-  @override
-  bool get isExplicitlyCovariant => unlinkedParam.isExplicitlyCovariant;
-
-  @override
-  bool get isInitializingFormal => unlinkedParam.isInitializingFormal;
-
-  @override
-  bool get isNamed =>
-      parameterKind == ParameterKind.NAMED ||
-      parameterKind == ParameterKind.NAMED_REQUIRED;
-
-  @override
-  bool get isNotOptional =>
-      parameterKind == ParameterKind.REQUIRED ||
-      parameterKind == ParameterKind.NAMED_REQUIRED;
-
-  @override
-  bool get isOptional =>
-      parameterKind == ParameterKind.NAMED ||
-      parameterKind == ParameterKind.POSITIONAL;
-
-  @override
-  bool get isOptionalNamed => parameterKind == ParameterKind.NAMED;
-
-  @override
-  bool get isOptionalPositional => parameterKind == ParameterKind.POSITIONAL;
-
-  @override
-  bool get isPositional =>
-      parameterKind == ParameterKind.POSITIONAL ||
-      parameterKind == ParameterKind.REQUIRED;
-
-  @override
-  bool get isRequiredNamed => parameterKind == ParameterKind.NAMED_REQUIRED;
-
-  @override
-  bool get isRequiredPositional => parameterKind == ParameterKind.REQUIRED;
-
-  @override
-  get linkedNode => null;
-
-  @override
-  String get name => unlinkedParam.name;
-
-  @override
-  ParameterKind get parameterKind {
-    switch (unlinkedParam.kind) {
-      case UnlinkedParamKind.requiredPositional:
-        return ParameterKind.REQUIRED;
-      case UnlinkedParamKind.requiredNamed:
-        return ParameterKind.NAMED_REQUIRED;
-      case UnlinkedParamKind.optionalPositional:
-        return ParameterKind.POSITIONAL;
-      case UnlinkedParamKind.optionalNamed:
-        return ParameterKind.NAMED;
-    }
-    return null;
-  }
-
-  @override
-  DartType get type {
-    if (_inferredType != null) {
-      return _inferredType;
-    } else if (_declaredType == null) {
-      if (unlinkedParam.isFunctionTyped) {
-        _declaredType = new FunctionTypeImpl(
-            new FunctionElementForLink_FunctionTypedParam(
-                this, _typeParameterContext, unlinkedParam.parameters));
-      } else if (unlinkedParam.type == null) {
-        if (!compilationUnit.isInBuildUnit) {
-          _inferredType = compilationUnit.getLinkedType(
-              this, unlinkedParam.inferredTypeSlot);
-          return _inferredType;
-        } else {
-          _declaredType = DynamicTypeImpl.instance;
-        }
-      } else {
-        _declaredType =
-            compilationUnit.resolveTypeRef(this, unlinkedParam.type);
-      }
-    }
-    return _declaredType;
-  }
-
-  @override
-  void set type(DartType inferredType) {
-    assert(_inferredType == null);
-    _inferredType = inferredType;
-  }
-
-  @override
-  TypeParameterizedElementMixin get typeParameterContext {
-    return _typeParameterContext;
-  }
-
-  /// Store the results of type inference for this parameter in
-  /// [compilationUnit].
-  void link(CompilationUnitElementInBuildUnit compilationUnit) {
-    compilationUnit._storeLinkedType(
-        unlinkedParam.inferredTypeSlot, _inferredType, _typeParameterContext);
-    compilationUnit._storeLinkedTypeError(
-        unlinkedParam.inferredTypeSlot, _inferenceError);
-    if (inheritsCovariant) {
-      compilationUnit
-          ._storeInheritsCovariant(unlinkedParam.inheritsCovariantSlot);
-    }
-  }
-
-  @override
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-
-  void setInferenceError(TopLevelInferenceErrorBuilder error) {
-    assert(_inferenceError == null);
-    _inferenceError = error;
-  }
-}
-
-/// Element representing the parameter of a synthetic setter for a variable
-/// resynthesized during linking.
-class ParameterElementForLink_VariableSetter implements ParameterElementImpl {
-  @override
-  final PropertyAccessorElementForLink_Variable enclosingElement;
-
-  @override
-  bool inheritsCovariant = false;
-
-  ParameterElementForLink_VariableSetter(this.enclosingElement);
-
-  @override
-  bool get isCovariant => isExplicitlyCovariant || inheritsCovariant;
-
-  @override
-  bool get isExplicitlyCovariant => enclosingElement.variable.isCovariant;
-
-  bool get isInitializingFormal => unlinkedParam.isInitializingFormal;
-
-  @override
-  bool get isNamed =>
-      parameterKind == ParameterKind.NAMED ||
-      parameterKind == ParameterKind.NAMED_REQUIRED;
-
-  @override
-  bool get isNotOptional =>
-      parameterKind == ParameterKind.REQUIRED ||
-      parameterKind == ParameterKind.NAMED_REQUIRED;
-
-  @override
-  bool get isOptional =>
-      parameterKind == ParameterKind.NAMED ||
-      parameterKind == ParameterKind.POSITIONAL;
-
-  @override
-  bool get isOptionalNamed => parameterKind == ParameterKind.NAMED;
-
-  @override
-  bool get isOptionalPositional => parameterKind == ParameterKind.POSITIONAL;
-
-  @override
-  bool get isPositional =>
-      parameterKind == ParameterKind.POSITIONAL ||
-      parameterKind == ParameterKind.REQUIRED;
-
-  @override
-  bool get isRequiredNamed => parameterKind == ParameterKind.NAMED_REQUIRED;
-
-  @override
-  bool get isRequiredPositional => parameterKind == ParameterKind.REQUIRED;
-
-  @override
-  bool get isSynthetic => true;
-
-  @override
-  String get name => 'x';
-
-  @override
-  ParameterKind get parameterKind => ParameterKind.REQUIRED;
-
-  @override
-  DartType get type => enclosingElement.variable.type;
-
-  @override
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
-
-/// Mixin used by elements that can have parameters.
-abstract class ParameterParentElementForLink implements Element {
-  List<ParameterElement> _parameters;
-
-  /// Get the appropriate integer list to store in
-  /// [EntityRef.implicitFunctionTypeIndices] to refer to this element.  For an
-  /// element representing a function-typed parameter, this should return a
-  /// non-empty list.  For an element representing an executable, this should
-  /// return the empty list.
-  List<int> get implicitFunctionTypeIndices;
-
-  /// Get all the parameters of this element.
-  List<ParameterElement> get parameters {
-    if (_parameters == null) {
-      List<UnlinkedParam> unlinkedParameters = this.unlinkedParameters;
-      int numParameters = unlinkedParameters.length;
-      _parameters = new List<ParameterElement>(numParameters);
-      for (int i = 0; i < numParameters; i++) {
-        UnlinkedParam unlinkedParam = unlinkedParameters[i];
-        _parameters[i] = new ParameterElementForLink.forFactory(
-            this,
-            unlinkedParam,
-            typeParameterContext,
-            typeParameterContext.enclosingUnit.resynthesizerContext
-                as CompilationUnitElementForLink,
-            i);
-      }
-    }
-    return _parameters;
-  }
-
-  /// Get the innermost enclosing element that can declare type parameters
-  /// (which may be [this], or may be a parent when there are function-typed
-  /// parameters).
-  TypeParameterizedElementMixin get typeParameterContext;
-
-  /// Get the list of unlinked parameters of this element.
-  List<UnlinkedParam> get unlinkedParameters;
-}
-
-/// Element representing a getter or setter resynthesized from a summary during
-/// linking.
-abstract class PropertyAccessorElementForLink
-    implements PropertyAccessorElementImpl, ReferenceableElementForLink {
-  void link(CompilationUnitElementInBuildUnit compilationUnit);
-}
-
-/// Specialization of [PropertyAccessorElementForLink] for synthetic accessors
-/// implied by the synthetic fields of an enum declaration.
-class PropertyAccessorElementForLink_EnumField
-    with ReferenceableElementForLink
-    implements PropertyAccessorElementForLink {
-  @override
-  final FieldElementForLink_EnumField variable;
-
-  FunctionTypeImpl _type;
-
-  PropertyAccessorElementForLink_EnumField(this.variable);
-
-  @override
-  DartType get asStaticType => returnType;
-
-  @override
-  Element get enclosingElement => variable.enclosingElement;
-
-  @override
-  bool get isAbstract => false;
-
-  @override
-  bool get isGetter => true;
-
-  @override
-  bool get isSetter => false;
-
-  @override
-  bool get isStatic => variable.isStatic;
-
-  @override
-  bool get isSynthetic => true;
-
-  @override
-  ElementKind get kind => ElementKind.GETTER;
-
-  @override
-  LibraryElementForLink get library =>
-      variable.enclosingElement.enclosingElement.enclosingElement;
-
-  @override
-  String get name => variable.name;
-
-  @override
-  List<ParameterElement> get parameters => const [];
-
-  @override
-  DartType get returnType => variable.type;
-
-  @override
-  FunctionTypeImpl get type => _type ??= new FunctionTypeImpl(this);
-
-  @override
-  List<TypeParameterElement> get typeParameters => const [];
-
-  @override
-  ReferenceableElementForLink getContainedName(String name) {
-    return new NonstaticMemberElementForLink(library, this, name);
-  }
-
-  @override
-  FunctionElementForLink_Local getLocalFunction(int index) {
-    // TODO(paulberry): implement (should return the synthetic function element
-    // for the enum field's initializer).
-    return null;
-  }
-
-  @override
-  bool isAccessibleIn(LibraryElement library) =>
-      !Identifier.isPrivateName(name) || identical(this.library, library);
-
-  @override
-  void link(CompilationUnitElementInBuildUnit compilationUnit) {}
-
-  @override
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-
-  @override
-  String toString() => '$enclosingElement.$name';
-}
-
-/// Specialization of [PropertyAccessorElementForLink] for non-synthetic
-/// accessors explicitly declared in the source code.
-class PropertyAccessorElementForLink_Executable
-    extends ExecutableElementForLink_NonLocal
-    with ReferenceableElementForLink
-    implements PropertyAccessorElementForLink {
-  @override
-  PropertyInducingElement variable;
-
-  PropertyAccessorElementForLink_Executable(
-      CompilationUnitElementForLink enclosingUnit,
-      ClassMemberContainerForLink enclosingClass,
-      UnlinkedExecutable unlinkedExecutable,
-      this.variable)
-      : super(enclosingUnit, enclosingClass, unlinkedExecutable);
-
-  @override
-  DartType get asStaticType => returnType;
-
-  @override
-  PropertyAccessorElementForLink_Executable get correspondingGetter =>
-      variable.getter;
-
-  @override
-  bool get isGetter =>
-      serializedExecutable.kind == UnlinkedExecutableKind.getter;
-
-  @override
-  bool get isSetter =>
-      serializedExecutable.kind == UnlinkedExecutableKind.setter;
-
-  @override
-  bool get isStatic => enclosingClass == null || super.isStatic;
-
-  @override
-  ElementKind get kind =>
-      serializedExecutable.kind == UnlinkedExecutableKind.getter
-          ? ElementKind.GETTER
-          : ElementKind.SETTER;
-
-  @override
-  ReferenceableElementForLink getContainedName(String name) {
-    return new NonstaticMemberElementForLink(
-        library as LibraryElementForLink, this, name);
-  }
-
-  @override
-  FunctionElementForLink_Local getLocalFunction(int index) {
-    // TODO(paulberry): implement
-    return null;
-  }
-
-  @override
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-
-  @override
-  String toString() => '$enclosingElement.$name';
-}
-
-/// Specialization of [PropertyAccessorElementForLink] for synthetic accessors
-/// implied by a field or variable declaration.
-class PropertyAccessorElementForLink_Variable
-    with ReferenceableElementForLink
-    implements PropertyAccessorElementForLink {
-  @override
-  final bool isSetter;
-
-  final VariableElementForLink variable;
-  FunctionTypeImpl _type;
-  ParameterElementForLink_VariableSetter _parameter;
-  List<ParameterElement> _parameters;
-
-  PropertyAccessorElementForLink_Variable(this.variable, this.isSetter);
-
-  @override
-  ConstVariableNode get asConstVariable => variable._constNode;
-
-  @override
-  DartType get asStaticType => returnType;
-
-  @override
-  TypeInferenceNode get asTypeInferenceNode => variable._typeInferenceNode;
-
-  @override
-  String get displayName => variable.displayName;
-
-  @override
-  Element get enclosingElement => variable.enclosingElement;
-
-  @override
-  bool get isAbstract => false;
-
-  @override
-  bool get isGetter => !isSetter;
-
-  @override
-  bool get isStatic => variable.isStatic;
-
-  @override
-  bool get isSynthetic => true;
-
-  @override
-  ElementKind get kind => isSetter ? ElementKind.SETTER : ElementKind.GETTER;
-
-  @override
-  LibraryElementForLink get library =>
-      variable.compilationUnit.enclosingElement;
-
-  @override
-  String get name => isSetter ? '${variable.name}=' : variable.name;
-
-  @override
-  List<ParameterElement> get parameters {
-    if (_parameters == null) {
-      _parameters = <ParameterElementForLink_VariableSetter>[];
-      if (isSetter) {
-        _parameter = new ParameterElementForLink_VariableSetter(this);
-        _parameters.add(_parameter);
-      }
-    }
-    return _parameters;
-  }
-
-  @override
-  DartType get returnType {
-    if (isSetter) {
-      return VoidTypeImpl.instance;
-    } else {
-      return variable.type;
-    }
-  }
-
-  @override
-  FunctionTypeImpl get type => _type ??= new FunctionTypeImpl(this);
-
-  @override
-  List<TypeParameterElement> get typeParameters {
-    // TODO(paulberry): is this correct for fields in generic classes?
-    return const [];
-  }
-
-  @override
-  ReferenceableElementForLink getContainedName(String name) {
-    return new NonstaticMemberElementForLink(library, this, name);
-  }
-
-  @override
-  FunctionElementForLink_Local getLocalFunction(int index) {
-    if (index == 0) {
-      return variable.initializer;
-    } else {
-      return null;
-    }
-  }
-
-  @override
-  bool isAccessibleIn(LibraryElement library) =>
-      !Identifier.isPrivateName(name) || identical(this.library, library);
-
-  @override
-  void link(CompilationUnitElementInBuildUnit compilationUnit) {
-    if (isSetter && _parameter != null) {
-      if (_parameter.inheritsCovariant) {
-        compilationUnit._storeInheritsCovariant(
-            variable.unlinkedVariable.inheritsCovariantSlot);
-      }
-    }
-  }
-
-  @override
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-
-  @override
-  String toString() => '$enclosingElement.$name';
-}
-
-/// Base class representing an element which can be the target of a reference.
-/// When used as a mixin, implements the default behavior shared by most
-/// elements.
-mixin ReferenceableElementForLink implements Element {
-  /// If this element is a class reference, return it. Otherwise return `null`.
-  ClassElementForLink get asClass => null;
-
-  /// If this element can be used in a constructor invocation context,
-  /// return the associated constructor (which may be `this` or some
-  /// other element).  Otherwise return `null`.
-  ConstructorElementForLink get asConstructor => null;
-
-  /// If this element can be used in a getter context to refer to a
-  /// constant variable, return the [ConstVariableNode] for the
-  /// constant value.  Otherwise return `null`.
-  ConstVariableNode get asConstVariable => null;
-
-  /// Return the static type (possibly inferred) of the entity referred to by
-  /// this element.
-  DartType get asStaticType => DynamicTypeImpl.instance;
-
-  /// If this element can be used in a getter context as a type inference
-  /// dependency, return the [TypeInferenceNode] for the inferred type.
-  /// Otherwise return `null`.
-  TypeInferenceNode get asTypeInferenceNode => null;
-
-  /// See [TypeParameterElement.isSimplyBounded].
-  bool get isSimplyBounded => true;
-
-  @override
-  ElementLocation get location => new ElementLocationImpl.con1(this);
-
-  /// If non-null, the [SimplyBoundedNode] for determining whether this element
-  /// is simply bounded.
-  ///
-  /// If null, this element is known to be simply bounded based on its unlinked
-  /// representation alone (for example, it is a class declaration with no type
-  /// parameters, or it is a class declaration whose type parameters all lack
-  /// explicit bounds).  Or it is an element for which simple boundedness is
-  /// not relevant.
-  SimplyBoundedNode get _simplyBoundedNode => null;
-
-  /// Return the type indicated by this element when it is used in a
-  /// type instantiation context.  If this element can't legally be
-  /// instantiated as a type, return the dynamic type.
-  ///
-  /// If the type is parameterized, [getTypeArgument] will be called to retrieve
-  /// the type parameters.  It should return `null` for unspecified type
-  /// parameters.
-  DartType buildType(DartType getTypeArgument(int i),
-          List<int> implicitFunctionTypeIndices) =>
-      DynamicTypeImpl.instance;
-
-  /// If this element contains other named elements, return the
-  /// contained element having the given [name].  If this element can't
-  /// contain other named elements, or it doesn't contain an element
-  /// with the given name, return the singleton of
-  /// [UndefinedElementForLink].
-  ReferenceableElementForLink getContainedName(String name) {
-    // TODO(paulberry): handle references to `call` for function types.
-    return UndefinedElementForLink.instance;
-  }
-
-  /// If this element contains local functions, return the contained local
-  /// function having the given [index].  If this element doesn't contain local
-  /// functions, or the index is out of range, return `null`.
-  FunctionElementForLink_Local getLocalFunction(int index) => null;
-}
-
-/// Mixin providing the implementation of
-/// [ReferenceableElementForLink.isSimplyBounded] for elements representing a
-/// type.
-abstract class SimplyBoundableForLinkMixin
-    implements ReferenceableElementForLink {
-  @override
-  SimplyBoundedNode _simplyBoundedNode;
-
-  CompilationUnitElementForLink get enclosingUnit;
-
-  @override
-  bool get isSimplyBounded {
-    var slot = _notSimplyBoundedSlot;
-    if (slot == 0) return true;
-    if (enclosingUnit.isInBuildUnit) {
-      assert(_simplyBoundedNode.isEvaluated);
-      return _simplyBoundedNode.isSimplyBounded;
-    } else {
-      return !enclosingUnit._linkedUnit.notSimplyBounded.contains(slot);
-    }
-  }
-
-  int get _notSimplyBoundedSlot;
-
-  List<EntityRef> get _rhsTypesForSimplyBoundable;
-
-  List<UnlinkedTypeParam> get _typeParametersForSimplyBoundable;
-
-  void _initSimplyBoundable() {
-    if (enclosingUnit.isInBuildUnit && _notSimplyBoundedSlot != 0) {
-      _simplyBoundedNode = SimplyBoundedNode(enclosingUnit,
-          _typeParametersForSimplyBoundable, _rhsTypesForSimplyBoundable);
-    }
-  }
-
-  void _linkSimplyBoundable() {
-    if (_simplyBoundedNode != null) {
-      if (!_simplyBoundedNode.isEvaluated) {
-        new SimplyBoundedDependencyWalker().walk(_simplyBoundedNode);
-      }
-      if (!_simplyBoundedNode.isSimplyBounded) {
-        enclosingUnit._linkedUnit.notSimplyBounded.add(_notSimplyBoundedSlot);
-      }
-    }
-  }
-}
-
-/// Specialization of [DependencyWalker] for evaluating whether types are simply
-/// bounded.
-class SimplyBoundedDependencyWalker
-    extends DependencyWalker<SimplyBoundedNode> {
-  @override
-  void evaluate(SimplyBoundedNode v) {
-    v._evaluate();
-  }
-
-  @override
-  void evaluateScc(List<SimplyBoundedNode> scc) {
-    for (var node in scc) {
-      node._markCircular();
-    }
-  }
-}
-
-/// Specialization of [Node] used to construct the dependency graph for
-/// evaluating whether types are simply bounded.
-class SimplyBoundedNode extends Node<SimplyBoundedNode> {
-  /// The compilation unit enclosing the type whose simple-boundedness we need
-  /// to check
-  final CompilationUnitElementForLink _unit;
-
-  /// The type parameters of the type whose simple-boundedness we need to check
-  final List<UnlinkedTypeParam> _typeParameters;
-
-  /// If the type whose simple-boundedness we need to check is a typedef, the
-  /// types appering in its "right hand side"
-  final List<EntityRef> _rhsTypes;
-
-  @override
-  bool isEvaluated = false;
-
-  /// After execution of [_evaluate], indicates whether the type is
-  /// simply bounded.
-  ///
-  /// Prior to execution of [computeDependencies], `true`.
-  ///
-  /// Between execution of [computeDependencies] and [_evaluate], `true`
-  /// indicates that the type is simply bounded only if all of its dependencies
-  /// are simply bounded; `false` indicates that the type is not simply bounded.
-  bool isSimplyBounded = true;
-
-  SimplyBoundedNode(this._unit, this._typeParameters, this._rhsTypes);
-
-  @override
-  List<SimplyBoundedNode> computeDependencies() {
-    var dependencies = <SimplyBoundedNode>[];
-    for (var typeParameter in _typeParameters) {
-      var bound = typeParameter.bound;
-      if (bound != null) {
-        if (!_visitType(dependencies, bound, true)) {
-          // Note: we might consider setting isEvaluated=true here to prevent an
-          // unnecessary call to SimplyBoundedDependencyWalker.evaluate.
-          // However, we'd have to be careful to make sure this doesn't violate
-          // an invariant of the DependencyWalker algorithm, since normally it
-          // only expects isEvaluated to change during a call to .evaluate or
-          // .evaluateScc.
-          isSimplyBounded = false;
-          return const [];
-        }
-      }
-    }
-    for (var type in _rhsTypes) {
-      if (!_visitType(dependencies, type, false)) {
-        // Note: we might consider setting isEvaluated=true here to prevent an
-        // unnecessary call to SimplyBoundedDependencyWalker.evaluate.
-        // However, we'd have to be careful to make sure this doesn't violate
-        // an invariant of the DependencyWalker algorithm, since normally it
-        // only expects isEvaluated to change during a call to .evaluate or
-        // .evaluateScc.
-        isSimplyBounded = false;
-        return const [];
-      }
-    }
-    return dependencies;
-  }
-
-  void _evaluate() {
-    for (var dependency in _dependencies) {
-      if (!dependency.isSimplyBounded) {
-        isSimplyBounded = false;
-        break;
-      }
-    }
-    isEvaluated = true;
-  }
-
-  void _markCircular() {
-    isSimplyBounded = false;
-    isEvaluated = true;
-  }
-
-  /// Visits the parameters in [params], storing the [SimplyBoundedNode] for any
-  /// types they reference in [dependencies].
-  ///
-  /// If a type is found that is already known to be not simply bounded (because
-  /// it is in another build unit), or [disallowTypeParamReferences] is `true`
-  /// and a reference to a type parameter is found, `false` is returned and
-  /// further visiting is short-circuited.  Otherwise `true` is returned.
-  bool _visitParams(List<SimplyBoundedNode> dependencies,
-      List<UnlinkedParam> params, bool disallowTypeParamReferences) {
-    for (var param in params) {
-      if (!_visitType(dependencies, param.type, disallowTypeParamReferences)) {
-        return false;
-      }
-      if (isSimplyBounded && param.isFunctionTyped) {
-        if (!_visitParams(
-            dependencies, param.parameters, disallowTypeParamReferences)) {
-          return false;
-        }
-      }
-    }
-    return true;
-  }
-
-  /// Visits the type specified by [type], storing the [SimplyBoundedNode] for
-  /// any types it references in [dependencies].
-  ///
-  /// If a type is found that is already known to be not simply bounded (because
-  /// it is in another build unit), or [disallowTypeParamReferences] is `true`
-  /// and a reference to a type parameter is found, `false` is returned and
-  //  /// further visiting is short-circuited.  Otherwise `true` is returned.
-  bool _visitType(List<SimplyBoundedNode> dependencies, EntityRef type,
-      bool disallowTypeParamReferences) {
-    if (type != null) {
-      if (type.paramReference != 0) {
-        if (disallowTypeParamReferences) {
-          return false;
-        }
-      } else if (type.entityKind == EntityRefKind.genericFunctionType) {
-        if (!_visitParams(
-            dependencies, type.syntheticParams, disallowTypeParamReferences)) {
-          return false;
-        }
-        if (!_visitType(dependencies, type.syntheticReturnType,
-            disallowTypeParamReferences)) {
-          return false;
-        }
-      } else {
-        if (type.typeArguments.isEmpty) {
-          var ref = _unit.resolveRef(type.reference);
-          var dep = ref._simplyBoundedNode;
-          if (dep == null) {
-            if (!ref.isSimplyBounded) {
-              return false;
-            }
-          } else {
-            dependencies.add(dep);
-          }
-        } else {
-          for (var typeArgument in type.typeArguments) {
-            if (!_visitType(
-                dependencies, typeArgument, disallowTypeParamReferences)) {
-              return false;
-            }
-          }
-        }
-      }
-    }
-    return true;
-  }
-}
-
-/// Element used for references to special types such as `void`.
-class SpecialTypeElementForLink with ReferenceableElementForLink {
-  final Linker linker;
-  final DartType type;
-
-  SpecialTypeElementForLink(this.linker, this.type);
-
-  @override
-  DartType get asStaticType => linker.typeProvider.typeType;
-
-  @override
-  DartType buildType(
-      DartType getTypeArgument(int i), List<int> implicitFunctionTypeIndices) {
-    return type;
-  }
-
-  @override
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-
-  @override
-  String toString() => type.toString();
-}
-
-/// Element representing a synthetic variable resynthesized from a summary
-/// during linking.
-class SyntheticVariableElementForLink implements PropertyInducingElementImpl {
-  PropertyAccessorElementForLink_Executable _getter;
-  PropertyAccessorElementForLink_Executable _setter;
-
-  @override
-  PropertyAccessorElementForLink_Executable get getter => _getter;
-
-  @override
-  bool get isFinal => _setter == null;
-
-  @override
-  bool get isSynthetic => true;
-
-  @override
-  PropertyAccessorElementForLink_Executable get setter => _setter;
-
-  @override
-  void set type(DartType inferredType) {}
-
-  @override
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
-
-/// Element representing a top-level function.
-class TopLevelFunctionElementForLink extends ExecutableElementForLink_NonLocal
-    with ReferenceableElementForLink
-    implements FunctionElementImpl {
-  DartType _returnType;
-
-  TopLevelFunctionElementForLink(
-      CompilationUnitElementForLink enclosingUnit, UnlinkedExecutable _buf)
-      : super(enclosingUnit, null, _buf);
-
-  @override
-  DartType get asStaticType => type;
-
-  @override
-  String get identifier => serializedExecutable.name;
-
-  @override
-  bool get isStatic => true;
-
-  @override
-  ElementKind get kind => ElementKind.FUNCTION;
-
-  @override
-  FunctionElementForLink_Local getLocalFunction(int index) {
-    // TODO(paulberry): implement.
-    return null;
-  }
-
-  @override
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-
-  @override
-  String toString() => '$enclosingElement.$name';
-}
-
-/// Element representing a top level variable resynthesized from a
-/// summary during linking.
-class TopLevelVariableElementForLink extends VariableElementForLink
-    implements TopLevelVariableElement {
-  TopLevelVariableElementForLink(CompilationUnitElementForLink enclosingElement,
-      UnlinkedVariable unlinkedVariable, Expression initializerForInference)
-      : super(unlinkedVariable, enclosingElement, initializerForInference);
-
-  @override
-  CompilationUnitElementForLink get enclosingElement => compilationUnit;
-
-  @override
-  bool get isStatic => true;
-
-  @override
-  LibraryElementForLink get library => compilationUnit.library;
-
-  @override
-  TypeParameterizedElementMixin get _typeParameterContext => null;
-
-  /// Store the results of type inference for this variable in
-  /// [compilationUnit].
-  void link(CompilationUnitElementInBuildUnit compilationUnit) {
-    if (hasImplicitType) {
-      TypeInferenceNode typeInferenceNode = this._typeInferenceNode;
-      if (typeInferenceNode != null) {
-        compilationUnit._storeLinkedType(
-            unlinkedVariable.inferredTypeSlot, inferredType, null);
-        compilationUnit._storeLinkedTypeError(
-            unlinkedVariable.inferredTypeSlot, initializer._inferenceError);
-      }
-      initializer?.link(compilationUnit);
-    }
-  }
-}
-
-/// Specialization of [DependencyWalker] for performing type inference on static
-/// and top level variables.
-class TypeInferenceDependencyWalker
-    extends DependencyWalker<TypeInferenceNode> {
-  @override
-  void evaluate(TypeInferenceNode v) {
-    v.evaluate(null);
-  }
-
-  @override
-  void evaluateScc(List<TypeInferenceNode> scc) {
-    for (TypeInferenceNode v in scc) {
-      v.evaluate(scc);
-    }
-  }
-}
-
-/// Specialization of [Node] used to construct the type inference dependency
-/// graph.
-class TypeInferenceNode extends Node<TypeInferenceNode> {
-  /// The [FunctionElementForLink_Local] to which this node refers.
-  final FunctionElementForLink_Local functionElement;
-
-  TypeInferenceNode(this.functionElement);
-
-  @override
-  bool get isEvaluated => functionElement._hasTypeBeenInferred;
-
-  /// Collect the type inference dependencies in [unlinkedExecutable] (which
-  /// should be interpreted relative to [compilationUnit]) and store them in
-  /// [dependencies].
-  void collectDependencies(
-      List<TypeInferenceNode> dependencies,
-      UnlinkedExecutable unlinkedExecutable,
-      CompilationUnitElementForLink compilationUnit) {
-    UnlinkedExpr unlinkedConst = unlinkedExecutable?.bodyExpr;
-    if (unlinkedConst == null) {
-      return;
-    }
-    int refPtr = 0;
-    int intPtr = 0;
-
-    for (UnlinkedExprOperation operation in unlinkedConst.operations) {
-      switch (operation) {
-        case UnlinkedExprOperation.pushInt:
-          intPtr++;
-          break;
-        case UnlinkedExprOperation.pushLongInt:
-          int numInts = unlinkedConst.ints[intPtr++];
-          intPtr += numInts;
-          break;
-        case UnlinkedExprOperation.concatenate:
-          intPtr++;
-          break;
-        case UnlinkedExprOperation.pushReference:
-          EntityRef ref = unlinkedConst.references[refPtr++];
-          // TODO(paulberry): cache these resolved references for
-          // later use by evaluate().
-          TypeInferenceNode dependency =
-              compilationUnit.resolveRef(ref.reference).asTypeInferenceNode;
-          if (dependency != null) {
-            dependencies.add(dependency);
-          }
-          break;
-        case UnlinkedExprOperation.invokeConstructor:
-          refPtr++;
-          intPtr += 2;
-          break;
-        case UnlinkedExprOperation.makeUntypedList:
-        case UnlinkedExprOperation.makeUntypedMap:
-        case UnlinkedExprOperation.makeUntypedSet:
-        case UnlinkedExprOperation.makeUntypedSetOrMap:
-        case UnlinkedExprOperation.forParts:
-        case UnlinkedExprOperation.variableDeclaration:
-        case UnlinkedExprOperation.forInitializerDeclarationsUntyped:
-          intPtr++;
-          break;
-        case UnlinkedExprOperation.makeTypedList:
-        case UnlinkedExprOperation.makeTypedSet:
-        case UnlinkedExprOperation.forInitializerDeclarationsTyped:
-          refPtr++;
-          intPtr++;
-          break;
-        case UnlinkedExprOperation.makeTypedMap:
-        case UnlinkedExprOperation.makeTypedMap2:
-          refPtr += 2;
-          intPtr++;
-          break;
-        case UnlinkedExprOperation.assignToRef:
-          EntityRef ref = unlinkedConst.references[refPtr++];
-          // TODO(paulberry): cache these resolved references for
-          // later use by evaluate().
-          TypeInferenceNode dependency =
-              compilationUnit.resolveRef(ref.reference).asTypeInferenceNode;
-          if (dependency != null) {
-            dependencies.add(dependency);
-          }
-          break;
-        case UnlinkedExprOperation.invokeMethodRef:
-          EntityRef ref = unlinkedConst.references[refPtr++];
-          TypeInferenceNode dependency =
-              compilationUnit.resolveRef(ref.reference).asTypeInferenceNode;
-          if (dependency != null) {
-            dependencies.add(dependency);
-          }
-          intPtr += 2;
-          int numTypeArguments = unlinkedConst.ints[intPtr++];
-          refPtr += numTypeArguments;
-          break;
-        case UnlinkedExprOperation.invokeMethod:
-          intPtr += 2;
-          int numTypeArguments = unlinkedConst.ints[intPtr++];
-          refPtr += numTypeArguments;
-          break;
-        case UnlinkedExprOperation.typeCast:
-        case UnlinkedExprOperation.typeCheck:
-        case UnlinkedExprOperation.forEachPartsWithTypedDeclaration:
-          refPtr++;
-          break;
-        case UnlinkedExprOperation.pushLocalFunctionReference:
-          int popCount = unlinkedConst.ints[intPtr++];
-          assert(popCount == 0); // TODO(paulberry): handle the nonzero case.
-          dependencies.add(functionElement
-              .getLocalFunction(unlinkedConst.ints[intPtr++])
-              .asTypeInferenceNode);
-          break;
-        default:
-          break;
-      }
-    }
-    assert(refPtr == unlinkedConst.references.length);
-    assert(intPtr == unlinkedConst.ints.length);
-  }
-
-  @override
-  List<TypeInferenceNode> computeDependencies() {
-    List<TypeInferenceNode> dependencies = <TypeInferenceNode>[];
-    collectDependencies(dependencies, functionElement.serializedExecutable,
-        functionElement.compilationUnit);
-    return dependencies;
-  }
-
-  void evaluate(List<TypeInferenceNode> cycle) {
-    if (cycle != null) {
-      List<String> cycleNames = cycle
-          .map((node) {
-            Element e = node.functionElement;
-            while (e != null) {
-              if (e is VariableElement) {
-                return e.name;
-              }
-              e = e.enclosingElement;
-            }
-            return '<unknown>';
-          })
-          .toSet()
-          .toList();
-      functionElement._setInferenceError(new TopLevelInferenceErrorBuilder(
-          kind: TopLevelInferenceErrorKind.dependencyCycle,
-          arguments: cycleNames));
-      functionElement._setInferredType(DynamicTypeImpl.instance);
-    } else {
-      var computer = new ExprTypeComputer(functionElement);
-      DartType bodyType = computer.compute();
-      if (computer.errorKind != null) {
-        functionElement._setInferenceError(
-            new TopLevelInferenceErrorBuilder(kind: computer.errorKind));
-        functionElement._setInferredType(DynamicTypeImpl.instance);
-      } else {
-        if (functionElement.isAsynchronous) {
-          var linker = functionElement.compilationUnit.library._linker;
-          var typeProvider = linker.typeProvider;
-          var typeSystem = linker.typeSystem;
-          if (bodyType.isDartAsyncFutureOr) {
-            bodyType = (bodyType as InterfaceType).typeArguments[0];
-          }
-          bodyType = typeProvider.futureType
-              .instantiate([typeSystem.flatten(bodyType)]);
-        }
-        functionElement._setInferredType(bodyType);
-      }
-    }
-  }
-
-  @override
-  String toString() => 'TypeInferenceNode($functionElement)';
-}
-
-class TypeProviderForLink extends TypeProviderBase {
-  final Linker _linker;
-
-  InterfaceType _boolType;
-  InterfaceType _deprecatedType;
-  InterfaceType _doubleType;
-  InterfaceType _functionType;
-  InterfaceType _futureDynamicType;
-  InterfaceType _futureNullType;
-  InterfaceType _futureOrNullType;
-  InterfaceType _futureOrType;
-  InterfaceType _futureType;
-  InterfaceType _intType;
-  InterfaceType _iterableDynamicType;
-  InterfaceType _iterableObjectType;
-  InterfaceType _iterableType;
-  InterfaceType _listType;
-  InterfaceType _mapType;
-  InterfaceType _mapObjectObjectType;
-  InterfaceType _nullType;
-  InterfaceType _numType;
-  InterfaceType _objectType;
-  InterfaceType _setType;
-  InterfaceType _stackTraceType;
-  InterfaceType _streamDynamicType;
-  InterfaceType _streamType;
-  InterfaceType _stringType;
-  InterfaceType _symbolType;
-  InterfaceType _typeType;
-
-  TypeProviderForLink(this._linker);
-
-  @override
-  InterfaceType get boolType =>
-      _boolType ??= _buildInterfaceType(_linker.coreLibrary, 'bool');
-
-  @override
-  DartType get bottomType => BottomTypeImpl.instance;
-
-  @override
-  InterfaceType get deprecatedType => _deprecatedType ??=
-      _buildInterfaceType(_linker.coreLibrary, 'Deprecated');
-
-  @override
-  InterfaceType get doubleType =>
-      _doubleType ??= _buildInterfaceType(_linker.coreLibrary, 'double');
-
-  @override
-  DartType get dynamicType => DynamicTypeImpl.instance;
-
-  @override
-  InterfaceType get functionType =>
-      _functionType ??= _buildInterfaceType(_linker.coreLibrary, 'Function');
-
-  @override
-  InterfaceType get futureDynamicType =>
-      _futureDynamicType ??= futureType.instantiate(<DartType>[dynamicType]);
-
-  @override
-  ClassElement get futureElement => futureType.element;
-
-  @override
-  InterfaceType get futureNullType =>
-      _futureNullType ??= futureType.instantiate(<DartType>[nullType]);
-
-  @override
-  ClassElement get futureOrElement => futureOrType.element;
-
-  @override
-  InterfaceType get futureOrNullType =>
-      _futureOrNullType ??= futureOrType.instantiate(<DartType>[nullType]);
-
-  @override
-  InterfaceType get futureOrType =>
-      _futureOrType ??= _buildInterfaceType(_linker.asyncLibrary, 'FutureOr');
-
-  @override
-  InterfaceType get futureType =>
-      _futureType ??= _buildInterfaceType(_linker.asyncLibrary, 'Future');
-
-  @override
-  InterfaceType get intType =>
-      _intType ??= _buildInterfaceType(_linker.coreLibrary, 'int');
-
-  @override
-  InterfaceType get iterableDynamicType => _iterableDynamicType ??=
-      iterableType.instantiate(<DartType>[dynamicType]);
-
-  @override
-  ClassElement get iterableElement => iterableType.element;
-
-  @override
-  InterfaceType get iterableObjectType =>
-      _iterableObjectType ??= iterableType.instantiate(<DartType>[objectType]);
-
-  @override
-  InterfaceType get iterableType =>
-      _iterableType ??= _buildInterfaceType(_linker.coreLibrary, 'Iterable');
-
-  @override
-  ClassElement get listElement => listType.element;
-
-  @override
-  InterfaceType get listType =>
-      _listType ??= _buildInterfaceType(_linker.coreLibrary, 'List');
-
-  @override
-  ClassElement get mapElement => mapType.element;
-
-  @override
-  InterfaceType get mapObjectObjectType => _mapObjectObjectType ??=
-      mapType.instantiate(<DartType>[objectType, objectType]);
-
-  @override
-  InterfaceType get mapType =>
-      _mapType ??= _buildInterfaceType(_linker.coreLibrary, 'Map');
-
-  @override
-  DartType get neverType => BottomTypeImpl.instance;
-
-  @override
-  DartObjectImpl get nullObject {
-    // TODO(paulberry): implement if needed
-    throw new UnimplementedError();
-  }
-
-  @override
-  InterfaceType get nullType =>
-      _nullType ??= _buildInterfaceType(_linker.coreLibrary, 'Null');
-
-  @override
-  InterfaceType get numType =>
-      _numType ??= _buildInterfaceType(_linker.coreLibrary, 'num');
-
-  @override
-  InterfaceType get objectType =>
-      _objectType ??= _buildInterfaceType(_linker.coreLibrary, 'Object');
-
-  @override
-  ClassElement get setElement => setType.element;
-
-  @override
-  InterfaceType get setType =>
-      _setType ??= _buildInterfaceType(_linker.coreLibrary, 'Set');
-
-  @override
-  InterfaceType get stackTraceType => _stackTraceType ??=
-      _buildInterfaceType(_linker.coreLibrary, 'StackTrace');
-
-  @override
-  InterfaceType get streamDynamicType =>
-      _streamDynamicType ??= streamType.instantiate(<DartType>[dynamicType]);
-
-  @override
-  ClassElement get streamElement => streamType.element;
-
-  @override
-  InterfaceType get streamType =>
-      _streamType ??= _buildInterfaceType(_linker.asyncLibrary, 'Stream');
-
-  @override
-  InterfaceType get stringType =>
-      _stringType ??= _buildInterfaceType(_linker.coreLibrary, 'String');
-
-  @override
-  ClassElement get symbolElement => symbolType.element;
-
-  @override
-  InterfaceType get symbolType =>
-      _symbolType ??= _buildInterfaceType(_linker.coreLibrary, 'Symbol');
-
-  @override
-  InterfaceType get typeType =>
-      _typeType ??= _buildInterfaceType(_linker.coreLibrary, 'Type');
-
-  @override
-  VoidType get voidType => VoidTypeImpl.instance;
-
-  @override
-  InterfaceType futureOrType2(DartType valueType) {
-    return futureOrType.instantiate([valueType]);
-  }
-
-  @override
-  InterfaceType futureType2(DartType valueType) {
-    return futureType.instantiate([valueType]);
-  }
-
-  @override
-  InterfaceType iterableType2(DartType elementType) {
-    return iterableType.instantiate([elementType]);
-  }
-
-  @override
-  InterfaceType listType2(DartType elementType) {
-    return listType.instantiate([elementType]);
-  }
-
-  @override
-  InterfaceType mapType2(DartType keyType, DartType valueType) {
-    return mapType.instantiate([keyType, valueType]);
-  }
-
-  @override
-  InterfaceType setType2(DartType elementType) {
-    return setType.instantiate([elementType]);
-  }
-
-  @override
-  InterfaceType streamType2(DartType elementType) {
-    return streamType.instantiate([elementType]);
-  }
-
-  InterfaceType _buildInterfaceType(
-      LibraryElementForLink library, String name) {
-    return library.getContainedName(name).buildType((int i) {
-      // TODO(scheglov) accept type parameter names
-      var element = new TypeParameterElementImpl('T$i', -1);
-      return new TypeParameterTypeImpl(element);
-    }, const []);
-  }
-}
-
-/// Singleton element used for unresolved references.
-class UndefinedElementForLink with ReferenceableElementForLink {
-  static final UndefinedElementForLink instance =
-      new UndefinedElementForLink._();
-
-  UndefinedElementForLink._();
-
-  @override
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
-
-/// Element representing a top level variable resynthesized from a
-/// summary during linking.
-abstract class VariableElementForLink
-    implements NonParameterVariableElementImpl, PropertyInducingElement {
-  /// The unlinked representation of the variable in the summary.
-  final UnlinkedVariable unlinkedVariable;
-
-  /// If non-null, the AST for the initializer expression; this is used for
-  /// inferring the expression type.
-  final Expression _initializerForInference;
-
-  /// If this variable is declared `const` and the enclosing library is
-  /// part of the build unit being linked, the variable's node in the
-  /// constant evaluation dependency graph.  Otherwise `null`.
-  ConstNode _constNode;
-
-  /// If this variable has an initializer and an implicit type, and the
-  /// enclosing library is part of the build unit being linked, the variable's
-  /// node in the type inference dependency graph.  Otherwise `null`.
-  TypeInferenceNode _typeInferenceNode;
-
-  FunctionElementForLink_Initializer _initializer;
-  DartType _inferredType;
-  DartType _declaredType;
-  PropertyAccessorElementForLink_Variable _getter;
-  PropertyAccessorElementForLink_Variable _setter;
-
-  /// The compilation unit in which this variable appears.
-  final CompilationUnitElementForLink compilationUnit;
-
-  VariableElementForLink(this.unlinkedVariable, this.compilationUnit,
-      this._initializerForInference) {
-    if (!compilationUnit.isInBuildUnit) return;
-    if (unlinkedVariable.initializer?.bodyExpr == null) {
-      if (_initializerForInference == null) return;
-    } else {
-      _constNode = new ConstVariableNode(this);
-    }
-    if (unlinkedVariable.type == null) {
-      _typeInferenceNode = initializer.asTypeInferenceNode;
-    }
-  }
-
-  /// If the variable has an explicitly declared return type, return it.
-  /// Otherwise return `null`.
-  DartType get declaredType {
-    if (unlinkedVariable.type == null) {
-      return null;
-    } else {
-      return _declaredType ??=
-          compilationUnit.resolveTypeRef(this, unlinkedVariable.type);
-    }
-  }
-
-  @override
-  String get displayName => unlinkedVariable.name;
-
-  @override
-  PropertyAccessorElementForLink_Variable get getter =>
-      _getter ??= new PropertyAccessorElementForLink_Variable(this, false);
-
-  @override
-  bool get hasImplicitType => unlinkedVariable.type == null;
-
-  @override
-  String get identifier => unlinkedVariable.name;
-
-  /// Return the inferred type of the variable element.  Should only be called
-  /// if no type was explicitly declared.
-  DartType get inferredType {
-    // We should only try to infer a type when none is explicitly declared.
-    assert(unlinkedVariable.type == null);
-    if (_inferredType == null) {
-      if (_typeInferenceNode != null) {
-        assert(Linker._initializerTypeInferenceCycle == null);
-        Linker._initializerTypeInferenceCycle =
-            compilationUnit.library.libraryCycleForLink;
-        Linker._isPerformingVariableTypeInference = true;
-        try {
-          new TypeInferenceDependencyWalker().walk(_typeInferenceNode);
-          assert(_inferredType != null);
-        } finally {
-          Linker._initializerTypeInferenceCycle = null;
-          Linker._isPerformingVariableTypeInference = false;
-        }
-      } else if (compilationUnit.isInBuildUnit) {
-        _inferredType = DynamicTypeImpl.instance;
-      } else {
-        _inferredType = compilationUnit.getLinkedType(
-            this, unlinkedVariable.inferredTypeSlot);
-      }
-    }
-    return _inferredType;
-  }
-
-  @override
-  FunctionElementForLink_Initializer get initializer {
-    if (unlinkedVariable.initializer == null) {
-      return null;
-    } else {
-      return _initializer ??= new FunctionElementForLink_Initializer(
-          this, _initializerForInference);
-    }
-  }
-
-  @override
-  bool get isConst => unlinkedVariable.isConst;
-
-  /// Return `true` if this variable is a field that was explicitly marked as
-  /// being covariant (in the setter's parameter).
-  bool get isCovariant => unlinkedVariable.isCovariant;
-
-  @override
-  bool get isFinal => unlinkedVariable.isFinal;
-
-  @override
-  bool get isStatic;
-
-  @override
-  bool get isSynthetic => false;
-
-  @override
-  String get name => unlinkedVariable.name;
-
-  @override
-  DartType get propagatedType {
-    return DynamicTypeImpl.instance;
-  }
-
-  @override
-  PropertyAccessorElementForLink_Variable get setter {
-    if (!isConst && !isFinal) {
-      return _setter ??=
-          new PropertyAccessorElementForLink_Variable(this, true);
-    } else {
-      return null;
-    }
-  }
-
-  @override
-  DartType get type => declaredType ?? inferredType;
-
-  @override
-  void set type(DartType newType) {
-    // TODO(paulberry): store inferred type.
-  }
-
-  @override
-  TypeParameterizedElementMixin get typeParameterContext {
-    return _typeParameterContext;
-  }
-
-  /// The context in which type parameters should be interpreted, or `null` if
-  /// there are no type parameters in scope.
-  TypeParameterizedElementMixin get _typeParameterContext;
-
-  @override
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-
-  @override
-  String toString() => '$enclosingElement.$name';
-}
-
-/// Specialization of [LibraryResynthesizer] for resynthesis during linking.
-class _LibraryResynthesizer extends LibraryResynthesizerMixin {
-  LibraryElementForLink _library;
-
-  @override
-  LibraryElement get library => _library;
-
-  @override
-  List<LinkedExportName> get linkedExportNames => _library._linkedExportNames;
-
-  @override
-  Element buildExportName(LinkedExportName exportName) {
-    LibraryElementForLink dependency =
-        _library.buildImportedLibrary(exportName.dependency);
-    return dependency.getContainedName(exportName.name);
-  }
-}
-
-/// Specialization of [ReferenceInfo] for resynthesis during linking.
-class _ReferenceInfo extends ReferenceInfo {
-  @override
-  final ReferenceableElementForLink element;
-
-  @override
-  final ReferenceInfo enclosing;
-
-  @override
-  final String name;
-
-  @override
-  final bool hasTypeParameters;
-
-  _ReferenceInfo(
-      this.enclosing, this.element, this.name, this.hasTypeParameters);
-
-  /// TODO(paulberry): this method doesn't seem to be used.  Investigate whether
-  /// it is needed.
-  @override
-  DartType get type => throw new UnimplementedError();
-}
-
-/// Specialization of [UnitResynthesizer] for resynthesis during linking.
-class _UnitResynthesizer extends UnitResynthesizer with UnitResynthesizerMixin {
-  CompilationUnitElementForLink _unit;
-
-  @override
-  LibraryElement get library => _unit.library;
-
-  @override
-  TypeProvider get typeProvider => _unit.library._linker.typeProvider;
-
-  @override
-  TypeSystem get typeSystem => _unit.library._linker._typeSystem;
-
-  @override
-  DartType buildType(ElementImpl context, EntityRef type) =>
-      _unit.resolveTypeRef(context, type);
-
-  @override
-  DartType buildTypeForClassInfo(
-      info, int numTypeArguments, DartType Function(int i) getTypeArgument) {
-    ClassElementForLink class_ = info.element;
-    if (numTypeArguments == 0) {
-      DartType type = class_.typeWithDefaultBounds;
-      _typesWithImplicitArguments[type] = true;
-      return type;
-    }
-    return class_.buildType(getTypeArgument, const []);
-  }
-
-  @override
-  bool doesTypeHaveImplicitArguments(ParameterizedType type) =>
-      _typesWithImplicitArguments[type] != null;
-
-  @override
-  _ReferenceInfo getReferenceInfo(int index) {
-    return _unit.resolveRefToInfo(index);
-  }
-}
diff --git a/pkg/analyzer/lib/src/summary/package_bundle_reader.dart b/pkg/analyzer/lib/src/summary/package_bundle_reader.dart
index 4de81f7..ca70dd2 100644
--- a/pkg/analyzer/lib/src/summary/package_bundle_reader.dart
+++ b/pkg/analyzer/lib/src/summary/package_bundle_reader.dart
@@ -5,15 +5,12 @@
 import 'dart:io' as io;
 import 'dart:math' show min;
 
-import 'package:analyzer/dart/analysis/session.dart';
 import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/src/dart/analysis/driver.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/source_io.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart';
 import 'package:analyzer/src/summary/idl.dart';
-import 'package:analyzer/src/summary/resynthesize.dart';
 
 /**
  * A [ConflictingSummaryException] indicates that two different summaries
@@ -131,54 +128,15 @@
   Source resolveAbsolute(Uri uri, [Uri actualUri]) {
     actualUri ??= uri;
     String uriString = uri.toString();
-    if (AnalysisDriver.useSummary2) {
-      String summaryPath = _dataStore.uriToSummaryPath[uriString];
-      if (summaryPath != null) {
-        return new InSummarySource(actualUri, summaryPath);
-      }
-    } else {
-      UnlinkedUnit unit = _dataStore.unlinkedMap[uriString];
-      if (unit != null) {
-        String summaryPath = _dataStore.uriToSummaryPath[uriString];
-        return new InSummarySource(actualUri, summaryPath);
-      }
+    String summaryPath = _dataStore.uriToSummaryPath[uriString];
+    if (summaryPath != null) {
+      return new InSummarySource(actualUri, summaryPath);
     }
     return null;
   }
 }
 
 /**
- * A concrete resynthesizer that serves summaries from [SummaryDataStore].
- */
-class StoreBasedSummaryResynthesizer extends SummaryResynthesizer {
-  final SummaryDataStore _dataStore;
-
-  StoreBasedSummaryResynthesizer(
-      AnalysisContext context,
-      AnalysisSession session,
-      SourceFactory sourceFactory,
-      bool _,
-      this._dataStore)
-      : super(context, session, sourceFactory, true);
-
-  @override
-  LinkedLibrary getLinkedSummary(String uri) {
-    return _dataStore.linkedMap[uri];
-  }
-
-  @override
-  UnlinkedUnit getUnlinkedSummary(String uri) {
-    return _dataStore.unlinkedMap[uri];
-  }
-
-  @override
-  bool hasLibrarySummary(String uri) {
-    LinkedLibrary linkedLibrary = _dataStore.linkedMap[uri];
-    return linkedLibrary != null;
-  }
-}
-
-/**
  * A [SummaryDataStore] is a container for the data extracted from a set of
  * summary package bundles.  It contains maps which can be used to find linked
  * and unlinked summaries by URI.
@@ -319,11 +277,7 @@
    * with the given absolute [uri].
    */
   bool hasLinkedLibrary(String uri) {
-    if (AnalysisDriver.useSummary2) {
-      return _libraryUris.contains(uri);
-    } else {
-      return linkedMap.containsKey(uri);
-    }
+    return _libraryUris.contains(uri);
   }
 
   /**
@@ -331,22 +285,14 @@
    * with the given absolute [uri].
    */
   bool hasUnlinkedUnit(String uri) {
-    if (AnalysisDriver.useSummary2) {
-      return uriToSummaryPath.containsKey(uri);
-    } else {
-      return unlinkedMap.containsKey(uri);
-    }
+    return uriToSummaryPath.containsKey(uri);
   }
 
   /**
    * Return `true` if the unit with the [uri] is a part unit in the store.
    */
   bool isPartUnit(String uri) {
-    if (AnalysisDriver.useSummary2) {
-      return _partUris.contains(uri);
-    } else {
-      return !linkedMap.containsKey(uri);
-    }
+    return _partUris.contains(uri);
   }
 
   void _fillMaps(String path, ResourceProvider resourceProvider) {
diff --git a/pkg/analyzer/lib/src/summary/prelink.dart b/pkg/analyzer/lib/src/summary/prelink.dart
deleted file mode 100644
index b0116e6..0000000
--- a/pkg/analyzer/lib/src/summary/prelink.dart
+++ /dev/null
@@ -1,723 +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 'package:analyzer/dart/analysis/declared_variables.dart';
-import 'package:analyzer/src/generated/utilities_dart.dart';
-import 'package:analyzer/src/summary/format.dart';
-import 'package:analyzer/src/summary/idl.dart';
-import 'package:analyzer/src/summary/name_filter.dart';
-
-/**
- * Create a [LinkedLibraryBuilder] corresponding to the given [definingUnitUri]
- * and [definingUnit], which should be the defining compilation unit for a
- * library. Compilation units referenced by the defining compilation unit via
- * `part` declarations will be retrieved using [getPart].  Public namespaces
- * for libraries referenced by the defining compilation unit via `import`
- * declarations (and files reachable from them via `part` and `export`
- * declarations) will be retrieved using [getImport].
- */
-LinkedLibraryBuilder prelink(
-    String definingUnitUri,
-    UnlinkedUnit definingUnit,
-    GetPartCallback getPart,
-    GetImportCallback getImport,
-    DeclaredVariables declaredVariables) {
-  return new _Prelinker(
-          definingUnitUri, definingUnit, getPart, getImport, declaredVariables)
-      .prelink();
-}
-
-/**
- * Type of the callback used by the prelinker to obtain public namespace
- * information about libraries with the given [absoluteUri] imported by the
- * library to be prelinked (and the transitive closure of parts and exports
- * reachable from those libraries).
- *
- * If no file exists at the given uri, `null` should be returned.
- */
-typedef UnlinkedPublicNamespace GetImportCallback(String absoluteUri);
-
-/**
- * Type of the callback used by the prelinker to obtain unlinked summaries of
- * part files of the library to be prelinked.
- *
- * If no file exists at the given uri, `null` should be returned.
- */
-typedef UnlinkedUnit GetPartCallback(String absoluteUri);
-
-/**
- * A [_Meaning] representing a class.
- */
-class _ClassMeaning extends _Meaning {
-  final _Namespace namespace;
-
-  _ClassMeaning(int unit, int dependency, int numTypeParameters, this.namespace)
-      : super(unit, ReferenceKind.classOrEnum, dependency, numTypeParameters);
-}
-
-/**
- * A node in computing exported namespaces.
- */
-class _ExportNamespace {
-  static int nextId = 0;
-
-  /**
-   * The export namespace, full (with all exports included), or partial (with
-   * public namespace, and only some of the exports included).
-   */
-  final _Namespace namespace;
-
-  /**
-   * This field is set to non-zero when we start computing the export namespace
-   * for the corresponding library, and is set back to zero when we finish
-   * computation.
-   */
-  int id = 0;
-
-  /**
-   * Whether the [namespace] is full, so we don't need chasing exports.
-   */
-  bool isFull = false;
-
-  _ExportNamespace(this.namespace);
-}
-
-/**
- * A [_Meaning] stores all the information necessary to find the declaration
- * referred to by a name in a namespace.
- */
-class _Meaning {
-  /**
-   * Which unit in the dependent library contains the declared entity.
-   */
-  final int unit;
-
-  /**
-   * The kind of entity being referred to.
-   */
-  final ReferenceKind kind;
-
-  /**
-   * Which of the dependencies of the library being prelinked contains the
-   * declared entity.
-   */
-  final int dependency;
-
-  /**
-   * If the entity being referred to is generic, the number of type parameters
-   * it accepts.  Otherwise zero.
-   */
-  final int numTypeParameters;
-
-  _Meaning(this.unit, this.kind, this.dependency, this.numTypeParameters);
-
-  /**
- * Encode this [_Meaning] as a [LinkedExportName], using the given [name].
- */
-  LinkedExportName encodeExportName(String name) {
-    return new LinkedExportNameBuilder(
-        name: name, dependency: dependency, unit: unit, kind: kind);
-  }
-
-/**
-   * Encode this [_Meaning] as a [LinkedReference].
-   */
-  LinkedReferenceBuilder encodeReference() {
-    return new LinkedReferenceBuilder(
-        unit: unit,
-        kind: kind,
-        dependency: dependency,
-        numTypeParameters: numTypeParameters);
-  }
-}
-
-/**
- * Mapping from names to corresponding unique [_Meaning]s.
- */
-class _Namespace {
-  final Set<String> namesWithConflictingDefinitions = new Set<String>();
-  final Set<String> libraryNames = new Set<String>();
-  final Map<String, _Meaning> map = <String, _Meaning>{};
-
-  /**
-   * Return the [_Meaning] of the name, or `null` is not defined.
-   */
-  _Meaning operator [](String name) {
-    return map[name];
-  }
-
-  /**
-   * Define that the [name] has the given [value].  If the [name] already been
-   * defined with a different value, then it becomes undefined.
-   */
-  void add(String name, _Meaning value) {
-    // Already determined to be a conflict.
-    if (namesWithConflictingDefinitions.contains(name)) {
-      return;
-    }
-
-    _Meaning currentValue = map[name];
-    if (currentValue == null) {
-      map[name] = value;
-    } else if (currentValue == value) {
-      // The same value, ignore.
-    } else {
-      // A conflict, remember it, and un-define the name.
-      namesWithConflictingDefinitions.add(name);
-      map.remove(name);
-    }
-  }
-
-  /**
-   * Return `true` if the [name] was defined before [rememberLibraryNames]
-   * invocation.
-   */
-  bool definesLibraryName(String name) => libraryNames.contains(name);
-
-  /**
-   * Return `true` if the [name] is already defined.
-   */
-  bool definesName(String name) => map.containsKey(name);
-
-  /**
-   * Apply [f] to each name-meaning pair.
-   */
-  void forEach(void f(String key, _Meaning value)) {
-    map.forEach(f);
-  }
-
-  /**
-   * This method should be invoked after defining all names that are defined
-   * in a library, before defining imported names.
-   */
-  void rememberLibraryNames() {
-    libraryNames.addAll(map.keys);
-  }
-}
-
-/**
- * A [_Meaning] representing a prefix introduced by an import directive.
- */
-class _PrefixMeaning extends _Meaning {
-  final _Namespace namespace = new _Namespace();
-
-  _PrefixMeaning() : super(0, ReferenceKind.prefix, 0, 0);
-}
-
-/**
- * Helper class containing temporary data structures needed to prelink a single
- * library.
- */
-class _Prelinker {
-  final String definingUnitUri;
-  final UnlinkedUnit definingUnit;
-  final GetPartCallback getPart;
-  final GetImportCallback getImport;
-  final DeclaredVariables declaredVariables;
-
-  /**
-   * Cache of values returned by [getImport].
-   */
-  final Map<String, UnlinkedPublicNamespace> importCache =
-      <String, UnlinkedPublicNamespace>{};
-
-  /**
-   * Cache of values returned by [getPart].
-   */
-  final Map<String, UnlinkedUnit> partCache = <String, UnlinkedUnit>{};
-
-  /**
-   * Names defined inside the library being prelinked.
-   */
-  final _Namespace privateNamespace = new _Namespace()
-    ..add('dynamic', new _Meaning(0, ReferenceKind.classOrEnum, 0, 0))
-    ..add('void', new _Meaning(0, ReferenceKind.classOrEnum, 0, 0));
-
-  /**
-   * List of dependencies of the library being prelinked.  This will be output
-   * to [LinkedLibrary.dependencies].
-   */
-  final List<LinkedDependencyBuilder> dependencies =
-      <LinkedDependencyBuilder>[];
-
-  /**
-   * Map from the absolute URI of a dependent library to the index of the
-   * corresponding entry in [dependencies].
-   */
-  final Map<String, int> uriToDependency = <String, int>{};
-
-  /**
-   * List of public namespaces corresponding to each entry in [dependencies].
-   */
-  final List<_Namespace> dependencyToPublicNamespace = <_Namespace>[];
-
-  /**
-   * Map from absolute URI of a library to its export namespace.
-   */
-  final Map<String, _ExportNamespace> exportNamespaces = {};
-
-  _Prelinker(this.definingUnitUri, this.definingUnit, this.getPart,
-      this.getImport, this.declaredVariables) {
-    partCache[definingUnitUri] = definingUnit;
-    importCache[definingUnitUri] = definingUnit.publicNamespace;
-  }
-
-  void addClassToPrivateNamespace(int unitNum, UnlinkedClass cls) {
-    _Namespace namespace = new _Namespace();
-    cls.fields.forEach((field) {
-      if (field.isStatic && field.isConst) {
-        namespace.add(field.name,
-            new _Meaning(unitNum, ReferenceKind.propertyAccessor, 0, 0));
-      }
-    });
-    cls.executables.forEach((executable) {
-      ReferenceKind kind = null;
-      if (executable.kind == UnlinkedExecutableKind.constructor) {
-        kind = ReferenceKind.constructor;
-      } else if (executable.kind == UnlinkedExecutableKind.functionOrMethod &&
-          executable.isStatic) {
-        kind = ReferenceKind.method;
-      } else if (executable.kind == UnlinkedExecutableKind.getter &&
-          executable.isStatic) {
-        kind = ReferenceKind.propertyAccessor;
-      }
-      if (kind != null && executable.name.isNotEmpty) {
-        namespace.add(executable.name,
-            new _Meaning(unitNum, kind, 0, executable.typeParameters.length));
-      }
-    });
-    privateNamespace.add(cls.name,
-        new _ClassMeaning(unitNum, 0, cls.typeParameters.length, namespace));
-  }
-
-  /**
-   * Compute the public namespace for the library whose URI is reachable from
-   * [definingUnit] via [absoluteUri], by aggregating together public namespace
-   * information from all of its parts.
-   */
-  _Namespace aggregatePublicNamespace(String absoluteUri) {
-    if (uriToDependency.containsKey(absoluteUri)) {
-      return dependencyToPublicNamespace[uriToDependency[absoluteUri]];
-    }
-    assert(dependencies.length == dependencyToPublicNamespace.length);
-    int dependency = dependencies.length;
-    uriToDependency[absoluteUri] = dependency;
-    List<String> unitUris = getUnitUris(absoluteUri);
-    LinkedDependencyBuilder linkedDependency = new LinkedDependencyBuilder(
-        uri: absoluteUri,
-        parts: unitUris.skip(1).map((uri) => uri ?? '').toList());
-    dependencies.add(linkedDependency);
-
-    _Namespace aggregated = new _Namespace();
-
-    for (int unitNum = 0; unitNum < unitUris.length; unitNum++) {
-      String unitUri = unitUris[unitNum];
-      UnlinkedPublicNamespace importedNamespace = getImportCached(unitUri);
-      if (importedNamespace == null) {
-        continue;
-      }
-      for (UnlinkedPublicName name in importedNamespace.names) {
-        if (name.kind == ReferenceKind.classOrEnum) {
-          _Namespace namespace = new _Namespace();
-          name.members.forEach((executable) {
-            namespace.add(
-                executable.name,
-                new _Meaning(
-                    unitNum, executable.kind, 0, executable.numTypeParameters));
-          });
-          aggregated.add(
-              name.name,
-              new _ClassMeaning(
-                  unitNum, dependency, name.numTypeParameters, namespace));
-        } else {
-          aggregated.add(
-              name.name,
-              new _Meaning(
-                  unitNum, name.kind, dependency, name.numTypeParameters));
-        }
-      }
-    }
-
-    aggregated.rememberLibraryNames();
-
-    dependencyToPublicNamespace.add(aggregated);
-    return aggregated;
-  }
-
-  /**
-   * Compute the export namespace for the library whose URI is reachable from
-   * [definingUnit] via [absoluteUri], by aggregating together public namespace
-   * information from the library and the transitive closure of its exports.
-   */
-  _Namespace computeExportNamespace(String absoluteUri) {
-    int firstCycleIdOfLastCall = 0;
-    _Namespace chaseExports(String absoluteUri) {
-      _ExportNamespace exportNamespace = getExportNamespace(absoluteUri);
-
-      // If the export namespace is ready, return it.
-      if (exportNamespace.isFull) {
-        firstCycleIdOfLastCall = 0;
-        return exportNamespace.namespace;
-      }
-
-      // If we are computing the export namespace for this library, and we
-      // reached here, then we found a cycle.
-      if (exportNamespace.id != 0) {
-        firstCycleIdOfLastCall = exportNamespace.id;
-        return null;
-      }
-
-      // Give each library a unique identifier.
-      exportNamespace.id = _ExportNamespace.nextId++;
-
-      // Append from exports.
-      int firstCycleId = 0;
-      UnlinkedPublicNamespace publicNamespace = getImportCached(absoluteUri);
-      if (publicNamespace != null) {
-        for (UnlinkedExportPublic export in publicNamespace.exports) {
-          String unlinkedExportUri =
-              _selectUri(export.uri, export.configurations);
-          String exportUri = resolveUri(absoluteUri, unlinkedExportUri);
-          if (exportUri != null) {
-            NameFilter filter =
-                new NameFilter.forUnlinkedCombinators(export.combinators);
-            _Namespace exported = chaseExports(exportUri);
-            exported?.forEach((String name, _Meaning meaning) {
-              if (filter.accepts(name) &&
-                  !exportNamespace.namespace.definesLibraryName(name)) {
-                exportNamespace.namespace.add(name, meaning);
-              }
-            });
-            if (firstCycleIdOfLastCall != 0) {
-              if (firstCycleId == 0 || firstCycleId > firstCycleIdOfLastCall) {
-                firstCycleId = firstCycleIdOfLastCall;
-              }
-            }
-          }
-        }
-      }
-
-      // If this library is the first component of the cycle, then we are at
-      // the beginning of this cycle, and combination of partial export
-      // namespaces of other exported libraries and declarations of this
-      // library is the full export namespace of this library.
-      if (firstCycleId != 0 && firstCycleId == exportNamespace.id) {
-        firstCycleId = 0;
-      }
-
-      // We're done with this library, successfully or not.
-      exportNamespace.id = 0;
-
-      // If no cycle detected in exports, mark the export namespace as full.
-      if (firstCycleId == 0) {
-        exportNamespace.isFull = true;
-      }
-
-      // Return the full or partial result.
-      firstCycleIdOfLastCall = firstCycleId;
-      return exportNamespace.namespace;
-    }
-
-    _ExportNamespace.nextId = 1;
-    return chaseExports(absoluteUri);
-  }
-
-  /**
-   * Extract all the names defined in [unit] (which is the [unitNum]th unit in
-   * the library being prelinked) and store them in [privateNamespace].
-   * Excludes names introduced by `import` statements.
-   */
-  void extractPrivateNames(UnlinkedUnit unit, int unitNum) {
-    for (UnlinkedClass cls in unit.classes) {
-      addClassToPrivateNamespace(unitNum, cls);
-    }
-    for (UnlinkedEnum enm in unit.enums) {
-      _Namespace namespace = new _Namespace();
-      enm.values.forEach((UnlinkedEnumValue value) {
-        namespace.add(value.name,
-            new _Meaning(unitNum, ReferenceKind.propertyAccessor, 0, 0));
-      });
-      namespace.add('values',
-          new _Meaning(unitNum, ReferenceKind.propertyAccessor, 0, 0));
-      privateNamespace.add(
-          enm.name, new _ClassMeaning(unitNum, 0, 0, namespace));
-    }
-    for (UnlinkedExecutable executable in unit.executables) {
-      privateNamespace.add(
-          executable.name,
-          new _Meaning(
-              unitNum,
-              executable.kind == UnlinkedExecutableKind.functionOrMethod
-                  ? ReferenceKind.topLevelFunction
-                  : ReferenceKind.topLevelPropertyAccessor,
-              0,
-              executable.typeParameters.length));
-    }
-    for (UnlinkedClass mixin in unit.mixins) {
-      addClassToPrivateNamespace(unitNum, mixin);
-    }
-    for (UnlinkedTypedef typedef in unit.typedefs) {
-      ReferenceKind kind;
-      switch (typedef.style) {
-        case TypedefStyle.functionType:
-          kind = ReferenceKind.typedef;
-          break;
-        case TypedefStyle.genericFunctionType:
-          kind = ReferenceKind.genericFunctionTypedef;
-          break;
-      }
-      assert(kind != null);
-      privateNamespace.add(typedef.name,
-          new _Meaning(unitNum, kind, 0, typedef.typeParameters.length));
-    }
-    for (UnlinkedVariable variable in unit.variables) {
-      privateNamespace.add(variable.name,
-          new _Meaning(unitNum, ReferenceKind.topLevelPropertyAccessor, 0, 0));
-      if (!(variable.isConst || variable.isFinal)) {
-        privateNamespace.add(
-            variable.name + '=',
-            new _Meaning(
-                unitNum, ReferenceKind.topLevelPropertyAccessor, 0, 0));
-      }
-    }
-  }
-
-  /**
-   * Filter the export namespace for the library whose URI is reachable the
-   * given [absoluteUri], retaining only those names accepted by
-   * [combinators], and store the resulting names in [result].  Names that
-   * already exist in [result] are not overwritten.
-   */
-  void filterExportNamespace(String absoluteUri,
-      List<UnlinkedCombinator> combinators, _Namespace result) {
-    _Namespace exportNamespace = computeExportNamespace(absoluteUri);
-    if (result == null) {
-      // This can happen if the import prefix was shadowed by a local name, so
-      // the imported symbols are inaccessible.
-      return;
-    }
-    NameFilter filter = new NameFilter.forUnlinkedCombinators(combinators);
-    exportNamespace.forEach((String name, _Meaning meaning) {
-      if (filter.accepts(name) && !result.definesLibraryName(name)) {
-        result.add(name, meaning);
-      }
-    });
-  }
-
-  /**
-   * Return the [_ExportNamespace] for the library with the given [absoluteUri].
-   * The export namespace might be full (will all exports included), or
-   * partial (with public namespace, and only some of the exports included).
-   */
-  _ExportNamespace getExportNamespace(String absoluteUri) {
-    _ExportNamespace exportNamespace = exportNamespaces[absoluteUri];
-    if (exportNamespace == null) {
-      _Namespace publicNamespace = aggregatePublicNamespace(absoluteUri);
-      exportNamespace = new _ExportNamespace(publicNamespace);
-      exportNamespaces[absoluteUri] = exportNamespace;
-    }
-    return exportNamespace;
-  }
-
-  /**
-   * Wrapper around [getImport] that caches the return value in [importCache].
-   */
-  UnlinkedPublicNamespace getImportCached(String absoluteUri) {
-    return importCache.putIfAbsent(absoluteUri, () => getImport(absoluteUri));
-  }
-
-  /**
-   * Wrapper around [getPart] that caches the return value in [partCache] and
-   * updates [importCache] appropriately.
-   */
-  UnlinkedUnit getPartCached(String absoluteUri) {
-    return partCache.putIfAbsent(absoluteUri, () {
-      UnlinkedUnit unit = getPart(absoluteUri);
-      importCache[absoluteUri] = unit?.publicNamespace;
-      return unit;
-    });
-  }
-
-  /**
-   * Compute the set of absolute URIs of all the compilation units in the
-   * library whose URI is reachable from [definingUnit] via [absoluteUri].
-   */
-  List<String> getUnitUris(String absoluteUri) {
-    List<String> result = <String>[absoluteUri];
-    UnlinkedPublicNamespace publicNamespace = getImportCached(absoluteUri);
-    if (publicNamespace != null) {
-      result.addAll(publicNamespace.parts.map((String uri) {
-        return resolveUri(absoluteUri, uri);
-      }));
-    }
-    return result;
-  }
-
-  /**
-   * Process a single `import` declaration in the library being prelinked.  The
-   * return value is the index of the imported library in [dependencies].
-   */
-  int handleImport(UnlinkedImport import) {
-    String unlinkedUri = import.isImplicit
-        ? 'dart:core'
-        : _selectUri(import.uri, import.configurations);
-    String absoluteUri = resolveUri(definingUnitUri, unlinkedUri);
-
-    _Namespace targetNamespace = null;
-    if (import.prefixReference != 0) {
-      // The name introduced by an import declaration can't have a prefix of
-      // its own.
-      assert(
-          definingUnit.references[import.prefixReference].prefixReference == 0);
-      String prefix = definingUnit.references[import.prefixReference].name;
-      _Meaning prefixMeaning = privateNamespace[prefix];
-      if (prefixMeaning is _PrefixMeaning) {
-        targetNamespace = prefixMeaning.namespace;
-      }
-    } else {
-      targetNamespace = privateNamespace;
-    }
-    filterExportNamespace(absoluteUri, import.combinators, targetNamespace);
-    return uriToDependency[absoluteUri];
-  }
-
-  /**
-   * Produce a [LinkedUnit] for the given [unit], by resolving every one of
-   * its references.
-   */
-  LinkedUnitBuilder linkUnit(UnlinkedUnit unit) {
-    if (unit == null) {
-      return new LinkedUnitBuilder();
-    }
-    Map<int, _Namespace> prefixNamespaces = <int, _Namespace>{};
-    List<LinkedReferenceBuilder> references = <LinkedReferenceBuilder>[];
-    for (int i = 0; i < unit.references.length; i++) {
-      UnlinkedReference reference = unit.references[i];
-      _Namespace namespace;
-      if (reference.prefixReference == 0) {
-        namespace = privateNamespace;
-      } else {
-        // Prefix references must always point backward.
-        assert(reference.prefixReference < i);
-        namespace = prefixNamespaces[reference.prefixReference];
-        // Expressions like 'a.b.c.d' cannot be prelinked.
-        namespace ??= new _Namespace();
-      }
-      _Meaning meaning = namespace[reference.name];
-      if (meaning != null) {
-        if (meaning is _PrefixMeaning) {
-          prefixNamespaces[i] = meaning.namespace;
-        } else if (meaning is _ClassMeaning) {
-          prefixNamespaces[i] = meaning.namespace;
-        }
-        references.add(meaning.encodeReference());
-      } else {
-        references
-            .add(new LinkedReferenceBuilder(kind: ReferenceKind.unresolved));
-      }
-    }
-    return new LinkedUnitBuilder(references: references);
-  }
-
-  /**
-   * Form the [LinkedLibrary] for the [definingUnit] that was passed to the
-   * constructor.
-   */
-  LinkedLibraryBuilder prelink() {
-    aggregatePublicNamespace(definingUnitUri);
-
-    // Gather up the unlinked summaries for all the compilation units in the
-    // library.
-    List<String> unitUris = getUnitUris(definingUnitUri);
-    List<UnlinkedUnit> units = unitUris.map(getPartCached).toList();
-
-    // Create the private namespace for the library by gathering all the names
-    // defined in its compilation units.
-    for (int unitNum = 0; unitNum < units.length; unitNum++) {
-      UnlinkedUnit unit = units[unitNum];
-      if (unit != null) {
-        extractPrivateNames(unit, unitNum);
-      }
-    }
-
-    // Fill in exported names.  This must be done before filling in prefixes
-    // defined in import declarations, because prefixes shouldn't shadow
-    // exports.
-    List<LinkedExportNameBuilder> exportNames = <LinkedExportNameBuilder>[];
-    computeExportNamespace(definingUnitUri)
-        .forEach((String name, _Meaning meaning) {
-      if (!privateNamespace.definesName(name)) {
-        exportNames.add(meaning.encodeExportName(name));
-      }
-    });
-
-    // Fill in prefixes defined in import declarations.
-    for (UnlinkedImport import in units[0].imports) {
-      if (import.prefixReference != 0) {
-        String name = units[0].references[import.prefixReference].name;
-        if (!privateNamespace.definesName(name)) {
-          privateNamespace.add(name, new _PrefixMeaning());
-        }
-      }
-    }
-
-    // All the names defined so far are library local, they take precedence
-    // over anything imported from other libraries.
-    privateNamespace.rememberLibraryNames();
-
-    // Fill in imported and exported names.
-    List<int> importDependencies =
-        definingUnit.imports.map(handleImport).toList();
-    List<int> exportDependencies = definingUnit.publicNamespace.exports
-        .map((UnlinkedExportPublic exp) {
-          String unlinkedUri = _selectUri(exp.uri, exp.configurations);
-          String absoluteUri = resolveUri(definingUnitUri, unlinkedUri);
-          return uriToDependency[absoluteUri];
-        })
-        .where((dependency) => dependency != null)
-        .toList();
-
-    // Link each compilation unit.
-    List<LinkedUnitBuilder> linkedUnits = units.map(linkUnit).toList();
-
-    return new LinkedLibraryBuilder(
-        units: linkedUnits,
-        dependencies: dependencies,
-        importDependencies: importDependencies,
-        exportDependencies: exportDependencies,
-        exportNames: exportNames,
-        numPrelinkedDependencies: dependencies.length);
-  }
-
-  /**
-   * Resolve [relativeUri] relative to [containingUri].  Return `null` if
-   * [relativeUri] is invalid or empty, so cannot be resolved.
-   */
-  String resolveUri(String containingUri, String relativeUri) {
-    if (relativeUri == '') {
-      return null;
-    }
-    try {
-      Uri containingUriObj = Uri.parse(containingUri);
-      Uri relativeUriObj = Uri.parse(relativeUri);
-      return resolveRelativeUri(containingUriObj, relativeUriObj).toString();
-    } on FormatException {
-      return null;
-    }
-  }
-
-  /**
-   * Return the URI of the first configuration from the given [configurations]
-   * which condition is satisfied, or the [defaultUri].
-   */
-  String _selectUri(
-      String defaultUri, List<UnlinkedConfiguration> configurations) {
-    for (UnlinkedConfiguration configuration in configurations) {
-      if (declaredVariables.get(configuration.name) == configuration.value) {
-        return configuration.uri;
-      }
-    }
-    return defaultUri;
-  }
-}
diff --git a/pkg/analyzer/lib/src/summary/public_namespace_computer.dart b/pkg/analyzer/lib/src/summary/public_namespace_computer.dart
deleted file mode 100644
index 4c2e4db..0000000
--- a/pkg/analyzer/lib/src/summary/public_namespace_computer.dart
+++ /dev/null
@@ -1,213 +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 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/ast/visitor.dart';
-import 'package:analyzer/src/summary/format.dart';
-import 'package:analyzer/src/summary/idl.dart';
-
-/**
- * Compute the public namespace portion of the summary for the given [unit],
- * which is presumed to be an unresolved AST.
- */
-UnlinkedPublicNamespaceBuilder computePublicNamespace(CompilationUnit unit) {
-  _PublicNamespaceVisitor visitor = new _PublicNamespaceVisitor();
-  unit.accept(visitor);
-  return new UnlinkedPublicNamespaceBuilder(
-      names: visitor.names, exports: visitor.exports, parts: visitor.parts);
-}
-
-/**
- * Serialize a [Configuration] into a [UnlinkedConfigurationBuilder].
- */
-UnlinkedConfigurationBuilder serializeConfiguration(
-    Configuration configuration) {
-  return new UnlinkedConfigurationBuilder(
-      name: configuration.name.components.map((i) => i.name).join('.'),
-      value: configuration.value?.stringValue ?? 'true',
-      uri: configuration.uri.stringValue);
-}
-
-class _CombinatorEncoder extends SimpleAstVisitor<UnlinkedCombinatorBuilder> {
-  _CombinatorEncoder();
-
-  List<String> encodeNames(NodeList<SimpleIdentifier> names) =>
-      names.map((SimpleIdentifier id) => id.name).toList();
-
-  @override
-  UnlinkedCombinatorBuilder visitHideCombinator(HideCombinator node) {
-    return new UnlinkedCombinatorBuilder(hides: encodeNames(node.hiddenNames));
-  }
-
-  @override
-  UnlinkedCombinatorBuilder visitShowCombinator(ShowCombinator node) {
-    return new UnlinkedCombinatorBuilder(
-        shows: encodeNames(node.shownNames),
-        offset: node.offset,
-        end: node.end);
-  }
-}
-
-class _PublicNamespaceVisitor extends RecursiveAstVisitor {
-  final List<UnlinkedPublicNameBuilder> names = <UnlinkedPublicNameBuilder>[];
-  final List<UnlinkedExportPublicBuilder> exports =
-      <UnlinkedExportPublicBuilder>[];
-  final List<String> parts = <String>[];
-
-  _PublicNamespaceVisitor();
-
-  UnlinkedPublicNameBuilder addNameIfPublic(
-      String name, ReferenceKind kind, int numTypeParameters) {
-    if (isPublic(name)) {
-      UnlinkedPublicNameBuilder b = new UnlinkedPublicNameBuilder(
-          name: name, kind: kind, numTypeParameters: numTypeParameters);
-      names.add(b);
-      return b;
-    }
-    return null;
-  }
-
-  bool isPublic(String name) => !name.startsWith('_');
-
-  @override
-  visitClassDeclaration(ClassDeclaration node) {
-    UnlinkedPublicNameBuilder cls = addNameIfPublic(
-        node.name.name,
-        ReferenceKind.classOrEnum,
-        node.typeParameters?.typeParameters?.length ?? 0);
-    if (cls != null) {
-      _addClassMembers(cls, node.members);
-    }
-  }
-
-  @override
-  visitClassTypeAlias(ClassTypeAlias node) {
-    addNameIfPublic(node.name.name, ReferenceKind.classOrEnum,
-        node.typeParameters?.typeParameters?.length ?? 0);
-  }
-
-  @override
-  visitEnumDeclaration(EnumDeclaration node) {
-    UnlinkedPublicNameBuilder enm =
-        addNameIfPublic(node.name.name, ReferenceKind.classOrEnum, 0);
-    if (enm != null) {
-      enm.members.add(new UnlinkedPublicNameBuilder(
-          name: 'values',
-          kind: ReferenceKind.propertyAccessor,
-          numTypeParameters: 0));
-      for (EnumConstantDeclaration enumConstant in node.constants) {
-        String name = enumConstant.name.name;
-        if (isPublic(name)) {
-          enm.members.add(new UnlinkedPublicNameBuilder(
-              name: name,
-              kind: ReferenceKind.propertyAccessor,
-              numTypeParameters: 0));
-        }
-      }
-    }
-  }
-
-  @override
-  visitExportDirective(ExportDirective node) {
-    exports.add(new UnlinkedExportPublicBuilder(
-        uri: node.uri.stringValue,
-        combinators: node.combinators
-            .map((Combinator c) => c.accept(new _CombinatorEncoder()))
-            .toList(),
-        configurations:
-            node.configurations.map(serializeConfiguration).toList()));
-  }
-
-  @override
-  visitFunctionDeclaration(FunctionDeclaration node) {
-    String name = node.name.name;
-    if (node.isSetter) {
-      name += '=';
-    }
-    addNameIfPublic(
-        name,
-        node.isGetter || node.isSetter
-            ? ReferenceKind.topLevelPropertyAccessor
-            : ReferenceKind.topLevelFunction,
-        node.functionExpression.typeParameters?.typeParameters?.length ?? 0);
-  }
-
-  @override
-  visitFunctionTypeAlias(FunctionTypeAlias node) {
-    addNameIfPublic(node.name.name, ReferenceKind.typedef,
-        node.typeParameters?.typeParameters?.length ?? 0);
-  }
-
-  @override
-  visitGenericTypeAlias(GenericTypeAlias node) {
-    addNameIfPublic(node.name.name, ReferenceKind.genericFunctionTypedef,
-        node.typeParameters?.typeParameters?.length ?? 0);
-  }
-
-  @override
-  visitMixinDeclaration(MixinDeclaration node) {
-    UnlinkedPublicNameBuilder mixin = addNameIfPublic(
-        node.name.name,
-        ReferenceKind.classOrEnum,
-        node.typeParameters?.typeParameters?.length ?? 0);
-    if (mixin != null) {
-      _addClassMembers(mixin, node.members);
-    }
-  }
-
-  @override
-  visitPartDirective(PartDirective node) {
-    parts.add(node.uri.stringValue ?? '');
-  }
-
-  @override
-  visitVariableDeclaration(VariableDeclaration node) {
-    String name = node.name.name;
-    addNameIfPublic(name, ReferenceKind.topLevelPropertyAccessor, 0);
-    if (!node.isFinal && !node.isConst) {
-      addNameIfPublic('$name=', ReferenceKind.topLevelPropertyAccessor, 0);
-    }
-  }
-
-  void _addClassMembers(
-      UnlinkedPublicNameBuilder builder, List<ClassMember> members) {
-    for (ClassMember member in members) {
-      if (member is FieldDeclaration && member.isStatic) {
-        for (VariableDeclaration field in member.fields.variables) {
-          String name = field.name.name;
-          if (isPublic(name)) {
-            builder.members.add(new UnlinkedPublicNameBuilder(
-                name: name,
-                kind: ReferenceKind.propertyAccessor,
-                numTypeParameters: 0));
-          }
-        }
-      }
-      if (member is MethodDeclaration &&
-          member.isStatic &&
-          !member.isSetter &&
-          !member.isOperator) {
-        String name = member.name.name;
-        if (isPublic(name)) {
-          builder.members.add(new UnlinkedPublicNameBuilder(
-              name: name,
-              kind: member.isGetter
-                  ? ReferenceKind.propertyAccessor
-                  : ReferenceKind.method,
-              numTypeParameters:
-                  member.typeParameters?.typeParameters?.length ?? 0));
-        }
-      }
-      if (member is ConstructorDeclaration && member.name != null) {
-        String name = member.name.name;
-        if (isPublic(name)) {
-          builder.members.add(new UnlinkedPublicNameBuilder(
-              name: name,
-              kind: ReferenceKind.constructor,
-              numTypeParameters: 0));
-        }
-      }
-    }
-  }
-}
diff --git a/pkg/analyzer/lib/src/summary/resynthesize.dart b/pkg/analyzer/lib/src/summary/resynthesize.dart
deleted file mode 100644
index 0b8c5ac..0000000
--- a/pkg/analyzer/lib/src/summary/resynthesize.dart
+++ /dev/null
@@ -1,1671 +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:collection';
-
-import 'package:analyzer/dart/analysis/session.dart';
-import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/dart/element/nullability_suffix.dart';
-import 'package:analyzer/dart/element/type.dart';
-import 'package:analyzer/src/dart/element/element.dart';
-import 'package:analyzer/src/dart/element/handle.dart';
-import 'package:analyzer/src/dart/element/member.dart';
-import 'package:analyzer/src/dart/element/type.dart';
-import 'package:analyzer/src/dart/element/type_provider.dart';
-import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/resolver.dart';
-import 'package:analyzer/src/generated/source_io.dart';
-import 'package:analyzer/src/generated/testing/ast_test_factory.dart';
-import 'package:analyzer/src/generated/utilities_dart.dart';
-import 'package:analyzer/src/summary/expr_builder.dart';
-import 'package:analyzer/src/summary/format.dart';
-import 'package:analyzer/src/summary/idl.dart';
-
-/**
- * Expando for marking types with implicit type arguments, which are the same as
- * type parameter bounds (in strong mode), or `dynamic` (in spec mode).
- *
- * If a type is associated with a non-null value in this expando, then it has
- * implicit type arguments.
- */
-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 {
-  /// Builds the export namespace for the library by aggregating together its
-  /// public namespace and export names.
-  Namespace buildExportNamespace();
-
-  /// Builds the public namespace for the library.
-  Namespace buildPublicNamespace();
-}
-
-/// [LibraryResynthesizerContextMixin] contains methods useful for implementing
-/// the [LibraryResynthesizerContext] interface.
-abstract class LibraryResynthesizerContextMixin
-    implements LibraryResynthesizerContext {
-  /// Gets the associated [LibraryResynthesizer].
-  LibraryResynthesizer get resynthesizer;
-
-  @override
-  Namespace buildExportNamespace() => resynthesizer.buildExportNamespace();
-
-  @override
-  Namespace buildPublicNamespace() => resynthesizer.buildPublicNamespace();
-}
-
-/// [LibraryResynthesizerMixin] contains methods useful for implementing the
-/// [LibraryResynthesizer] interface.
-abstract class LibraryResynthesizerMixin implements LibraryResynthesizer {
-  /// Gets the library element being resynthesized.
-  LibraryElement get library;
-
-  /// Gets the list of export names created during summary linking.
-  List<LinkedExportName> get linkedExportNames;
-
-  /// Builds or retrieves an [Element] for the entity referred to by the given
-  /// [exportName].
-  Element buildExportName(LinkedExportName exportName);
-
-  @override
-  Namespace buildExportNamespace() {
-    Namespace publicNamespace = library.publicNamespace;
-    List<LinkedExportName> exportNames = linkedExportNames;
-    Map<String, Element> definedNames = new HashMap<String, Element>();
-    // Start by populating all the public names from [publicNamespace].
-    publicNamespace.definedNames.forEach((String name, Element element) {
-      definedNames[name] = element;
-    });
-    // Add all the names from [exportNames].
-    for (LinkedExportName exportName in exportNames) {
-      String name = exportName.name;
-      if (!definedNames.containsKey(name)) {
-        definedNames[name] = buildExportName(exportName);
-      }
-    }
-    return new Namespace(definedNames);
-  }
-
-  @override
-  Namespace buildPublicNamespace() =>
-      new NamespaceBuilder().createPublicNamespaceForLibrary(library);
-}
-
-class RecursiveInstantiateToBounds {}
-
-/// Data structure used during resynthesis to record all the information that is
-/// known about how to resynthesize a single entry in [LinkedUnit.references]
-/// (and its associated entry in [UnlinkedUnit.references], if it exists).
-abstract class ReferenceInfo {
-  /// The element referred to by this reference, or `null` if there is no
-  /// associated element (e.g. because it is a reference to an undefined
-  /// entity).
-  Element get element;
-
-  /// The enclosing [_ReferenceInfo], or `null` for top-level elements.
-  ReferenceInfo get enclosing;
-
-  /// Indicates whether the thing being referenced has at least one type
-  /// parameter.
-  bool get hasTypeParameters;
-
-  /// The name of the entity referred to by this reference.
-  String get name;
-
-  /// If this reference refers to a non-generic type, the type it refers to.
-  /// Otherwise `null`.
-  DartType get type;
-}
-
-/**
- * Implementation of [ElementResynthesizer] used when resynthesizing an element
- * model from summaries.
- */
-abstract class SummaryResynthesizer extends ElementResynthesizer {
-  /**
-   * Source factory used to convert URIs to [Source] objects.
-   */
-  final SourceFactory sourceFactory;
-
-  /**
-   * Cache of [Source] objects that have already been converted from URIs.
-   */
-  final Map<String, Source> _sources = <String, Source>{};
-
-  /**
-   * The `dart:core` library for the context.
-   */
-  LibraryElementImpl _coreLibrary;
-
-  /**
-   * The `dart:async` library for the context.
-   */
-  LibraryElementImpl _asyncLibrary;
-
-  /**
-   * The [TypeProvider] used to obtain SDK types during resynthesis.
-   */
-  TypeProvider _typeProvider;
-
-  /**
-   * Map of compilation units resynthesized from summaries.  The two map keys
-   * are the first two elements of the element's location (the library URI and
-   * the compilation unit URI).
-   */
-  final Map<String, Map<String, CompilationUnitElementImpl>>
-      _resynthesizedUnits = <String, Map<String, CompilationUnitElementImpl>>{};
-
-  /**
-   * Map of top level elements resynthesized from summaries.  The three map
-   * keys are the first three elements of the element's location (the library
-   * URI, the compilation unit URI, and the name of the top level declaration).
-   */
-  final Map<String, Map<String, Map<String, Element>>> _resynthesizedElements =
-      <String, Map<String, Map<String, Element>>>{};
-
-  /**
-   * Map of libraries which have been resynthesized from summaries.  The map
-   * key is the library URI.
-   */
-  final Map<String, LibraryElement> _resynthesizedLibraries =
-      <String, LibraryElement>{};
-
-  SummaryResynthesizer(AnalysisContext context, AnalysisSession session,
-      this.sourceFactory, bool _)
-      : super(context, session) {
-    _buildTypeProvider();
-  }
-
-  /**
-   * Number of libraries that have been resynthesized so far.
-   */
-  int get resynthesisCount => _resynthesizedLibraries.length;
-
-  /**
-   * Indicates whether the summary should be resynthesized assuming strong mode
-   * semantics.
-   */
-  @deprecated
-  bool get strongMode => true;
-
-  /**
-   * The [TypeProvider] used to obtain SDK types during resynthesis.
-   */
-  TypeProvider get typeProvider => _typeProvider;
-
-  /**
-   * The [TypeSystem] used perform type operations.
-   */
-  TypeSystem get typeSystem => context.typeSystem;
-
-  /**
-   * The client installed this resynthesizer into the context, and set its
-   * type provider, so it is not safe to access type provider to create
-   * additional types.
-   */
-  void finishCoreAsyncLibraries() {
-    _coreLibrary.createLoadLibraryFunction(_typeProvider);
-    _asyncLibrary.createLoadLibraryFunction(_typeProvider);
-  }
-
-  @override
-  Element getElement(ElementLocation location) {
-    List<String> components = location.components;
-    String libraryUri = components[0];
-    // Resynthesize locally.
-    if (components.length == 1) {
-      return getLibraryElement(libraryUri);
-    } else if (components.length == 2) {
-      LibraryElement libraryElement = getLibraryElement(libraryUri);
-      // Try to find the unit element.
-      {
-        Map<String, CompilationUnitElement> libraryMap =
-            _resynthesizedUnits[libraryUri];
-        assert(libraryMap != null);
-        String unitUri = components[1];
-        CompilationUnitElement unitElement = libraryMap[unitUri];
-        if (unitElement != null) {
-          return unitElement;
-        }
-      }
-      // Try to find the prefix element.
-      {
-        String name = components[1];
-        for (PrefixElement prefix in libraryElement.prefixes) {
-          if (prefix.name == name) {
-            return prefix;
-          }
-        }
-      }
-      // Fail.
-      throw new Exception('The element not found in summary: $location');
-    } else if (components.length == 3 || components.length == 4) {
-      String unitUri = components[1];
-      // Prepare elements-in-units in the library.
-      Map<String, Map<String, Element>> unitsInLibrary =
-          _resynthesizedElements[libraryUri];
-      if (unitsInLibrary == null) {
-        unitsInLibrary = new HashMap<String, Map<String, Element>>();
-        _resynthesizedElements[libraryUri] = unitsInLibrary;
-      }
-      // Prepare elements in the unit.
-      Map<String, Element> elementsInUnit = unitsInLibrary[unitUri];
-      if (elementsInUnit == null) {
-        // Prepare the CompilationUnitElementImpl.
-        Map<String, CompilationUnitElementImpl> libraryMap =
-            _resynthesizedUnits[libraryUri];
-        if (libraryMap == null) {
-          getLibraryElement(libraryUri);
-          libraryMap = _resynthesizedUnits[libraryUri];
-          if (libraryMap == null) {
-            throw new StateError(
-                'Unable to find library `$libraryUri` in a summary file.');
-          }
-        }
-        CompilationUnitElementImpl unitElement = libraryMap[unitUri];
-        // Fill elements in the unit map.
-        if (unitElement != null) {
-          elementsInUnit = new HashMap<String, Element>();
-          void putElement(Element e) {
-            String id =
-                e is PropertyAccessorElementImpl ? e.identifier : e.name;
-            elementsInUnit[id] = e;
-          }
-
-          unitElement.accessors.forEach(putElement);
-          unitElement.enums.forEach(putElement);
-          unitElement.functions.forEach(putElement);
-          unitElement.functionTypeAliases.forEach(putElement);
-          unitElement.mixins.forEach(putElement);
-          unitElement.topLevelVariables.forEach(putElement);
-          unitElement.types.forEach(putElement);
-          unitsInLibrary[unitUri] = elementsInUnit;
-        }
-      }
-      // Get the element.
-      Element element = elementsInUnit[components[2]];
-      if (element != null && components.length == 4) {
-        String name = components[3];
-        Element parentElement = element;
-        if (parentElement is ClassElement) {
-          if (name.endsWith('?')) {
-            element =
-                parentElement.getGetter(name.substring(0, name.length - 1));
-          } else if (name.endsWith('=')) {
-            element =
-                parentElement.getSetter(name.substring(0, name.length - 1));
-          } else if (name.isEmpty) {
-            element = parentElement.unnamedConstructor;
-          } else {
-            element = parentElement.getField(name) ??
-                parentElement.getMethod(name) ??
-                parentElement.getNamedConstructor(name);
-          }
-        } else {
-          // The only elements that are currently retrieved using 4-component
-          // locations are class members.
-          throw new StateError(
-              '4-element locations not supported for ${element.runtimeType}');
-        }
-      }
-      if (element == null) {
-        throw new Exception('Element not found in summary: $location');
-      }
-      return element;
-    } else {
-      throw new UnimplementedError(location.toString());
-    }
-  }
-
-  /**
-   * Get the [LibraryElement] for the given [uri], resynthesizing it if it
-   * hasn't been resynthesized already.
-   */
-  LibraryElement getLibraryElement(String uri) {
-    return _resynthesizedLibraries.putIfAbsent(uri, () {
-      LinkedLibrary serializedLibrary = getLinkedSummary(uri);
-      Source librarySource = _getSource(uri);
-      if (serializedLibrary == null) {
-        LibraryElementImpl libraryElement =
-            new LibraryElementImpl(context, session, '', -1, 0, true);
-        libraryElement.isSynthetic = true;
-        CompilationUnitElementImpl unitElement =
-            new CompilationUnitElementImpl();
-        libraryElement.definingCompilationUnit = unitElement;
-        unitElement.source = librarySource;
-        unitElement.librarySource = librarySource;
-        libraryElement.createLoadLibraryFunction(typeProvider);
-        libraryElement.publicNamespace = new Namespace({});
-        libraryElement.exportNamespace = new Namespace({});
-        _resynthesizedUnits[uri] = {uri: unitElement};
-        return libraryElement;
-      }
-      UnlinkedUnit unlinkedSummary = getUnlinkedSummary(uri);
-      if (unlinkedSummary == null) {
-        throw new StateError('Unable to find unlinked summary: $uri');
-      }
-      List<UnlinkedUnit> serializedUnits = <UnlinkedUnit>[unlinkedSummary];
-      for (String part in serializedUnits[0].publicNamespace.parts) {
-        Source partSource = sourceFactory.resolveUri(librarySource, part);
-        UnlinkedUnit partUnlinkedUnit;
-        if (partSource != null) {
-          String partAbsUri = partSource.uri.toString();
-          partUnlinkedUnit = getUnlinkedSummary(partAbsUri);
-        }
-        serializedUnits.add(partUnlinkedUnit ??
-            new UnlinkedUnitBuilder(codeRange: new CodeRangeBuilder()));
-      }
-      _LibraryResynthesizer libraryResynthesizer = new _LibraryResynthesizer(
-          this, serializedLibrary, serializedUnits, librarySource);
-      LibraryElement library = libraryResynthesizer.buildLibrary();
-      _resynthesizedUnits[uri] = libraryResynthesizer.resynthesizedUnits;
-      return library;
-    });
-  }
-
-  /**
-   * Return the [LinkedLibrary] for the given [uri] or `null` if it could not
-   * be found.  Caller has already checked that `parent.hasLibrarySummary(uri)`
-   * returns `false`.
-   */
-  LinkedLibrary getLinkedSummary(String uri);
-
-  /**
-   * Return the [UnlinkedUnit] for the given [uri] or `null` if it could not
-   * be found.  Caller has already checked that `parent.hasLibrarySummary(uri)`
-   * returns `false`.
-   */
-  UnlinkedUnit getUnlinkedSummary(String uri);
-
-  /**
-   * Return `true` if this resynthesizer can provide summaries of the libraries
-   * with the given [uri].  Caller has already checked that
-   * `parent.hasLibrarySummary(uri)` returns `false`.
-   */
-  bool hasLibrarySummary(String uri);
-
-  void _buildTypeProvider() {
-    _coreLibrary = getLibraryElement('dart:core') as LibraryElementImpl;
-    _asyncLibrary = getLibraryElement('dart:async') as LibraryElementImpl;
-    _typeProvider = new TypeProviderImpl(_coreLibrary, _asyncLibrary);
-  }
-
-  /**
-   * Get the [Source] object for the given [uri].
-   */
-  Source _getSource(String uri) {
-    return _sources.putIfAbsent(uri, () => sourceFactory.forUri(uri));
-  }
-}
-
-class SummaryResynthesizerContext implements ResynthesizerContext {
-  final _UnitResynthesizer unitResynthesizer;
-
-  SummaryResynthesizerContext(this.unitResynthesizer);
-
-  @deprecated
-  @override
-  bool get isStrongMode => true;
-
-  @override
-  ElementAnnotationImpl buildAnnotation(ElementImpl context, UnlinkedExpr uc) {
-    return unitResynthesizer.buildAnnotation(context, uc);
-  }
-
-  @override
-  Expression buildExpression(ElementImpl context, UnlinkedExpr uc) {
-    return unitResynthesizer._buildConstExpression(context, uc);
-  }
-
-  @override
-  UnitExplicitTopLevelAccessors buildTopLevelAccessors() {
-    return unitResynthesizer.buildUnitExplicitTopLevelAccessors();
-  }
-
-  @override
-  UnitExplicitTopLevelVariables buildTopLevelVariables() {
-    return unitResynthesizer.buildUnitExplicitTopLevelVariables();
-  }
-
-  @override
-  TopLevelInferenceError getTypeInferenceError(int slot) {
-    return unitResynthesizer.getTypeInferenceError(slot);
-  }
-
-  @override
-  bool inheritsCovariant(int slot) {
-    return unitResynthesizer.parametersInheritingCovariant.contains(slot);
-  }
-
-  @override
-  bool isInConstCycle(int slot) {
-    return unitResynthesizer.constCycles.contains(slot);
-  }
-
-  @override
-  bool isSimplyBounded(int notSimplyBoundedSlot) {
-    return !unitResynthesizer.linkedUnit.notSimplyBounded
-        .contains(notSimplyBoundedSlot);
-  }
-
-  @override
-  ConstructorElement resolveConstructorRef(
-      ElementImpl context, EntityRef entry) {
-    return unitResynthesizer._getConstructorForEntry(context, entry);
-  }
-
-  @override
-  DartType resolveLinkedType(ElementImpl context, int slot) {
-    return unitResynthesizer.buildLinkedType(context, slot);
-  }
-
-  @override
-  DartType resolveTypeRef(ElementImpl context, EntityRef type,
-      {bool defaultVoid: false,
-      bool instantiateToBoundsAllowed: true,
-      bool declaredType: false}) {
-    return unitResynthesizer.buildType(context, type,
-        defaultVoid: defaultVoid,
-        instantiateToBoundsAllowed: instantiateToBoundsAllowed,
-        declaredType: declaredType);
-  }
-}
-
-/// An instance of [_UnitResynthesizer] is responsible for resynthesizing the
-/// elements in a single unit from that unit's summary.
-abstract class UnitResynthesizer {
-  /// Gets the [LibraryElement] being resynthesized.
-  LibraryElement get library;
-
-  /// Gets the [TypeProvider], which may be used to create core types.
-  TypeProvider get typeProvider;
-
-  /// Gets the [TypeSystem], which may be used to create core types.
-  TypeSystem get typeSystem;
-
-  /// Builds a [DartType] object based on a [EntityRef].  This [DartType]
-  /// may refer to elements in other libraries than the library being
-  /// deserialized, so handles may be used to avoid having to deserialize other
-  /// libraries in the process.
-  DartType buildType(ElementImpl context, EntityRef type);
-
-  /// Builds a [DartType] object based on [ReferenceInfo], which should refer to
-  /// a class, by filling in the type arguments as appropriate, and performing
-  /// instantiate to bounds if necessary.
-  DartType buildTypeForClassInfo(ReferenceInfo info, int numTypeArguments,
-      DartType getTypeArgument(int i));
-
-  /// Returns the defining type for a [ConstructorElement] by applying
-  /// [typeArgumentRefs] to the given linked [info].  Returns [DynamicTypeImpl]
-  /// if the [info] is unresolved.
-  DartType createConstructorDefiningType(ElementImpl context,
-      ReferenceInfo info, List<EntityRef> typeArgumentRefs);
-
-  /// Determines if the given [type] has implicit type arguments.
-  bool doesTypeHaveImplicitArguments(ParameterizedType type);
-
-  /// Returns the [ConstructorElement] corresponding to the given linked [info],
-  /// using the [classType] which has already been computed (e.g. by
-  /// [createConstructorDefiningType]).  Both cases when [info] is a
-  /// [ClassElement] and [ConstructorElement] are supported.
-  ConstructorElement getConstructorForInfo(
-      InterfaceType classType, ReferenceInfo info);
-
-  /// Returns the [ReferenceInfo] with the given [index].
-  ReferenceInfo getReferenceInfo(int index);
-}
-
-/// [UnitResynthesizerMixin] contains methods useful for implementing the
-/// [UnitResynthesizer] interface.
-mixin UnitResynthesizerMixin implements UnitResynthesizer {
-  @override
-  DartType createConstructorDefiningType(ElementImpl context,
-      ReferenceInfo info, List<EntityRef> typeArgumentRefs) {
-    bool isClass = info.element is ClassElement;
-    ReferenceInfo classInfo = isClass ? info : info.enclosing;
-    if (classInfo == null) {
-      return DynamicTypeImpl.instance;
-    }
-    List<DartType> typeArguments =
-        typeArgumentRefs.map((t) => buildType(context, t)).toList();
-    return buildTypeForClassInfo(classInfo, typeArguments.length, (i) {
-      if (i < typeArguments.length) {
-        return typeArguments[i];
-      } else {
-        return DynamicTypeImpl.instance;
-      }
-    });
-  }
-
-  @override
-  ConstructorElement getConstructorForInfo(
-      InterfaceType classType, ReferenceInfo info) {
-    ConstructorElement element;
-    Element infoElement = info.element;
-    if (infoElement is ConstructorElement) {
-      element = infoElement;
-    } else if (infoElement is ClassElement) {
-      element = infoElement.unnamedConstructor;
-    }
-    if (element != null && info.hasTypeParameters) {
-      return ConstructorMember.from(element, classType);
-    }
-    return element;
-  }
-}
-
-/**
- * Local function element representing the initializer for a variable that has
- * been resynthesized from a summary.  The actual element won't be constructed
- * until it is requested.  But properties [context] and [enclosingElement] can
- * be used without creating the actual element.
- */
-class _DeferredInitializerElement extends FunctionElementHandle {
-  /**
-   * The variable element containing this element.
-   */
-  @override
-  final VariableElement enclosingElement;
-
-  _DeferredInitializerElement(this.enclosingElement) : super(null, null);
-
-  @override
-  FunctionElement get actualElement => enclosingElement.initializer;
-
-  @override
-  AnalysisContext get context => enclosingElement.context;
-
-  @override
-  ElementLocation get location => actualElement.location;
-
-  @override
-  AnalysisSession get session => enclosingElement.session;
-}
-
-/// Specialization of [LibraryResynthesizer] for resynthesis from linked
-/// summaries.
-class _LibraryResynthesizer extends LibraryResynthesizerMixin {
-  /**
-   * The [SummaryResynthesizer] which is being used to obtain summaries.
-   */
-  final SummaryResynthesizer summaryResynthesizer;
-
-  /**
-   * Linked summary of the library to be resynthesized.
-   */
-  final LinkedLibrary linkedLibrary;
-
-  /**
-   * Unlinked compilation units constituting the library to be resynthesized.
-   */
-  final List<UnlinkedUnit> unlinkedUnits;
-
-  /**
-   * [Source] object for the library to be resynthesized.
-   */
-  final Source librarySource;
-
-  /**
-   * The URI of [librarySource].
-   */
-  Uri libraryUri;
-
-  /**
-   * The URI of [librarySource].
-   */
-  String libraryUriStr;
-
-  /**
-   * Indicates whether [librarySource] is the `dart:core` library.
-   */
-  bool isCoreLibrary;
-
-  /**
-   * The resynthesized library.
-   */
-  LibraryElementImpl library;
-
-  /**
-   * Map of compilation unit elements that have been resynthesized so far.  The
-   * key is the URI of the compilation unit.
-   */
-  final Map<String, CompilationUnitElementImpl> resynthesizedUnits =
-      <String, CompilationUnitElementImpl>{};
-
-  _LibraryResynthesizer(this.summaryResynthesizer, this.linkedLibrary,
-      this.unlinkedUnits, this.librarySource) {
-    libraryUri = librarySource.uri;
-    libraryUriStr = libraryUri.toString();
-    isCoreLibrary = libraryUriStr == 'dart:core';
-  }
-
-  @override
-  List<LinkedExportName> get linkedExportNames => linkedLibrary.exportNames;
-
-  /**
-   * Resynthesize a [NamespaceCombinator].
-   */
-  NamespaceCombinator buildCombinator(UnlinkedCombinator serializedCombinator) {
-    if (serializedCombinator.shows.isNotEmpty) {
-      return new ShowElementCombinatorImpl.forSerialized(serializedCombinator);
-    } else {
-      return new HideElementCombinatorImpl.forSerialized(serializedCombinator);
-    }
-  }
-
-  @override
-  ElementHandle buildExportName(LinkedExportName exportName) {
-    String name = exportName.name;
-    if (exportName.kind == ReferenceKind.topLevelPropertyAccessor &&
-        !name.endsWith('=')) {
-      name += '?';
-    }
-    ElementLocationImpl location = new ElementLocationImpl.con3(
-        getReferencedLocationComponents(
-            exportName.dependency, exportName.unit, name));
-    switch (exportName.kind) {
-      case ReferenceKind.classOrEnum:
-        return new ClassElementHandle(summaryResynthesizer, location);
-      case ReferenceKind.typedef:
-        return new FunctionTypeAliasElementHandle(
-            summaryResynthesizer, location);
-      case ReferenceKind.genericFunctionTypedef:
-        return new GenericTypeAliasElementHandle(
-            summaryResynthesizer, location);
-      case ReferenceKind.topLevelFunction:
-        return new FunctionElementHandle(summaryResynthesizer, location);
-      case ReferenceKind.topLevelPropertyAccessor:
-        return new PropertyAccessorElementHandle(
-            summaryResynthesizer, location);
-      case ReferenceKind.constructor:
-      case ReferenceKind.function:
-      case ReferenceKind.propertyAccessor:
-      case ReferenceKind.method:
-      case ReferenceKind.prefix:
-      case ReferenceKind.unresolved:
-      case ReferenceKind.variable:
-        // Should never happen.  Exported names never refer to import prefixes,
-        // and they always refer to defined top-level entities.
-        throw new StateError('Unexpected export name kind: ${exportName.kind}');
-    }
-    return null;
-  }
-
-  /**
-   * Main entry point.  Resynthesize the [LibraryElement] and return it.
-   */
-  LibraryElement buildLibrary() {
-    // Create LibraryElementImpl.
-    bool hasName = unlinkedUnits[0].libraryName.isNotEmpty;
-    library = new LibraryElementImpl.forSerialized(
-        summaryResynthesizer.context,
-        summaryResynthesizer.session,
-        unlinkedUnits[0].libraryName,
-        hasName ? unlinkedUnits[0].libraryNameOffset : -1,
-        unlinkedUnits[0].libraryNameLength,
-        new _LibraryResynthesizerContext(this),
-        unlinkedUnits[0]);
-    // Create the defining unit.
-    _UnitResynthesizer definingUnitResynthesizer =
-        createUnitResynthesizer(0, librarySource, null);
-    CompilationUnitElementImpl definingUnit = definingUnitResynthesizer.unit;
-    library.definingCompilationUnit = definingUnit;
-    definingUnit.source = librarySource;
-    definingUnit.librarySource = librarySource;
-    // Create parts.
-    List<_UnitResynthesizer> partResynthesizers = <_UnitResynthesizer>[];
-    UnlinkedUnit unlinkedDefiningUnit = unlinkedUnits[0];
-    assert(unlinkedDefiningUnit.publicNamespace.parts.length + 1 ==
-        linkedLibrary.units.length);
-    for (int i = 1; i < linkedLibrary.units.length; i++) {
-      _UnitResynthesizer partResynthesizer = buildPart(
-          definingUnitResynthesizer,
-          unlinkedDefiningUnit.publicNamespace.parts[i - 1],
-          unlinkedDefiningUnit.parts[i - 1],
-          i);
-      if (partResynthesizer != null) {
-        partResynthesizers.add(partResynthesizer);
-      }
-    }
-    library.parts = partResynthesizers.map((r) => r.unit).toList();
-    // Populate units.
-    rememberUriToUnit(definingUnitResynthesizer);
-    for (_UnitResynthesizer partResynthesizer in partResynthesizers) {
-      rememberUriToUnit(partResynthesizer);
-    }
-    // Create the synthetic element for `loadLibrary`.
-    // Until the client received dart:core and dart:async, we cannot do this,
-    // because the TypeProvider is not fully initialized. So, it is up to the
-    // Dart SDK client to initialize TypeProvider and finish the dart:core and
-    // dart:async libraries creation.
-    if (library.name != 'dart.core' && library.name != 'dart.async') {
-      library.createLoadLibraryFunction(summaryResynthesizer.typeProvider);
-    }
-    // Done.
-    return library;
-  }
-
-  /**
-   * Create a [_UnitResynthesizer] that will resynthesize the part with the
-   * given [uri]. Return `null` if the [uri] is invalid.
-   */
-  _UnitResynthesizer buildPart(_UnitResynthesizer definingUnitResynthesizer,
-      String uri, UnlinkedPart partDecl, int unitNum) {
-    Source unitSource =
-        summaryResynthesizer.sourceFactory.resolveUri(librarySource, uri);
-    _UnitResynthesizer partResynthesizer =
-        createUnitResynthesizer(unitNum, unitSource, partDecl);
-    CompilationUnitElementImpl partUnit = partResynthesizer.unit;
-    partUnit.uriOffset = partDecl.uriOffset;
-    partUnit.uriEnd = partDecl.uriEnd;
-    partUnit.source = unitSource;
-    partUnit.librarySource = librarySource;
-    partUnit.uri = uri;
-    return partResynthesizer;
-  }
-
-  /**
-   * Set up data structures for deserializing a compilation unit.
-   */
-  _UnitResynthesizer createUnitResynthesizer(
-      int unitNum, Source unitSource, UnlinkedPart unlinkedPart) {
-    LinkedUnit linkedUnit = linkedLibrary.units[unitNum];
-    UnlinkedUnit unlinkedUnit = unlinkedUnits[unitNum];
-    return new _UnitResynthesizer(
-        this, unlinkedUnit, linkedUnit, unitSource, unlinkedPart);
-  }
-
-  /**
-   * Build the components of an [ElementLocationImpl] for the entity in the
-   * given [unit] of the dependency located at [dependencyIndex], and having
-   * the given [name].
-   */
-  List<String> getReferencedLocationComponents(
-      int dependencyIndex, int unit, String name) {
-    if (dependencyIndex == 0) {
-      String partUri;
-      if (unit != 0) {
-        String uri = unlinkedUnits[0].publicNamespace.parts[unit - 1];
-        partUri = _resolveRelativeUri(uri);
-      } else {
-        partUri = libraryUriStr;
-      }
-      return <String>[libraryUriStr, partUri, name];
-    }
-
-    LinkedDependency dependency = linkedLibrary.dependencies[dependencyIndex];
-    String referencedLibraryUri = _resolveRelativeUri(dependency.uri);
-
-    String partUri;
-    if (unit != 0) {
-      String uri = dependency.parts[unit - 1];
-      partUri = _resolveRelativeUri(uri);
-    } else {
-      partUri = referencedLibraryUri;
-    }
-    return <String>[referencedLibraryUri, partUri, name];
-  }
-
-  /**
-   * Remember the absolute URI to the corresponding unit mapping.
-   */
-  void rememberUriToUnit(_UnitResynthesizer unitResynthesizer) {
-    CompilationUnitElementImpl unit = unitResynthesizer.unit;
-    Source source = unit.source;
-    if (source != null) {
-      String absoluteUri = source.uri.toString();
-      resynthesizedUnits[absoluteUri] = unit;
-    }
-  }
-
-  /**
-   * Resolve the [relativeUriStr] against [libraryUri] using Dart rules.
-   */
-  String _resolveRelativeUri(String relativeUriStr) {
-    Uri relativeUri = Uri.parse(relativeUriStr);
-    Uri resolvedUri = resolveRelativeUri(libraryUri, relativeUri);
-    return resolvedUri.toString();
-  }
-}
-
-/**
- * Implementation of [LibraryResynthesizerContext] for [_LibraryResynthesizer].
- */
-class _LibraryResynthesizerContext extends LibraryResynthesizerContextMixin
-    implements LibraryResynthesizerContext {
-  final _LibraryResynthesizer resynthesizer;
-
-  _LibraryResynthesizerContext(this.resynthesizer);
-
-  @override
-  LinkedLibrary get linkedLibrary => resynthesizer.linkedLibrary;
-
-  @override
-  LibraryElement buildExportedLibrary(String relativeUri) {
-    return _getLibraryByRelativeUri(relativeUri);
-  }
-
-  @override
-  LibraryElement buildImportedLibrary(int dependency) {
-    String depUri = resynthesizer.linkedLibrary.dependencies[dependency].uri;
-    return _getLibraryByRelativeUri(depUri);
-  }
-
-  @override
-  FunctionElement findEntryPoint() {
-    LibraryElementImpl library = resynthesizer.library;
-    Element entryPoint =
-        library.exportNamespace.get(FunctionElement.MAIN_FUNCTION_NAME);
-    if (entryPoint is FunctionElement) {
-      return entryPoint;
-    }
-    return null;
-  }
-
-  @override
-  void patchTopLevelAccessors() {
-    LibraryElementImpl library = resynthesizer.library;
-    BuildLibraryElementUtils.patchTopLevelAccessors(library);
-  }
-
-  LibraryElementHandle _getLibraryByRelativeUri(String depUri) {
-    Source source = resynthesizer.summaryResynthesizer.sourceFactory
-        .resolveUri(resynthesizer.librarySource, depUri);
-    if (source == null) {
-      return null;
-    }
-    String absoluteUri = source.uri.toString();
-    return new LibraryElementHandle(resynthesizer.summaryResynthesizer,
-        new ElementLocationImpl.con3(<String>[absoluteUri]));
-  }
-}
-
-/// Specialization of [ReferenceInfo] for resynthesis from linked summaries.
-class _ReferenceInfo extends ReferenceInfo {
-  /**
-   * The [_LibraryResynthesizer] which is being used to obtain summaries.
-   */
-  final _LibraryResynthesizer libraryResynthesizer;
-
-  @override
-  final _ReferenceInfo enclosing;
-
-  @override
-  final String name;
-
-  /**
-   * Is `true` if the [element] can be used as a declared type.
-   */
-  final bool isDeclarableType;
-
-  @override
-  final Element element;
-
-  /**
-   * If this reference refers to a non-generic type, the type it refers to.
-   * Otherwise `null`.
-   */
-  DartType _type;
-
-  /**
-   * The number of type parameters accepted by the entity referred to by this
-   * reference, or zero if it doesn't accept any type parameters.
-   */
-  final int numTypeParameters;
-
-  bool _isBeingInstantiatedToBounds = false;
-  bool _isRecursiveWhileInstantiateToBounds = false;
-
-  /**
-   * Create a new [_ReferenceInfo] object referring to an element called [name]
-   * via the element handle [element], and having [numTypeParameters] type
-   * parameters.
-   *
-   * For the special types `dynamic` and `void`, [specialType] should point to
-   * the type itself.  Otherwise, pass `null` and the type will be computed
-   * when appropriate.
-   */
-  _ReferenceInfo(
-      this.libraryResynthesizer,
-      this.enclosing,
-      this.name,
-      this.isDeclarableType,
-      this.element,
-      DartType specialType,
-      this.numTypeParameters) {
-    if (specialType != null) {
-      _type = specialType;
-    }
-  }
-
-  @override
-  bool get hasTypeParameters => numTypeParameters != 0;
-
-  @override
-  DartType get type {
-    if (_type == null) {
-      _type = _buildType(true, 0, (_) => DynamicTypeImpl.instance, const []);
-    }
-    return _type;
-  }
-
-  List<DartType> get _dynamicTypeArguments =>
-      new List<DartType>.filled(numTypeParameters, DynamicTypeImpl.instance);
-
-  /**
-   * Build a [DartType] corresponding to the result of applying some type
-   * arguments to the entity referred to by this [_ReferenceInfo].  The type
-   * arguments are retrieved by calling [getTypeArgument].
-   *
-   * If [implicitFunctionTypeIndices] is not empty, a [DartType] should be
-   * created which refers to a function type implicitly defined by one of the
-   * element's parameters.  [implicitFunctionTypeIndices] is interpreted as in
-   * [EntityRef.implicitFunctionTypeIndices].
-   *
-   * If the entity referred to by this [_ReferenceInfo] is not a type, `null`
-   * is returned.
-   */
-  DartType buildType(bool instantiateToBoundsAllowed, int numTypeArguments,
-      DartType getTypeArgument(int i), List<int> implicitFunctionTypeIndices) {
-    DartType result =
-        (numTypeParameters == 0 && implicitFunctionTypeIndices.isEmpty)
-            ? type
-            : _buildType(instantiateToBoundsAllowed, numTypeArguments,
-                getTypeArgument, implicitFunctionTypeIndices);
-    if (result == null) {
-      return DynamicTypeImpl.instance;
-    }
-    return result;
-  }
-
-  /**
-   * If this reference refers to a type, build a [DartType].  Otherwise return
-   * `null`.  If [numTypeArguments] is the same as the [numTypeParameters],
-   * the type is instantiated with type arguments returned by [getTypeArgument],
-   * otherwise it is instantiated with type parameter bounds (if strong mode),
-   * or with `dynamic` type arguments.
-   *
-   * If [implicitFunctionTypeIndices] is not null, a [DartType] should be
-   * created which refers to a function type implicitly defined by one of the
-   * element's parameters.  [implicitFunctionTypeIndices] is interpreted as in
-   * [EntityRef.implicitFunctionTypeIndices].
-   */
-  DartType _buildType(bool instantiateToBoundsAllowed, int numTypeArguments,
-      DartType getTypeArgument(int i), List<int> implicitFunctionTypeIndices) {
-    ElementHandle element = this.element; // To allow type promotion
-    if (element is ClassElementHandle) {
-      List<DartType> typeArguments = null;
-      // If type arguments are specified, use them.
-      // Otherwise, delay until they are requested.
-      if (numTypeParameters == 0) {
-        return element.type;
-      } else if (numTypeArguments == numTypeParameters) {
-        typeArguments = _buildTypeArguments(numTypeArguments, getTypeArgument);
-      }
-      InterfaceTypeImpl type =
-          new InterfaceTypeImpl.elementWithNameAndArgs(element, name, () {
-        if (typeArguments == null) {
-          if (!_isBeingInstantiatedToBounds) {
-            _isBeingInstantiatedToBounds = true;
-            _isRecursiveWhileInstantiateToBounds = false;
-            try {
-              InterfaceType instantiatedToBounds = libraryResynthesizer
-                  .summaryResynthesizer.context.typeSystem
-                  .instantiateToBounds(element.type) as InterfaceType;
-              if (_isRecursiveWhileInstantiateToBounds) {
-                throw new RecursiveInstantiateToBounds();
-              }
-              return instantiatedToBounds.typeArguments;
-            } finally {
-              _isBeingInstantiatedToBounds = false;
-            }
-          } else {
-            _isRecursiveWhileInstantiateToBounds = true;
-            typeArguments = _dynamicTypeArguments;
-          }
-        }
-        return typeArguments;
-      });
-      // Mark the type as having implicit type arguments, so that we don't
-      // attempt to request them during constant expression resynthesizing.
-      if (typeArguments == null) {
-        _typesWithImplicitTypeArguments[type] = true;
-      }
-      // Done.
-      return type;
-    } else if (element is GenericTypeAliasElementHandle) {
-      GenericTypeAliasElementImpl actualElement = element.actualElement;
-      List<DartType> typeArguments;
-      if (numTypeArguments == numTypeParameters) {
-        typeArguments = _buildTypeArguments(numTypeArguments, getTypeArgument);
-      } else if (instantiateToBoundsAllowed) {
-        if (!_isBeingInstantiatedToBounds) {
-          _isBeingInstantiatedToBounds = true;
-          _isRecursiveWhileInstantiateToBounds = false;
-          try {
-            typeArguments = libraryResynthesizer
-                .summaryResynthesizer.context.typeSystem
-                .instantiateTypeFormalsToBounds(element.typeParameters);
-            if (_isRecursiveWhileInstantiateToBounds) {
-              typeArguments = _dynamicTypeArguments;
-            }
-          } finally {
-            _isBeingInstantiatedToBounds = false;
-          }
-        } else {
-          _isRecursiveWhileInstantiateToBounds = true;
-          typeArguments = _dynamicTypeArguments;
-        }
-      } else {
-        typeArguments = _dynamicTypeArguments;
-      }
-      return GenericTypeAliasElementImpl.typeAfterSubstitution(
-          actualElement, typeArguments);
-    } else if (element is FunctionTypedElement) {
-      if (element is FunctionTypeAliasElementHandle) {
-        List<DartType> typeArguments;
-        if (numTypeArguments == numTypeParameters) {
-          typeArguments =
-              _buildTypeArguments(numTypeArguments, getTypeArgument);
-        } else if (instantiateToBoundsAllowed) {
-          if (!_isBeingInstantiatedToBounds) {
-            _isBeingInstantiatedToBounds = true;
-            _isRecursiveWhileInstantiateToBounds = false;
-            try {
-              FunctionType instantiatedToBounds = libraryResynthesizer
-                  .summaryResynthesizer.context.typeSystem
-                  .instantiateToBounds(element.type) as FunctionType;
-              if (!_isRecursiveWhileInstantiateToBounds) {
-                typeArguments = instantiatedToBounds.typeArguments;
-              } else {
-                typeArguments = _dynamicTypeArguments;
-              }
-            } finally {
-              _isBeingInstantiatedToBounds = false;
-            }
-          } else {
-            _isRecursiveWhileInstantiateToBounds = true;
-            typeArguments = _dynamicTypeArguments;
-          }
-        } else {
-          typeArguments = _dynamicTypeArguments;
-        }
-        return element.instantiate(typeArguments);
-      } else {
-        FunctionTypedElementComputer computer;
-        if (implicitFunctionTypeIndices.isNotEmpty) {
-          numTypeArguments = numTypeParameters;
-          computer = () {
-            FunctionTypedElement element = this.element;
-            for (int index in implicitFunctionTypeIndices) {
-              element = element.parameters[index].type.element;
-            }
-            return element;
-          };
-        } else {
-          // For a type that refers to a generic executable, the type arguments are
-          // not supposed to include the arguments to the executable itself.
-          if (element is MethodElementHandle && !element.isStatic) {
-            numTypeArguments = enclosing?.numTypeParameters ?? 0;
-          } else {
-            numTypeArguments = 0;
-          }
-          computer = () => this.element as FunctionTypedElement;
-        }
-        // TODO(paulberry): Is it a bug that we have to pass `false` for
-        // isInstantiated?
-        return new DeferredFunctionTypeImpl(computer, null,
-            _buildTypeArguments(numTypeArguments, getTypeArgument), false);
-      }
-    } else {
-      return null;
-    }
-  }
-
-  /**
-   * Build a list of type arguments having length [numTypeArguments] where each
-   * type argument is obtained by calling [getTypeArgument].
-   */
-  List<DartType> _buildTypeArguments(
-      int numTypeArguments, DartType getTypeArgument(int i)) {
-    List<DartType> typeArguments = const <DartType>[];
-    if (numTypeArguments != 0) {
-      typeArguments = new List<DartType>(numTypeArguments);
-      for (int i = 0; i < numTypeArguments; i++) {
-        typeArguments[i] = getTypeArgument(i);
-      }
-    }
-    return typeArguments;
-  }
-}
-
-/// Specialization of [UnitResynthesizer] for resynthesis from linked summaries.
-class _UnitResynthesizer extends UnitResynthesizer with UnitResynthesizerMixin {
-  /**
-   * The [_LibraryResynthesizer] which is being used to obtain summaries.
-   */
-  final _LibraryResynthesizer libraryResynthesizer;
-
-  /**
-   * The [UnlinkedUnit] from which elements are currently being resynthesized.
-   */
-  final UnlinkedUnit unlinkedUnit;
-
-  /**
-   * The [LinkedUnit] from which elements are currently being resynthesized.
-   */
-  final LinkedUnit linkedUnit;
-
-  /**
-   * The [CompilationUnitElementImpl] for the compilation unit currently being
-   * resynthesized.
-   */
-  CompilationUnitElementImpl unit;
-
-  /**
-   * Map from slot id to the corresponding [EntityRef] object for linked types
-   * (i.e. propagated and inferred types).
-   */
-  final Map<int, EntityRef> linkedTypeMap = <int, EntityRef>{};
-
-  /**
-   * Set of slot ids corresponding to const constructors that are part of
-   * cycles.
-   */
-  Set<int> constCycles;
-
-  /**
-   * Set of slot ids corresponding to parameters that inherit `@covariant`
-   * behavior.
-   */
-  Set<int> parametersInheritingCovariant;
-
-  int numLinkedReferences;
-  int numUnlinkedReferences;
-
-  /**
-   * List of [_ReferenceInfo] objects describing the references in the current
-   * compilation unit.  This list is works as a lazily filled cache, use
-   * [getReferenceInfo] to get the [_ReferenceInfo] for an index.
-   */
-  List<_ReferenceInfo> referenceInfos;
-
-  /**
-   * The [ResynthesizerContext] for this resynthesize session.
-   */
-  ResynthesizerContext _resynthesizerContext;
-
-  _UnitResynthesizer(this.libraryResynthesizer, this.unlinkedUnit,
-      this.linkedUnit, Source unitSource, UnlinkedPart unlinkedPart) {
-    _resynthesizerContext = new SummaryResynthesizerContext(this);
-    unit = new CompilationUnitElementImpl.forSerialized(
-        libraryResynthesizer.library,
-        _resynthesizerContext,
-        unlinkedUnit,
-        unlinkedPart);
-
-    {
-      List<int> lineStarts = unlinkedUnit.lineStarts;
-      if (lineStarts.isEmpty) {
-        lineStarts = const <int>[0];
-      }
-      unit.lineInfo = new LineInfo(lineStarts);
-    }
-
-    for (EntityRef t in linkedUnit.types) {
-      linkedTypeMap[t.slot] = t;
-    }
-    constCycles = linkedUnit.constCycles.toSet();
-    parametersInheritingCovariant =
-        linkedUnit.parametersInheritingCovariant.toSet();
-    numLinkedReferences = linkedUnit.references.length;
-    numUnlinkedReferences = unlinkedUnit.references.length;
-    referenceInfos = new List<_ReferenceInfo>(numLinkedReferences);
-  }
-
-  @override
-  LibraryElement get library => libraryResynthesizer.library;
-
-  SummaryResynthesizer get summaryResynthesizer =>
-      libraryResynthesizer.summaryResynthesizer;
-
-  @override
-  TypeProvider get typeProvider => summaryResynthesizer.typeProvider;
-
-  @override
-  TypeSystem get typeSystem => summaryResynthesizer.typeSystem;
-
-  /**
-   * Build [ElementAnnotationImpl] for the given [UnlinkedExpr].
-   */
-  ElementAnnotationImpl buildAnnotation(ElementImpl context, UnlinkedExpr uc) {
-    ElementAnnotationImpl elementAnnotation = new ElementAnnotationImpl(unit);
-    Expression constExpr = _buildConstExpression(context, uc);
-    if (constExpr == null) {
-      // Invalid constant expression.
-    } else if (constExpr is Identifier) {
-      ArgumentList arguments = constExpr.getProperty(ExprBuilder.ARGUMENT_LIST);
-      elementAnnotation.element = constExpr.staticElement;
-      elementAnnotation.annotationAst =
-          AstTestFactory.annotation2(constExpr, null, arguments);
-    } else if (constExpr is InstanceCreationExpression) {
-      var element = constExpr.staticElement;
-      elementAnnotation.element = element;
-      Identifier typeName = constExpr.constructorName.type.name;
-      SimpleIdentifier constructorName = constExpr.constructorName.name;
-      if (typeName is SimpleIdentifier && constructorName != null) {
-        // E.g. `@cls.ctor()`.  Since `cls.ctor` would have been parsed as
-        // a PrefixedIdentifier, we need to resynthesize it as one.
-        typeName = AstTestFactory.identifier(typeName, constructorName);
-        constructorName = null;
-      }
-      elementAnnotation.annotationAst = AstTestFactory.annotation2(
-          typeName, constructorName, constExpr.argumentList)
-        ..element = constExpr.staticElement;
-    } else if (constExpr is PropertyAccess) {
-      var target = constExpr.target as Identifier;
-      var propertyName = constExpr.propertyName;
-      var propertyElement = propertyName.staticElement;
-      ArgumentList arguments = constExpr.getProperty(ExprBuilder.ARGUMENT_LIST);
-      elementAnnotation.element = propertyElement;
-      elementAnnotation.annotationAst =
-          AstTestFactory.annotation2(target, propertyName, arguments)
-            ..element = propertyElement;
-    } else {
-      throw new StateError(
-          'Unexpected annotation type: ${constExpr.runtimeType}');
-    }
-    return elementAnnotation;
-  }
-
-  /**
-   * Build an implicit getter for the given [property] and bind it to the
-   * [property] and to its enclosing element.
-   */
-  PropertyAccessorElementImpl buildImplicitGetter(
-      PropertyInducingElementImpl property) {
-    PropertyAccessorElementImpl_ImplicitGetter getter =
-        new PropertyAccessorElementImpl_ImplicitGetter(property);
-    getter.enclosingElement = property.enclosingElement;
-    return getter;
-  }
-
-  /**
-   * Build an implicit setter for the given [property] and bind it to the
-   * [property] and to its enclosing element.
-   */
-  PropertyAccessorElementImpl buildImplicitSetter(
-      PropertyInducingElementImpl property) {
-    PropertyAccessorElementImpl_ImplicitSetter setter =
-        new PropertyAccessorElementImpl_ImplicitSetter(property);
-    setter.enclosingElement = property.enclosingElement;
-    return setter;
-  }
-
-  /**
-   * Build the appropriate [DartType] object corresponding to a slot id in the
-   * [LinkedUnit.types] table.
-   */
-  DartType buildLinkedType(ElementImpl context, int slot) {
-    if (slot == 0) {
-      // A slot id of 0 means there is no [DartType] object to build.
-      return null;
-    }
-    EntityRef type = linkedTypeMap[slot];
-    if (type == null) {
-      // A missing entry in [LinkedUnit.types] means there is no [DartType]
-      // stored in this slot.
-      return null;
-    }
-    return buildType(context, type);
-  }
-
-  @override
-  DartType buildType(ElementImpl context, EntityRef type,
-      {bool defaultVoid: false,
-      bool instantiateToBoundsAllowed: true,
-      bool declaredType: false}) {
-    if (type == null) {
-      if (defaultVoid) {
-        return VoidTypeImpl.instance;
-      } else {
-        return DynamicTypeImpl.instance;
-      }
-    }
-    if (type.refinedSlot != 0) {
-      var refinedType = linkedTypeMap[type.refinedSlot];
-      if (refinedType != null) {
-        type = refinedType;
-      }
-    }
-    DartType result;
-    if (type.paramReference != 0) {
-      result = context.typeParameterContext
-          .getTypeParameterType(type.paramReference);
-    } else if (type.entityKind == EntityRefKind.genericFunctionType) {
-      GenericFunctionTypeElement element =
-          new GenericFunctionTypeElementImpl.forSerialized(context, type);
-      result = element.type;
-    } else if (type.syntheticReturnType != null) {
-      FunctionElementImpl element =
-          new FunctionElementImpl_forLUB(context, type);
-      result = element.type;
-    } else {
-      DartType getTypeArgument(int i) {
-        if (i < type.typeArguments.length) {
-          return buildType(context, type.typeArguments[i],
-              declaredType: declaredType);
-        } else {
-          return DynamicTypeImpl.instance;
-        }
-      }
-
-      _ReferenceInfo referenceInfo = getReferenceInfo(type.reference);
-      if (declaredType && !referenceInfo.isDeclarableType) {
-        return DynamicTypeImpl.instance;
-      }
-
-      result = referenceInfo.buildType(
-          instantiateToBoundsAllowed,
-          type.typeArguments.length,
-          getTypeArgument,
-          type.implicitFunctionTypeIndices);
-    }
-    var nullabilitySuffix = decodeNullabilitySuffix(type.nullabilitySuffix);
-    return (result as TypeImpl).withNullability(nullabilitySuffix);
-  }
-
-  @override
-  DartType buildTypeForClassInfo(covariant _ReferenceInfo info,
-          int numTypeArguments, DartType getTypeArgument(int i)) =>
-      info.buildType(true, numTypeArguments, getTypeArgument, const <int>[]);
-
-  UnitExplicitTopLevelAccessors buildUnitExplicitTopLevelAccessors() {
-    Map<String, TopLevelVariableElementImpl> implicitVariables =
-        new HashMap<String, TopLevelVariableElementImpl>();
-    UnitExplicitTopLevelAccessors accessorsData =
-        new UnitExplicitTopLevelAccessors();
-    for (UnlinkedExecutable unlinkedExecutable in unlinkedUnit.executables) {
-      UnlinkedExecutableKind kind = unlinkedExecutable.kind;
-      if (kind == UnlinkedExecutableKind.getter ||
-          kind == UnlinkedExecutableKind.setter) {
-        // name
-        String name = unlinkedExecutable.name;
-        if (kind == UnlinkedExecutableKind.setter) {
-          assert(name.endsWith('='));
-          name = name.substring(0, name.length - 1);
-        }
-        // create
-        PropertyAccessorElementImpl accessor =
-            new PropertyAccessorElementImpl.forSerialized(
-                unlinkedExecutable, unit);
-        accessorsData.accessors.add(accessor);
-        // implicit variable
-        TopLevelVariableElementImpl variable = implicitVariables[name];
-        if (variable == null) {
-          variable = new TopLevelVariableElementImpl(name, -1);
-          variable.enclosingElement = unit;
-          implicitVariables[name] = variable;
-          accessorsData.implicitVariables.add(variable);
-          variable.isSynthetic = true;
-          variable.isFinal = kind == UnlinkedExecutableKind.getter;
-        } else {
-          variable.isFinal = false;
-        }
-        accessor.variable = variable;
-        // link
-        if (kind == UnlinkedExecutableKind.getter) {
-          variable.getter = accessor;
-        } else {
-          variable.setter = accessor;
-        }
-      }
-    }
-    return accessorsData;
-  }
-
-  UnitExplicitTopLevelVariables buildUnitExplicitTopLevelVariables() {
-    List<UnlinkedVariable> unlinkedVariables = unlinkedUnit.variables;
-    int numberOfVariables = unlinkedVariables.length;
-    UnitExplicitTopLevelVariables variablesData =
-        new UnitExplicitTopLevelVariables(numberOfVariables);
-    for (int i = 0; i < numberOfVariables; i++) {
-      UnlinkedVariable unlinkedVariable = unlinkedVariables[i];
-      TopLevelVariableElementImpl element;
-      if (unlinkedVariable.initializer?.bodyExpr != null &&
-          unlinkedVariable.isConst) {
-        element = new ConstTopLevelVariableElementImpl.forSerialized(
-            unlinkedVariable, unit);
-      } else {
-        element = new TopLevelVariableElementImpl.forSerialized(
-            unlinkedVariable, unit);
-      }
-      variablesData.variables[i] = element;
-      // implicit accessors
-      variablesData.implicitAccessors.add(buildImplicitGetter(element));
-      if (!(element.isConst || element.isFinal)) {
-        variablesData.implicitAccessors.add(buildImplicitSetter(element));
-      }
-    }
-    return variablesData;
-  }
-
-  @override
-  bool doesTypeHaveImplicitArguments(ParameterizedType type) =>
-      _typesWithImplicitTypeArguments[type] != null;
-
-  @override
-  _ReferenceInfo getReferenceInfo(int index) {
-    // We don't know how to reproduce this.
-    // https://github.com/dart-lang/sdk/issues/35551
-    // https://github.com/dart-lang/sdk/issues/34534
-    // So, adding logging to gather more information.
-    if (index >= referenceInfos.length) {
-      var buffer = StringBuffer();
-      buffer.writeln('librarySource: ${unit.librarySource}');
-      buffer.writeln('unitSource: ${unit.source}');
-      buffer.writeln('unlinkedUnit: ${unlinkedUnit.toJson()}');
-      buffer.writeln('linkedUnit: ${linkedUnit.toJson()}');
-      throw StateError(buffer.toString());
-    }
-
-    _ReferenceInfo result = referenceInfos[index];
-    if (result == null) {
-      LinkedReference linkedReference = linkedUnit.references[index];
-      String name;
-      int containingReference;
-      if (index < numUnlinkedReferences) {
-        name = unlinkedUnit.references[index].name;
-        containingReference = unlinkedUnit.references[index].prefixReference;
-      } else {
-        name = linkedUnit.references[index].name;
-        containingReference = linkedUnit.references[index].containingReference;
-      }
-      _ReferenceInfo enclosingInfo = containingReference != 0
-          ? getReferenceInfo(containingReference)
-          : null;
-      Element element;
-      DartType type;
-      bool isDeclarableType = false;
-      int numTypeParameters = linkedReference.numTypeParameters;
-      if (linkedReference.kind == ReferenceKind.unresolved) {
-        type = DynamicTypeImpl.instance;
-        element = null;
-        isDeclarableType = true;
-      } else if (name == 'dynamic') {
-        type = DynamicTypeImpl.instance;
-        element = type.element;
-        isDeclarableType = true;
-      } else if (name == 'void') {
-        type = VoidTypeImpl.instance;
-        element = type.element;
-        isDeclarableType = true;
-      } else if (name == '*bottom*') {
-        type = BottomTypeImpl.instance;
-        element = null;
-        isDeclarableType = true;
-      } else {
-        List<String> locationComponents;
-        if (enclosingInfo != null && enclosingInfo.element is ClassElement) {
-          String identifier = _getElementIdentifier(name, linkedReference.kind);
-          locationComponents =
-              enclosingInfo.element.location.components.toList();
-          locationComponents.add(identifier);
-        } else {
-          String identifier = _getElementIdentifier(name, linkedReference.kind);
-          locationComponents =
-              libraryResynthesizer.getReferencedLocationComponents(
-                  linkedReference.dependency, linkedReference.unit, identifier);
-          if (linkedReference.kind == ReferenceKind.prefix) {
-            locationComponents = <String>[
-              locationComponents[0],
-              locationComponents[2]
-            ];
-          }
-        }
-        ElementLocation location =
-            new ElementLocationImpl.con3(locationComponents);
-        if (enclosingInfo != null) {
-          numTypeParameters += enclosingInfo.numTypeParameters;
-        }
-        switch (linkedReference.kind) {
-          case ReferenceKind.classOrEnum:
-            if (locationComponents.length == 3 &&
-                locationComponents[0] == 'dart:core' &&
-                locationComponents[1] == 'dart:core' &&
-                locationComponents[2] == 'Never') {
-              element = NeverElementImpl.instance;
-              type = BottomTypeImpl.instance;
-            } else {
-              element = new ClassElementHandle(summaryResynthesizer, location);
-            }
-            isDeclarableType = true;
-            break;
-          case ReferenceKind.constructor:
-            assert(location.components.length == 4);
-            element =
-                new ConstructorElementHandle(summaryResynthesizer, location);
-            break;
-          case ReferenceKind.method:
-            assert(location.components.length == 4);
-            element = new MethodElementHandle(summaryResynthesizer, location);
-            break;
-          case ReferenceKind.propertyAccessor:
-            assert(location.components.length == 4);
-            element = new PropertyAccessorElementHandle(
-                summaryResynthesizer, location);
-            break;
-          case ReferenceKind.topLevelFunction:
-            assert(location.components.length == 3);
-            element = new FunctionElementHandle(summaryResynthesizer, location);
-            break;
-          case ReferenceKind.topLevelPropertyAccessor:
-            element = new PropertyAccessorElementHandle(
-                summaryResynthesizer, location);
-            break;
-          case ReferenceKind.typedef:
-          case ReferenceKind.genericFunctionTypedef:
-            element = new GenericTypeAliasElementHandle(
-                summaryResynthesizer, location);
-            isDeclarableType = true;
-            break;
-          case ReferenceKind.function:
-            Element enclosingElement = enclosingInfo.element;
-            if (enclosingElement is VariableElement) {
-              element = new _DeferredInitializerElement(enclosingElement);
-            } else {
-              throw new StateError('Unexpected element enclosing function:'
-                  ' ${enclosingElement.runtimeType}');
-            }
-            break;
-          case ReferenceKind.prefix:
-            element = new PrefixElementHandle(summaryResynthesizer, location);
-            break;
-          case ReferenceKind.variable:
-          case ReferenceKind.unresolved:
-            break;
-        }
-      }
-      result = new _ReferenceInfo(libraryResynthesizer, enclosingInfo, name,
-          isDeclarableType, element, type, numTypeParameters);
-      referenceInfos[index] = result;
-    }
-    return result;
-  }
-
-  /**
-   * Return the error reported during type inference for the given [slot],
-   * or `null` if there were no error.
-   */
-  TopLevelInferenceError getTypeInferenceError(int slot) {
-    if (slot == 0) {
-      return null;
-    }
-    for (TopLevelInferenceError error in linkedUnit.topLevelInferenceErrors) {
-      if (error.slot == slot) {
-        return error;
-      }
-    }
-    return null;
-  }
-
-  Expression _buildConstExpression(ElementImpl context, UnlinkedExpr uc) {
-    return new ExprBuilder(this, context, uc).build();
-  }
-
-  /**
-   * Return the [ConstructorElement] corresponding to the given [entry].
-   */
-  ConstructorElement _getConstructorForEntry(
-      ElementImpl context, EntityRef entry) {
-    _ReferenceInfo info = getReferenceInfo(entry.reference);
-    DartType type =
-        createConstructorDefiningType(context, info, entry.typeArguments);
-    if (type is InterfaceType) {
-      return getConstructorForInfo(type, info);
-    }
-    return null;
-  }
-
-  /**
-   * If the given [kind] is a top-level or class member property accessor, and
-   * the given [name] does not end with `=`, i.e. does not denote a setter,
-   * return the getter identifier by appending `?`.
-   */
-  static String _getElementIdentifier(String name, ReferenceKind kind) {
-    if (kind == ReferenceKind.topLevelPropertyAccessor ||
-        kind == ReferenceKind.propertyAccessor) {
-      if (!name.endsWith('=')) {
-        return name + '?';
-      }
-    }
-    return name;
-  }
-}
diff --git a/pkg/analyzer/lib/src/summary/summarize_ast.dart b/pkg/analyzer/lib/src/summary/summarize_ast.dart
deleted file mode 100644
index 401122b..0000000
--- a/pkg/analyzer/lib/src/summary/summarize_ast.dart
+++ /dev/null
@@ -1,1511 +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 'package:analyzer/dart/analysis/features.dart';
-import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/ast/token.dart';
-import 'package:analyzer/dart/ast/visitor.dart';
-import 'package:analyzer/src/dart/ast/mixin_super_invoked_names.dart';
-import 'package:analyzer/src/summary/api_signature.dart';
-import 'package:analyzer/src/summary/format.dart';
-import 'package:analyzer/src/summary/idl.dart';
-import 'package:analyzer/src/summary/public_namespace_computer.dart';
-import 'package:analyzer/src/summary/summarize_const_expr.dart';
-
-/// Serialize all the declarations in [compilationUnit] to an unlinked summary.
-///
-/// [serializeInferrableFields] indicates whether field initializers and closure
-/// bodies should be serialized to facilitate type inference.
-UnlinkedUnitBuilder serializeAstUnlinked(CompilationUnit compilationUnit,
-    {bool serializeInferrableFields: true}) {
-  return new _SummarizeAstVisitor(serializeInferrableFields,
-          compilationUnit.featureSet.isEnabled(Feature.non_nullable))
-      .serializeCompilationUnit(compilationUnit);
-}
-
-/// Instances of this class keep track of intermediate state during
-/// serialization of a single constant [Expression].
-class _ConstExprSerializer extends AbstractConstExprSerializer {
-  final _SummarizeAstVisitor visitor;
-
-  /// If the expression being serialized can contain closures, map whose
-  /// keys are the offsets of local function nodes representing those closures,
-  /// and whose values are indices of those local functions relative to their
-  /// siblings.
-  final Map<int, int> localClosureIndexMap;
-
-  /// The names of local variables and parameters that are in scope.
-  /// This is a list so that we can handle nesting by pushing and popping values
-  /// at the end of it.
-  final List<String> variableNames;
-
-  _ConstExprSerializer(bool forConst, this.visitor, this.localClosureIndexMap,
-      List<String> variableNames)
-      : variableNames = variableNames ?? [],
-        super(forConst);
-
-  @override
-  EntityRefNullabilitySuffix computeNullabilitySuffix(Token question) =>
-      visitor.computeNullabilitySuffix(question);
-
-  @override
-  bool isParameterName(String name) {
-    return variableNames?.contains(name) ?? false;
-  }
-
-  @override
-  void popVariableNames(int count) {
-    variableNames.length -= count;
-  }
-
-  @override
-  void pushVariableName(String name) {
-    variableNames.add(name);
-  }
-
-  @override
-  void serialize(Expression expr) {
-    int startingVariableCount = variableNames.length;
-    super.serialize(expr);
-    assert(startingVariableCount == variableNames.length);
-  }
-
-  @override
-  void serializeAnnotation(Annotation annotation) {
-    Identifier name = annotation.name;
-    EntityRefBuilder constructor;
-    if (name is PrefixedIdentifier && annotation.constructorName == null) {
-      constructor = serializeConstructorRef(name.prefix, null, name.identifier);
-    } else {
-      constructor = serializeConstructorRef(
-          annotation.name, null, annotation.constructorName);
-    }
-    if (annotation.arguments == null) {
-      references.add(constructor);
-      operations.add(UnlinkedExprOperation.pushReference);
-    } else {
-      serializeInstanceCreation(constructor, annotation.arguments, false);
-    }
-  }
-
-  @override
-  EntityRefBuilder serializeConstructorRef(Identifier typeName,
-      TypeArgumentList typeArguments, SimpleIdentifier name) {
-    EntityRefBuilder typeBuilder = serializeTypeName(
-        typeName, typeArguments, EntityRefNullabilitySuffix.starOrIrrelevant);
-    if (name == null) {
-      return typeBuilder;
-    } else {
-      int nameRef =
-          visitor.serializeReference(typeBuilder.reference, name.name);
-      return new EntityRefBuilder(
-          reference: nameRef, typeArguments: typeBuilder.typeArguments);
-    }
-  }
-
-  @override
-  List<int> serializeFunctionExpression(FunctionExpression functionExpression) {
-    int localIndex;
-    if (localClosureIndexMap == null) {
-      return null;
-    } else {
-      localIndex = localClosureIndexMap[functionExpression.offset];
-      assert(localIndex != null);
-      return <int>[0, localIndex];
-    }
-  }
-
-  @override
-  EntityRefBuilder serializeGenericFunctionType(GenericFunctionType node) =>
-      visitor.serializeGenericFunctionType(node);
-
-  EntityRefBuilder serializeIdentifier(Identifier identifier) {
-    EntityRefBuilder b =
-        new EntityRefBuilder(nullabilitySuffix: computeNullabilitySuffix(null));
-    if (identifier is SimpleIdentifier) {
-      int index = visitor.serializeSimpleReference(identifier.name);
-      if (index < 0) {
-        b.paramReference = -index;
-      } else {
-        b.reference = index;
-      }
-    } else if (identifier is PrefixedIdentifier) {
-      int prefix = visitor.serializeSimpleReference(identifier.prefix.name);
-      if (prefix < 0) {
-        throw new StateError('Invalid type parameter usage: $identifier}');
-      }
-      b.reference =
-          visitor.serializeReference(prefix, identifier.identifier.name);
-    } else {
-      throw new StateError(
-          'Unexpected identifier type: ${identifier.runtimeType}');
-    }
-    return b;
-  }
-
-  @override
-  EntityRefBuilder serializeIdentifierSequence(Expression expr) {
-    if (expr is Identifier) {
-      AstNode parent = expr.parent;
-      if (parent is MethodInvocation &&
-          parent.methodName == expr &&
-          parent.target != null) {
-        int targetId = serializeIdentifierSequence(parent.target).reference;
-        int nameId = visitor.serializeReference(targetId, expr.name);
-        return new EntityRefBuilder(reference: nameId);
-      }
-      return serializeIdentifier(expr);
-    }
-    if (expr is PropertyAccess) {
-      int targetId = serializeIdentifierSequence(expr.target).reference;
-      int nameId = visitor.serializeReference(targetId, expr.propertyName.name);
-      return new EntityRefBuilder(reference: nameId);
-    } else {
-      throw new StateError('Unexpected node type: ${expr.runtimeType}');
-    }
-  }
-
-  @override
-  EntityRefBuilder serializeTypeName(
-      Identifier name,
-      TypeArgumentList arguments,
-      EntityRefNullabilitySuffix nullabilitySuffix) {
-    return visitor.serializeTypeName(name, arguments, nullabilitySuffix);
-  }
-}
-
-/// A [_Scope] represents a set of name/value pairs defined locally within a
-/// limited span of a compilation unit.  (Note that the spec also uses the term
-/// "scope" to refer to the set of names defined at top level within a
-/// compilation unit, but we do not use [_Scope] for that purpose).
-class _Scope {
-  /// Names defined in this scope, and their meanings.
-  Map<String, _ScopedEntity> _definedNames = <String, _ScopedEntity>{};
-
-  /// Look up the meaning associated with the given [name], and return it.  If
-  /// [name] is not defined in this scope, return `null`.
-  _ScopedEntity operator [](String name) => _definedNames[name];
-
-  /// Let the given [name] refer to [entity] within this scope.
-  void operator []=(String name, _ScopedEntity entity) {
-    _definedNames[name] = entity;
-  }
-}
-
-/// A [_ScopedClassMember] is a [_ScopedEntity] refers to a member of a class.
-class _ScopedClassMember extends _ScopedEntity {
-  /// The name of the class.
-  final String className;
-
-  _ScopedClassMember(this.className);
-}
-
-/// Base class for entities that can live inside a scope.
-abstract class _ScopedEntity {}
-
-/// A [_ScopedTypeParameter] is a [_ScopedEntity] that refers to a type
-/// parameter of a class, typedef, or executable.
-class _ScopedTypeParameter extends _ScopedEntity {
-  /// Index of the type parameter within this scope.  Since summaries use De
-  /// Bruijn indices to refer to type parameters, which count upwards from the
-  /// innermost bound name, the last type parameter in the scope has an index of
-  /// 1, and each preceding type parameter has the next higher index.
-  final int index;
-
-  _ScopedTypeParameter(this.index);
-}
-
-/// Visitor used to create a summary from an AST.
-class _SummarizeAstVisitor extends RecursiveAstVisitor {
-  /// Indicates whether non-const field initializers and closure bodies should
-  /// be serialized to facilitate type inference.
-  ///
-  /// For one-phase summary generation, the only field initializers that need to
-  /// be serialized are those involved in constants, since type inference is
-  /// performed using the AST representation.
-  final bool _serializeInferrableFields;
-
-  final bool _nnbd;
-
-  /// List of objects which should be written to [UnlinkedUnit.classes].
-  final List<UnlinkedClassBuilder> classes = <UnlinkedClassBuilder>[];
-
-  /// List of objects which should be written to [UnlinkedUnit.enums].
-  final List<UnlinkedEnumBuilder> enums = <UnlinkedEnumBuilder>[];
-
-  /// List of objects which should be written to [UnlinkedUnit.executables],
-  /// [UnlinkedClass.executables] or [UnlinkedExecutable.localFunctions].
-  List<UnlinkedExecutableBuilder> executables = <UnlinkedExecutableBuilder>[];
-
-  /// List of objects which should be written to [UnlinkedUnit.extensions].
-  final List<UnlinkedExtensionBuilder> extensions =
-      <UnlinkedExtensionBuilder>[];
-
-  /// List of objects which should be written to [UnlinkedUnit.exports].
-  final List<UnlinkedExportNonPublicBuilder> exports =
-      <UnlinkedExportNonPublicBuilder>[];
-
-  /// Whether the current class declaration has a `const` constructor.
-  bool enclosingClassHasConstConstructor = false;
-
-  /// List of objects which should be written to [UnlinkedUnit.mixins].
-  final List<UnlinkedClassBuilder> mixins = <UnlinkedClassBuilder>[];
-
-  /// List of names of methods, getters, setters, and operators that are
-  /// super-invoked in the current mixin declaration.
-  Set<String> mixinSuperInvokedNames;
-
-  /// List of objects which should be written to [UnlinkedUnit.parts].
-  final List<UnlinkedPartBuilder> parts = <UnlinkedPartBuilder>[];
-
-  /// List of objects which should be written to [UnlinkedUnit.typedefs].
-  final List<UnlinkedTypedefBuilder> typedefs = <UnlinkedTypedefBuilder>[];
-
-  /// List of objects which should be written to [UnlinkedUnit.variables] or
-  /// [UnlinkedClass.fields].
-  List<UnlinkedVariableBuilder> variables = <UnlinkedVariableBuilder>[];
-
-  /// The unlinked portion of the "imports table".  This is the list of objects
-  /// which should be written to [UnlinkedUnit.imports].
-  final List<UnlinkedImportBuilder> unlinkedImports = <UnlinkedImportBuilder>[];
-
-  /// The unlinked portion of the "references table".  This is the list of
-  /// objects which should be written to [UnlinkedUnit.references].
-  final List<UnlinkedReferenceBuilder> unlinkedReferences =
-      <UnlinkedReferenceBuilder>[new UnlinkedReferenceBuilder()];
-
-  /// List of [_Scope]s currently in effect.  This is used to resolve type names
-  /// to type parameters within classes, typedefs, and executables, as well as
-  /// references to class members.
-  final List<_Scope> scopes = <_Scope>[];
-
-  /// True if 'dart:core' has been explicitly imported.
-  bool hasCoreBeenImported = false;
-
-  /// Names referenced by this compilation unit.  Structured as a map from
-  /// prefix index to (map from name to reference table index), where "prefix
-  /// index" means the index into [UnlinkedUnit.references] of the prefix (or
-  /// `null` if there is no prefix), and "reference table index" means the index
-  /// into [UnlinkedUnit.references] for the name itself.
-  final Map<int, Map<String, int>> nameToReference = <int, Map<String, int>>{};
-
-  /// True if the 'dart:core' library is been summarized.
-  bool isCoreLibrary = false;
-
-  /// True if the 'dart:core' library defining unit is been summarized.
-  bool isCoreLibraryDefiningUnit = false;
-
-  /// True is a [PartOfDirective] was found, so the unit is a part.
-  bool isPartOf = false;
-
-  /// If the library has a library directive, the library name derived from it.
-  /// Otherwise `null`.
-  String libraryName;
-
-  /// If the library has a library directive, the offset of the library name.
-  /// Otherwise `null`.
-  int libraryNameOffset;
-
-  /// If the library has a library directive, the length of the library name, as
-  /// it appears in the source file.  Otherwise `null`.
-  int libraryNameLength;
-
-  /// If the library has a library directive, the documentation comment for it
-  /// (if any).  Otherwise `null`.
-  UnlinkedDocumentationCommentBuilder libraryDocumentationComment;
-
-  /// If the library has a library directive, the annotations for it (if any).
-  /// Otherwise `null`.
-  List<UnlinkedExpr> libraryAnnotations = const <UnlinkedExprBuilder>[];
-
-  /// The number of slot ids which have been assigned to this compilation unit.
-  int numSlots = 0;
-
-  /// The [Block] that is being visited now, or `null` for non-local contexts.
-  Block enclosingBlock = null;
-
-  /// If an expression is being serialized which can contain closures, map whose
-  /// keys are the offsets of local function nodes representing those closures,
-  /// and whose values are indices of those local functions relative to their
-  /// siblings.
-  Map<int, int> _localClosureIndexMap;
-
-  /// Indicates whether closure function bodies should be serialized.  This flag
-  /// is set while visiting the bodies of initializer expressions that will be
-  /// needed by type inference.
-  bool _serializeClosureBodyExprs = false;
-
-  /// The set of variable names which are currently in scope.
-  List<String> _variableNames = [];
-
-  /// Indicates whether parameters found during visitors might inherit
-  /// covariance.
-  bool _parametersMayInheritCovariance = false;
-
-  _SummarizeAstVisitor(this._serializeInferrableFields, this._nnbd);
-
-  /// Create a slot id for storing a propagated or inferred type or const cycle
-  /// info.
-  int assignSlot() => ++numSlots;
-
-  /// Build a [_Scope] object containing the names defined within the body of a
-  /// class declaration.
-  _Scope buildClassMemberScope(
-      String className, NodeList<ClassMember> members) {
-    _Scope scope = new _Scope();
-    for (ClassMember member in members) {
-      if (member is MethodDeclaration) {
-        if (member.isSetter || member.isOperator) {
-          // We don't have to handle setters or operators because the only
-          // things we look up are type names and identifiers.
-        } else {
-          scope[member.name.name] = new _ScopedClassMember(className);
-        }
-      } else if (member is FieldDeclaration) {
-        for (VariableDeclaration field in member.fields.variables) {
-          // A field declaration introduces two names, one with a trailing `=`.
-          // We don't have to worry about the one with a trailing `=` because
-          // the only things we look up are type names and identifiers.
-          scope[field.name.name] = new _ScopedClassMember(className);
-        }
-      }
-    }
-    return scope;
-  }
-
-  EntityRefNullabilitySuffix computeNullabilitySuffix(Token question) {
-    if (!_nnbd) return EntityRefNullabilitySuffix.starOrIrrelevant;
-    if (question != null) return EntityRefNullabilitySuffix.question;
-    return EntityRefNullabilitySuffix.none;
-  }
-
-  /// Serialize the given list of [annotations].  If there are no annotations,
-  /// the empty list is returned.
-  List<UnlinkedExprBuilder> serializeAnnotations(
-      NodeList<Annotation> annotations) {
-    if (annotations == null || annotations.isEmpty) {
-      return const <UnlinkedExprBuilder>[];
-    }
-    return annotations.map((Annotation a) {
-      // Closures can't appear inside annotations, so we don't need a
-      // localClosureIndexMap.
-      Map<int, int> localClosureIndexMap = null;
-      _ConstExprSerializer serializer =
-          new _ConstExprSerializer(true, this, localClosureIndexMap, null);
-      try {
-        serializer.serializeAnnotation(a);
-      } on StateError {
-        return new UnlinkedExprBuilder()..isValidConst = false;
-      }
-      return serializer.toBuilder(a.atSign.next, a.endToken);
-    }).toList();
-  }
-
-  /// Serialize a [ClassDeclaration] or [ClassTypeAlias] into an [UnlinkedClass]
-  /// and store the result in [classes].
-  void serializeClass(
-      AstNode node,
-      Token abstractKeyword,
-      String name,
-      int nameOffset,
-      TypeParameterList typeParameters,
-      TypeName superclass,
-      WithClause withClause,
-      ImplementsClause implementsClause,
-      NodeList<ClassMember> members,
-      bool isMixinApplication,
-      Comment documentationComment,
-      NodeList<Annotation> annotations) {
-    int oldScopesLength = scopes.length;
-    enclosingClassHasConstConstructor = node is ClassDeclaration &&
-        node.members
-            .any((m) => m is ConstructorDeclaration && m.constKeyword != null);
-    List<UnlinkedExecutableBuilder> oldExecutables = executables;
-    executables = <UnlinkedExecutableBuilder>[];
-    List<UnlinkedVariableBuilder> oldVariables = variables;
-    variables = <UnlinkedVariableBuilder>[];
-    _TypeParameterScope typeParameterScope = new _TypeParameterScope();
-    scopes.add(typeParameterScope);
-    UnlinkedClassBuilder b = new UnlinkedClassBuilder();
-    b.name = name;
-    b.nameOffset = nameOffset;
-    b.isMixinApplication = isMixinApplication;
-    b.typeParameters =
-        serializeTypeParameters(typeParameters, typeParameterScope);
-    if (_shouldAssignNotSimplyBoundedSlot(typeParameters)) {
-      b.notSimplyBoundedSlot = assignSlot();
-    }
-    if (superclass != null) {
-      b.supertype = serializeType(superclass);
-    } else {
-      b.hasNoSupertype = isCoreLibrary && name == 'Object';
-    }
-    if (withClause != null) {
-      b.mixins = withClause.mixinTypes.map(serializeMixedInType).toList();
-    }
-    if (implementsClause != null) {
-      b.interfaces = implementsClause.interfaces.map(serializeType).toList();
-    }
-    if (members != null) {
-      scopes.add(buildClassMemberScope(name, members));
-      for (ClassMember member in members) {
-        member.accept(this);
-      }
-      scopes.removeLast();
-    }
-    b.executables = executables;
-    b.fields = variables;
-    b.isAbstract = abstractKeyword != null;
-    b.documentationComment = serializeDocumentation(documentationComment);
-    b.annotations = serializeAnnotations(annotations);
-    b.codeRange = serializeCodeRange(node);
-    classes.add(b);
-    scopes.removeLast();
-    assert(scopes.length == oldScopesLength);
-    executables = oldExecutables;
-    variables = oldVariables;
-  }
-
-  /// Create a [CodeRangeBuilder] for the given [node].
-  CodeRangeBuilder serializeCodeRange(AstNode node) {
-    return new CodeRangeBuilder(offset: node.offset, length: node.length);
-  }
-
-  /// Serialize a [Combinator] into an [UnlinkedCombinator].
-  UnlinkedCombinatorBuilder serializeCombinator(Combinator combinator) {
-    UnlinkedCombinatorBuilder b = new UnlinkedCombinatorBuilder();
-    if (combinator is ShowCombinator) {
-      b.shows =
-          combinator.shownNames.map((SimpleIdentifier id) => id.name).toList();
-      b.offset = combinator.offset;
-      b.end = combinator.end;
-    } else if (combinator is HideCombinator) {
-      b.hides =
-          combinator.hiddenNames.map((SimpleIdentifier id) => id.name).toList();
-    } else {
-      throw new StateError(
-          'Unexpected combinator type: ${combinator.runtimeType}');
-    }
-    return b;
-  }
-
-  /// Main entry point for serializing an AST.
-  UnlinkedUnitBuilder serializeCompilationUnit(
-      CompilationUnit compilationUnit) {
-    compilationUnit.directives.accept(this);
-    if (!hasCoreBeenImported) {
-      unlinkedImports.add(new UnlinkedImportBuilder(isImplicit: true));
-    }
-    compilationUnit.declarations.accept(this);
-    UnlinkedUnitBuilder b = new UnlinkedUnitBuilder(
-        isNNBD: compilationUnit.featureSet.isEnabled(Feature.non_nullable));
-    b.lineStarts = compilationUnit.lineInfo?.lineStarts;
-    b.isPartOf = isPartOf;
-    b.libraryName = libraryName;
-    b.libraryNameOffset = libraryNameOffset;
-    b.libraryNameLength = libraryNameLength;
-    b.libraryDocumentationComment = libraryDocumentationComment;
-    b.libraryAnnotations = libraryAnnotations;
-    b.codeRange = serializeCodeRange(compilationUnit);
-    b.classes = classes;
-    b.enums = enums;
-    b.executables = executables;
-    b.extensions = extensions;
-    b.exports = exports;
-    b.imports = unlinkedImports;
-    b.mixins = mixins;
-    b.parts = parts;
-    b.references = unlinkedReferences;
-    b.typedefs = typedefs;
-    b.variables = variables;
-
-    b.publicNamespace = computePublicNamespace(compilationUnit);
-    if (isCoreLibraryDefiningUnit) {
-      b.publicNamespace.names.add(
-        UnlinkedPublicNameBuilder(
-          name: 'Never',
-          kind: ReferenceKind.classOrEnum,
-        ),
-      );
-    }
-
-    _computeApiSignature(b);
-    return b;
-  }
-
-  /// Serialize the given [expression], creating an [UnlinkedExprBuilder].
-  UnlinkedExprBuilder serializeConstExpr(
-      bool forConst, Map<int, int> localClosureIndexMap, Expression expression,
-      [List<String> variableNames]) {
-    _ConstExprSerializer serializer = new _ConstExprSerializer(
-        forConst, this, localClosureIndexMap, variableNames);
-    serializer.serialize(expression);
-    return serializer.toBuilder(expression.beginToken, expression.endToken);
-  }
-
-  /// Serialize a [Comment] node into an [UnlinkedDocumentationComment] object.
-  UnlinkedDocumentationCommentBuilder serializeDocumentation(
-      Comment documentationComment) {
-    if (documentationComment == null) {
-      return null;
-    }
-    String text = documentationComment.tokens
-        .map((Token t) => t.toString())
-        .join('\n')
-        .replaceAll('\r\n', '\n');
-    return new UnlinkedDocumentationCommentBuilder(text: text);
-  }
-
-  /// Return an entity reference builder representing the type 'dynamic'.
-  EntityRefBuilder serializeDynamic() {
-    EntityRefBuilder builder = new EntityRefBuilder();
-    builder.reference = serializeReference(null, 'dynamic');
-    return builder;
-  }
-
-  /// Serialize an [EnumConstantDeclaration] into an [UnlinkedEnumValue].
-  UnlinkedEnumValueBuilder serializeEnumConstantDeclaration(
-      EnumConstantDeclaration node) {
-    return new UnlinkedEnumValueBuilder(
-        annotations: serializeAnnotations(node.metadata),
-        documentationComment: serializeDocumentation(node.documentationComment),
-        name: node.name.name,
-        nameOffset: node.name.offset);
-  }
-
-  /// Serialize a [FunctionDeclaration] or [MethodDeclaration] into an
-  /// [UnlinkedExecutable].
-  ///
-  /// If [serializeBodyExpr] is `true`, then the function definition is stored
-  /// in [UnlinkedExecutableBuilder.bodyExpr].
-  UnlinkedExecutableBuilder serializeExecutable(
-      AstNode node,
-      String name,
-      int nameOffset,
-      bool isGetter,
-      bool isSetter,
-      TypeAnnotation returnType,
-      FormalParameterList formalParameters,
-      FunctionBody body,
-      bool isTopLevel,
-      bool isDeclaredStatic,
-      Comment documentationComment,
-      NodeList<Annotation> annotations,
-      TypeParameterList typeParameters,
-      bool isExternal,
-      bool serializeBodyExpr,
-      bool serializeBody) {
-    int oldScopesLength = scopes.length;
-    _TypeParameterScope typeParameterScope = new _TypeParameterScope();
-    scopes.add(typeParameterScope);
-    UnlinkedExecutableBuilder b = new UnlinkedExecutableBuilder();
-    String nameString = name;
-    if (isGetter) {
-      b.kind = UnlinkedExecutableKind.getter;
-    } else if (isSetter) {
-      b.kind = UnlinkedExecutableKind.setter;
-      nameString = '$nameString=';
-    } else {
-      b.kind = UnlinkedExecutableKind.functionOrMethod;
-    }
-    b.isExternal = isExternal;
-    b.isAbstract = !isExternal && body is EmptyFunctionBody;
-    b.isAsynchronous = body.isAsynchronous;
-    b.isGenerator = body.isGenerator;
-    b.name = nameString;
-    b.nameOffset = nameOffset;
-    b.typeParameters =
-        serializeTypeParameters(typeParameters, typeParameterScope);
-    if (!isTopLevel) {
-      b.isStatic = isDeclaredStatic;
-    }
-    b.returnType = serializeType(returnType);
-    bool isSemanticallyStatic = isTopLevel || isDeclaredStatic;
-    if (formalParameters != null) {
-      bool oldMayInheritCovariance = _parametersMayInheritCovariance;
-      _parametersMayInheritCovariance = !isTopLevel && !isDeclaredStatic;
-      b.parameters = formalParameters.parameters
-          .map((FormalParameter p) => p.accept(this) as UnlinkedParamBuilder)
-          .toList();
-      _parametersMayInheritCovariance = oldMayInheritCovariance;
-      if (!isSemanticallyStatic) {
-        for (int i = 0; i < formalParameters.parameters.length; i++) {
-          if (!b.parameters[i].isFunctionTyped &&
-              b.parameters[i].type == null) {
-            b.parameters[i].inferredTypeSlot = assignSlot();
-          }
-        }
-      }
-    }
-    b.documentationComment = serializeDocumentation(documentationComment);
-    b.annotations = serializeAnnotations(annotations);
-    b.codeRange = serializeCodeRange(node);
-    if (returnType == null && !isSemanticallyStatic) {
-      b.inferredReturnTypeSlot = assignSlot();
-    }
-    b.visibleOffset = enclosingBlock?.offset;
-    b.visibleLength = enclosingBlock?.length;
-    int oldVariableNamesLength = _variableNames.length;
-    if (formalParameters != null && formalParameters.parameters.isNotEmpty) {
-      _variableNames.addAll(formalParameters.parameters
-          .map((FormalParameter p) => p.identifier.name));
-    }
-    serializeFunctionBody(
-        b, null, body, serializeBodyExpr, serializeBody, false);
-
-    if (mixinSuperInvokedNames != null) {
-      body?.accept(new MixinSuperInvokedNamesCollector(mixinSuperInvokedNames));
-    }
-
-    _variableNames.length = oldVariableNamesLength;
-    scopes.removeLast();
-    assert(scopes.length == oldScopesLength);
-    return b;
-  }
-
-  /// Record local functions and variables into the given executable. The given
-  /// [body] is usually an actual [FunctionBody], but may be an [Expression]
-  /// when we process a synthetic variable initializer function.
-  ///
-  /// If [initializers] is non-`null`, closures occurring inside the
-  /// initializers are serialized first.
-  ///
-  /// If [serializeBodyExpr] is `true`, then the function definition is stored
-  /// in [UnlinkedExecutableBuilder.bodyExpr], and closures occurring inside
-  /// [initializers] and [body] have their function bodies serialized as well.
-  ///
-  /// The return value is a map whose keys are the offsets of local function
-  /// nodes representing closures inside [initializers] and [body], and whose
-  /// values are the indices of those local functions relative to their
-  /// siblings.
-  Map<int, int> serializeFunctionBody(
-      UnlinkedExecutableBuilder b,
-      List<ConstructorInitializer> initializers,
-      AstNode body,
-      bool serializeBodyExpr,
-      bool serializeBody,
-      bool forConst) {
-    if (body is BlockFunctionBody || body is ExpressionFunctionBody) {
-      for (UnlinkedParamBuilder parameter in b.parameters) {
-        if (!parameter.isInitializingFormal) {
-          parameter.visibleOffset = body.offset;
-          parameter.visibleLength = body.length;
-        }
-      }
-    }
-    List<UnlinkedExecutableBuilder> oldExecutables = executables;
-    Map<int, int> oldLocalClosureIndexMap = _localClosureIndexMap;
-    bool oldSerializeClosureBodyExprs = _serializeClosureBodyExprs;
-    executables = <UnlinkedExecutableBuilder>[];
-    _localClosureIndexMap = <int, int>{};
-    _serializeClosureBodyExprs =
-        serializeBodyExpr && _serializeInferrableFields;
-    if (initializers != null) {
-      for (ConstructorInitializer initializer in initializers) {
-        initializer.accept(this);
-      }
-    }
-    if (serializeBody) {
-      body.accept(this);
-    }
-    if (serializeBodyExpr) {
-      if (body is Expression) {
-        b.bodyExpr = serializeConstExpr(
-            forConst, _localClosureIndexMap, body, _variableNames);
-      } else if (body is ExpressionFunctionBody) {
-        b.bodyExpr = serializeConstExpr(
-            forConst, _localClosureIndexMap, body.expression, _variableNames);
-      } else {
-        // TODO(paulberry): serialize other types of function bodies.
-      }
-    }
-    b.localFunctions = executables;
-    Map<int, int> localClosureIndexMap = _localClosureIndexMap;
-    executables = oldExecutables;
-    _localClosureIndexMap = oldLocalClosureIndexMap;
-    _serializeClosureBodyExprs = oldSerializeClosureBodyExprs;
-    return localClosureIndexMap;
-  }
-
-  /// Serialize the return type and parameters of a function-typed formal
-  /// parameter and store them in [b].
-  void serializeFunctionTypedParameterDetails(UnlinkedParamBuilder b,
-      TypeAnnotation returnType, FormalParameterList parameters) {
-    EntityRefBuilder serializedReturnType = serializeType(returnType);
-    if (serializedReturnType != null) {
-      b.type = serializedReturnType;
-    }
-    bool oldMayInheritCovariance = _parametersMayInheritCovariance;
-    _parametersMayInheritCovariance = false;
-    b.parameters = parameters.parameters
-        .map((FormalParameter p) => p.accept(this) as UnlinkedParamBuilder)
-        .toList();
-    _parametersMayInheritCovariance = oldMayInheritCovariance;
-  }
-
-  /// Serialize a generic function type.
-  EntityRefBuilder serializeGenericFunctionType(GenericFunctionType node) {
-    _TypeParameterScope typeParameterScope = new _TypeParameterScope();
-    scopes.add(typeParameterScope);
-    EntityRefBuilder b = new EntityRefBuilder(
-        nullabilitySuffix: computeNullabilitySuffix(node?.question));
-    b.entityKind = EntityRefKind.genericFunctionType;
-    b.typeParameters =
-        serializeTypeParameters(node.typeParameters, typeParameterScope);
-    b.syntheticReturnType = node.returnType == null
-        ? serializeDynamic()
-        : serializeType(node.returnType);
-    b.syntheticParams = node.parameters.parameters
-        .map((FormalParameter p) => p.accept(this) as UnlinkedParamBuilder)
-        .toList();
-    scopes.removeLast();
-    return b;
-  }
-
-  /// If the given [expression] is not `null`, serialize it as an
-  /// [UnlinkedExecutableBuilder], otherwise return `null`.
-  ///
-  /// If [serializeBodyExpr] is `true`, then the initializer expression is
-  /// stored in [UnlinkedExecutableBuilder.bodyExpr].
-  UnlinkedExecutableBuilder serializeInitializerFunction(
-      Expression expression, bool serializeBodyExpr, bool forConst) {
-    if (expression == null) {
-      return null;
-    }
-    UnlinkedExecutableBuilder initializer =
-        new UnlinkedExecutableBuilder(nameOffset: expression.offset);
-    serializeFunctionBody(
-        initializer, null, expression, serializeBodyExpr, true, forConst);
-    initializer.inferredReturnTypeSlot = assignSlot();
-    return initializer;
-  }
-
-  /// Serialize a type name that appears in a "with" clause to an [EntityRef].
-  EntityRefBuilder serializeMixedInType(TypeAnnotation node) {
-    var builder = serializeType(node);
-    if (builder != null && builder.typeArguments.isEmpty) {
-      // Type arguments may get inferred so we need to assign a slot to hold the
-      // complete inferred mixed in type.
-      builder.refinedSlot = assignSlot();
-    }
-    return builder;
-  }
-
-  /// Serialize a [MixinDeclaration] into an [UnlinkedClass]
-  /// and store the result in [mixins].
-  void serializeMixin(
-      AstNode node,
-      String name,
-      int nameOffset,
-      TypeParameterList typeParameters,
-      OnClause onClause,
-      ImplementsClause implementsClause,
-      NodeList<ClassMember> members,
-      Comment documentationComment,
-      NodeList<Annotation> annotations) {
-    List<UnlinkedExecutableBuilder> oldExecutables = executables;
-    executables = <UnlinkedExecutableBuilder>[];
-
-    mixinSuperInvokedNames = new Set<String>();
-
-    List<UnlinkedVariableBuilder> oldVariables = variables;
-    variables = <UnlinkedVariableBuilder>[];
-
-    int oldScopesLength = scopes.length;
-    _TypeParameterScope typeParameterScope = new _TypeParameterScope();
-    scopes.add(typeParameterScope);
-
-    UnlinkedClassBuilder b = new UnlinkedClassBuilder();
-    b.name = name;
-    b.nameOffset = nameOffset;
-    b.typeParameters =
-        serializeTypeParameters(typeParameters, typeParameterScope);
-    if (onClause != null) {
-      b.superclassConstraints =
-          onClause.superclassConstraints.map(serializeType).toList();
-    }
-    if (implementsClause != null) {
-      b.interfaces = implementsClause.interfaces.map(serializeType).toList();
-    }
-    if (members != null) {
-      scopes.add(buildClassMemberScope(name, members));
-      for (ClassMember member in members) {
-        member.accept(this);
-      }
-      scopes.removeLast();
-    }
-    b.executables = executables;
-    b.fields = variables;
-    b.superInvokedNames = mixinSuperInvokedNames.toList();
-    b.documentationComment = serializeDocumentation(documentationComment);
-    b.annotations = serializeAnnotations(annotations);
-    b.codeRange = serializeCodeRange(node);
-    mixins.add(b);
-
-    scopes.removeLast();
-    assert(scopes.length == oldScopesLength);
-
-    executables = oldExecutables;
-    mixinSuperInvokedNames = null;
-    variables = oldVariables;
-  }
-
-  /// Serialize a [FieldFormalParameter], [FunctionTypedFormalParameter], or
-  /// [SimpleFormalParameter] into an [UnlinkedParam].
-  UnlinkedParamBuilder serializeParameter(NormalFormalParameter node) {
-    UnlinkedParamBuilder b = new UnlinkedParamBuilder();
-    b.name = node.identifier?.name;
-    b.nameOffset = node.identifier?.offset;
-    b.annotations = serializeAnnotations(node.metadata);
-    b.codeRange = serializeCodeRange(node);
-    b.isExplicitlyCovariant = node.covariantKeyword != null;
-    b.isFinal = node.isFinal;
-    if (_parametersMayInheritCovariance) {
-      b.inheritsCovariantSlot = assignSlot();
-    }
-    if (node.isRequiredPositional) {
-      b.kind = UnlinkedParamKind.requiredPositional;
-    } else if (node.isRequiredNamed) {
-      b.kind = UnlinkedParamKind.requiredNamed;
-    } else if (node.isOptionalPositional) {
-      b.kind = UnlinkedParamKind.optionalPositional;
-    } else if (node.isOptionalNamed) {
-      b.kind = UnlinkedParamKind.optionalNamed;
-    } else {
-      // ignore: deprecated_member_use_from_same_package
-      throw new StateError('Unexpected parameter kind: ${node.kind}');
-    }
-    return b;
-  }
-
-  /// Serialize a reference to a top level name declared elsewhere, by adding an
-  /// entry to the references table if necessary.  If [prefixIndex] is not null,
-  /// the reference is associated with the prefix having the given index in the
-  /// references table.
-  int serializeReference(int prefixIndex, String name) => nameToReference
-          .putIfAbsent(prefixIndex, () => <String, int>{})
-          .putIfAbsent(name, () {
-        int index = unlinkedReferences.length;
-        unlinkedReferences.add(new UnlinkedReferenceBuilder(
-            prefixReference: prefixIndex, name: name));
-        return index;
-      });
-
-  /// Serialize a reference to a name declared either at top level or in a
-  /// nested scope.
-  ///
-  /// References to type parameters are returned as negative numbers.
-  int serializeSimpleReference(String name) {
-    int indexOffset = 0;
-    for (int i = scopes.length - 1; i >= 0; i--) {
-      _Scope scope = scopes[i];
-      _ScopedEntity entity = scope[name];
-      if (entity != null) {
-        if (entity is _ScopedClassMember) {
-          return serializeReference(
-              serializeReference(null, entity.className), name);
-        } else if (entity is _ScopedTypeParameter) {
-          int paramReference = indexOffset + entity.index;
-          return -paramReference;
-        }
-      }
-      if (scope is _TypeParameterScope) {
-        indexOffset += scope.length;
-      }
-    }
-    return serializeReference(null, name);
-  }
-
-  /// Serialize a type name (which might be defined in a nested scope, at top
-  /// level within this library, or at top level within an imported library) to
-  /// a [EntityRef].  Note that this method does the right thing if the
-  /// name doesn't refer to an entity other than a type (e.g. a class member).
-  EntityRefBuilder serializeType(TypeAnnotation node) {
-    var nullabilitySuffix = computeNullabilitySuffix(node?.question);
-    if (node is TypeName) {
-      return serializeTypeName(
-          node?.name, node?.typeArguments, nullabilitySuffix);
-    } else if (node is GenericFunctionType) {
-      return serializeGenericFunctionType(node);
-    } else if (node != null) {
-      throw new ArgumentError('Cannot serialize a ${node.runtimeType}');
-    }
-    return null;
-  }
-
-  /// Serialize a type name (which might be defined in a nested scope, at top
-  /// level within this library, or at top level within an imported library) to
-  /// a [EntityRef].  Note that this method does the right thing if the
-  /// name doesn't refer to an entity other than a type (e.g. a class member).
-  EntityRefBuilder serializeTypeName(
-      Identifier identifier,
-      TypeArgumentList typeArguments,
-      EntityRefNullabilitySuffix nullabilitySuffix) {
-    if (identifier == null) {
-      return null;
-    } else {
-      EntityRefBuilder b =
-          new EntityRefBuilder(nullabilitySuffix: nullabilitySuffix);
-      if (identifier is SimpleIdentifier) {
-        String name = identifier.name;
-        int indexOffset = 0;
-        for (int i = scopes.length - 1; i >= 0; i--) {
-          _Scope scope = scopes[i];
-          _ScopedEntity entity = scope[name];
-          if (entity != null) {
-            if (entity is _ScopedTypeParameter) {
-              b.paramReference = indexOffset + entity.index;
-              return b;
-            } else {
-              // None of the other things that can be declared in local scopes
-              // are types, so this is an error and should be treated as a
-              // reference to `dynamic`.
-              b.reference = serializeReference(null, 'dynamic');
-              return b;
-            }
-          }
-          if (scope is _TypeParameterScope) {
-            indexOffset += scope.length;
-          }
-        }
-        b.reference = serializeReference(null, name);
-      } else if (identifier is PrefixedIdentifier) {
-        int prefixIndex = serializeSimpleReference(identifier.prefix.name);
-        if (prefixIndex < 0) {
-          // Type parameters are not expected here, so this is an error and the
-          // type should be treated as a reference to `dynamic`.
-          b.reference = serializeReference(null, 'dynamic');
-          return b;
-        } else {
-          b.reference =
-              serializeReference(prefixIndex, identifier.identifier.name);
-        }
-      } else {
-        throw new StateError(
-            'Unexpected identifier type: ${identifier.runtimeType}');
-      }
-      if (typeArguments != null) {
-        b.typeArguments = typeArguments.arguments.map(serializeType).toList();
-      }
-      return b;
-    }
-  }
-
-  /// Serialize the given [typeParameters] into a list of [UnlinkedTypeParam]s,
-  /// and also store them in [typeParameterScope].
-  List<UnlinkedTypeParamBuilder> serializeTypeParameters(
-      TypeParameterList typeParameters,
-      _TypeParameterScope typeParameterScope) {
-    if (typeParameters != null) {
-      for (int i = 0; i < typeParameters.typeParameters.length; i++) {
-        TypeParameter typeParameter = typeParameters.typeParameters[i];
-        typeParameterScope[typeParameter.name.name] =
-            new _ScopedTypeParameter(typeParameters.typeParameters.length - i);
-      }
-      return typeParameters.typeParameters.map(visitTypeParameter).toList();
-    }
-    return const <UnlinkedTypeParamBuilder>[];
-  }
-
-  /// Serialize the given [variables] into [UnlinkedVariable]s, and store them
-  /// in [this.variables].
-  void serializeVariables(
-      VariableDeclarationList variables,
-      bool isDeclaredStatic,
-      Comment documentationComment,
-      NodeList<Annotation> annotations,
-      bool isField) {
-    bool isCovariant = isField
-        ? (variables.parent as FieldDeclaration).covariantKeyword != null
-        : false;
-    for (int i = 0; i < variables.variables.length; i++) {
-      VariableDeclaration variable = variables.variables[i];
-      UnlinkedVariableBuilder b = new UnlinkedVariableBuilder();
-      b.isConst = variables.isConst;
-      b.isCovariant = isCovariant;
-      b.isFinal = variables.isFinal;
-      b.isLate = variable.isLate;
-      b.isStatic = isDeclaredStatic;
-      b.name = variable.name.name;
-      b.nameOffset = variable.name.offset;
-      b.type = serializeType(variables.type);
-      b.documentationComment = serializeDocumentation(documentationComment);
-      b.annotations = serializeAnnotations(annotations);
-
-      {
-        int offset = (i == 0 ? variables.parent : variable).offset;
-        int length = variable.end - offset;
-        b.codeRange = new CodeRangeBuilder(offset: offset, length: length);
-      }
-
-      bool serializeBodyExpr = variable.isConst ||
-          _serializeInferrableFields && variables.type == null ||
-          isField &&
-              !isDeclaredStatic &&
-              variables.isFinal &&
-              enclosingClassHasConstConstructor;
-      b.initializer = serializeInitializerFunction(
-          variable.initializer, serializeBodyExpr, b.isConst);
-      if (isField && !isDeclaredStatic && !variables.isFinal) {
-        b.inheritsCovariantSlot = assignSlot();
-      }
-      if (variable.initializer != null &&
-          (variables.isFinal || variables.isConst)) {
-        b.propagatedTypeSlot = assignSlot();
-      }
-      bool isSemanticallyStatic = !isField || isDeclaredStatic;
-      if (variables.type == null &&
-          (variable.initializer != null || !isSemanticallyStatic)) {
-        b.inferredTypeSlot = assignSlot();
-      }
-      this.variables.add(b);
-    }
-  }
-
-  @override
-  void visitBlock(Block node) {
-    Block oldBlock = enclosingBlock;
-    enclosingBlock = node;
-    super.visitBlock(node);
-    enclosingBlock = oldBlock;
-  }
-
-  @override
-  void visitClassDeclaration(ClassDeclaration node) {
-    TypeName superclass =
-        node.extendsClause == null ? null : node.extendsClause.superclass;
-    serializeClass(
-        node,
-        node.abstractKeyword,
-        node.name.name,
-        node.name.offset,
-        node.typeParameters,
-        superclass,
-        node.withClause,
-        node.implementsClause,
-        node.members,
-        false,
-        node.documentationComment,
-        node.metadata);
-  }
-
-  @override
-  void visitClassTypeAlias(ClassTypeAlias node) {
-    serializeClass(
-        node,
-        node.abstractKeyword,
-        node.name.name,
-        node.name.offset,
-        node.typeParameters,
-        node.superclass,
-        node.withClause,
-        node.implementsClause,
-        null,
-        true,
-        node.documentationComment,
-        node.metadata);
-  }
-
-  @override
-  void visitConstructorDeclaration(ConstructorDeclaration node) {
-    UnlinkedExecutableBuilder b = new UnlinkedExecutableBuilder();
-    if (node.name != null) {
-      b.name = node.name.name;
-      b.nameOffset = node.name.offset;
-      b.periodOffset = node.period.offset;
-      b.nameEnd = node.name.end;
-    } else {
-      b.nameOffset = node.returnType.offset;
-    }
-    b.parameters = node.parameters.parameters
-        .map((FormalParameter p) => p.accept(this) as UnlinkedParamBuilder)
-        .toList();
-    b.kind = UnlinkedExecutableKind.constructor;
-    if (node.factoryKeyword != null) {
-      b.isFactory = true;
-      if (node.redirectedConstructor != null) {
-        b.isRedirectedConstructor = true;
-        TypeName typeName = node.redirectedConstructor.type;
-        // Closures can't appear inside factory constructor redirections, so we
-        // don't need a localClosureIndexMap.
-        Map<int, int> localClosureIndexMap = null;
-        b.redirectedConstructor =
-            new _ConstExprSerializer(true, this, localClosureIndexMap, null)
-                .serializeConstructorRef(typeName.name, typeName.typeArguments,
-                    node.redirectedConstructor.name);
-      }
-    } else {
-      for (ConstructorInitializer initializer in node.initializers) {
-        if (initializer is RedirectingConstructorInvocation) {
-          b.isRedirectedConstructor = true;
-          b.redirectedConstructorName = initializer.constructorName?.name;
-        }
-      }
-    }
-    if (node.constKeyword != null) {
-      b.isConst = true;
-      b.constCycleSlot = assignSlot();
-    }
-    b.isExternal =
-        node.externalKeyword != null || node.body is NativeFunctionBody;
-    b.documentationComment = serializeDocumentation(node.documentationComment);
-    b.annotations = serializeAnnotations(node.metadata);
-    b.codeRange = serializeCodeRange(node);
-    Map<int, int> localClosureIndexMap = serializeFunctionBody(b,
-        node.initializers, node.body, node.constKeyword != null, false, false);
-    if (node.constKeyword != null) {
-      List<String> constructorParameterNames =
-          node.parameters.parameters.map((p) => p.identifier.name).toList();
-      b.constantInitializers = node.initializers
-          .map((ConstructorInitializer initializer) =>
-              serializeConstructorInitializer(initializer, (Expression expr) {
-                return serializeConstExpr(true, localClosureIndexMap, expr,
-                    constructorParameterNames);
-              }))
-          .toList();
-    }
-    executables.add(b);
-  }
-
-  @override
-  UnlinkedParamBuilder visitDefaultFormalParameter(
-      DefaultFormalParameter node) {
-    UnlinkedParamBuilder b =
-        node.parameter.accept(this) as UnlinkedParamBuilder;
-    b.initializer = serializeInitializerFunction(node.defaultValue, true, true);
-    if (node.defaultValue != null) {
-      b.defaultValueCode = node.defaultValue.toSource();
-    }
-    b.codeRange = serializeCodeRange(node);
-    return b;
-  }
-
-  @override
-  void visitEnumDeclaration(EnumDeclaration node) {
-    UnlinkedEnumBuilder b = new UnlinkedEnumBuilder();
-    b.name = node.name.name;
-    b.nameOffset = node.name.offset;
-    b.values = node.constants.map(serializeEnumConstantDeclaration).toList();
-    b.documentationComment = serializeDocumentation(node.documentationComment);
-    b.annotations = serializeAnnotations(node.metadata);
-    b.codeRange = serializeCodeRange(node);
-    enums.add(b);
-  }
-
-  @override
-  void visitExportDirective(ExportDirective node) {
-    UnlinkedExportNonPublicBuilder b = new UnlinkedExportNonPublicBuilder(
-        uriOffset: node.uri.offset, uriEnd: node.uri.end, offset: node.offset);
-    b.annotations = serializeAnnotations(node.metadata);
-    exports.add(b);
-  }
-
-  @override
-  visitExtensionDeclaration(ExtensionDeclaration node) {
-    int oldScopesLength = scopes.length;
-    enclosingClassHasConstConstructor = false;
-    List<UnlinkedExecutableBuilder> oldExecutables = executables;
-    executables = <UnlinkedExecutableBuilder>[];
-    List<UnlinkedVariableBuilder> oldVariables = variables;
-    variables = <UnlinkedVariableBuilder>[];
-    _TypeParameterScope typeParameterScope = new _TypeParameterScope();
-    scopes.add(typeParameterScope);
-
-    UnlinkedExtensionBuilder b = UnlinkedExtensionBuilder();
-    b.name = node.name?.name;
-    b.nameOffset = node.name?.offset ?? 0;
-    b.typeParameters =
-        serializeTypeParameters(node.typeParameters, typeParameterScope);
-    b.extendedType = serializeType(node.extendedType);
-    if (node.members != null) {
-      scopes.add(buildClassMemberScope(node.name?.name, node.members));
-      for (ClassMember member in node.members) {
-        member.accept(this);
-      }
-      scopes.removeLast();
-    }
-    b.executables = executables;
-    b.fields = variables;
-    b.documentationComment = serializeDocumentation(node.documentationComment);
-    b.annotations = serializeAnnotations(node.metadata);
-    b.codeRange = serializeCodeRange(node);
-    extensions.add(b);
-
-    scopes.removeLast();
-    assert(scopes.length == oldScopesLength);
-    executables = oldExecutables;
-    variables = oldVariables;
-  }
-
-  @override
-  void visitFieldDeclaration(FieldDeclaration node) {
-    serializeVariables(node.fields, node.staticKeyword != null,
-        node.documentationComment, node.metadata, true);
-  }
-
-  @override
-  UnlinkedParamBuilder visitFieldFormalParameter(FieldFormalParameter node) {
-    UnlinkedParamBuilder b = serializeParameter(node);
-    b.isInitializingFormal = true;
-    if (node.type != null || node.parameters != null) {
-      b.isFunctionTyped = node.parameters != null;
-      if (node.parameters != null) {
-        serializeFunctionTypedParameterDetails(b, node.type, node.parameters);
-      } else {
-        b.type = serializeType(node.type);
-      }
-    }
-    return b;
-  }
-
-  @override
-  void visitFunctionDeclaration(FunctionDeclaration node) {
-    executables.add(serializeExecutable(
-        node,
-        node.name.name,
-        node.name.offset,
-        node.isGetter,
-        node.isSetter,
-        node.returnType,
-        node.functionExpression.parameters,
-        node.functionExpression.body,
-        true,
-        false,
-        node.documentationComment,
-        node.metadata,
-        node.functionExpression.typeParameters,
-        node.externalKeyword != null ||
-            node.functionExpression.body is NativeFunctionBody,
-        false,
-        node.parent is FunctionDeclarationStatement));
-  }
-
-  @override
-  void visitFunctionExpression(FunctionExpression node) {
-    if (node.parent is! FunctionDeclaration) {
-      if (_localClosureIndexMap != null) {
-        _localClosureIndexMap[node.offset] = executables.length;
-      }
-      executables.add(serializeExecutable(
-          node,
-          null,
-          node.offset,
-          false,
-          false,
-          null,
-          node.parameters,
-          node.body,
-          false,
-          false,
-          null,
-          null,
-          node.typeParameters,
-          false,
-          _serializeClosureBodyExprs,
-          true));
-    }
-  }
-
-  @override
-  void visitFunctionTypeAlias(FunctionTypeAlias node) {
-    int oldScopesLength = scopes.length;
-    _TypeParameterScope typeParameterScope = new _TypeParameterScope();
-    scopes.add(typeParameterScope);
-    UnlinkedTypedefBuilder b = new UnlinkedTypedefBuilder();
-    b.name = node.name.name;
-    b.nameOffset = node.name.offset;
-    b.typeParameters =
-        serializeTypeParameters(node.typeParameters, typeParameterScope);
-    b.notSimplyBoundedSlot = assignSlot();
-    EntityRefBuilder serializedReturnType = serializeType(node.returnType);
-    if (serializedReturnType != null) {
-      b.returnType = serializedReturnType;
-    }
-    b.parameters = node.parameters.parameters
-        .map((FormalParameter p) => p.accept(this) as UnlinkedParamBuilder)
-        .toList();
-    b.documentationComment = serializeDocumentation(node.documentationComment);
-    b.annotations = serializeAnnotations(node.metadata);
-    b.codeRange = serializeCodeRange(node);
-    typedefs.add(b);
-
-    scopes.removeLast();
-    assert(scopes.length == oldScopesLength);
-  }
-
-  @override
-  UnlinkedParamBuilder visitFunctionTypedFormalParameter(
-      FunctionTypedFormalParameter node) {
-    UnlinkedParamBuilder b = serializeParameter(node);
-    b.isFunctionTyped = true;
-    serializeFunctionTypedParameterDetails(b, node.returnType, node.parameters);
-    return b;
-  }
-
-  @override
-  void visitGenericTypeAlias(GenericTypeAlias node) {
-    int oldScopesLength = scopes.length;
-    _TypeParameterScope typeParameterScope = new _TypeParameterScope();
-    scopes.add(typeParameterScope);
-    UnlinkedTypedefBuilder b = new UnlinkedTypedefBuilder();
-    b.style = TypedefStyle.genericFunctionType;
-    b.name = node.name.name;
-    b.nameOffset = node.name.offset;
-    b.typeParameters =
-        serializeTypeParameters(node.typeParameters, typeParameterScope);
-    b.notSimplyBoundedSlot = assignSlot();
-    GenericFunctionType functionType = node.functionType;
-    EntityRefBuilder serializedType = functionType == null
-        ? null
-        : serializeGenericFunctionType(functionType);
-    if (serializedType != null) {
-      b.returnType = serializedType;
-    }
-    b.documentationComment = serializeDocumentation(node.documentationComment);
-    b.annotations = serializeAnnotations(node.metadata);
-    b.codeRange = serializeCodeRange(node);
-    typedefs.add(b);
-    scopes.removeLast();
-    assert(scopes.length == oldScopesLength);
-  }
-
-  @override
-  void visitImportDirective(ImportDirective node) {
-    UnlinkedImportBuilder b = new UnlinkedImportBuilder();
-    b.annotations = serializeAnnotations(node.metadata);
-    if (node.uri.stringValue == 'dart:core') {
-      hasCoreBeenImported = true;
-    }
-    b.offset = node.offset;
-    b.combinators = node.combinators.map(serializeCombinator).toList();
-    b.configurations = node.configurations.map(serializeConfiguration).toList();
-    if (node.prefix != null) {
-      b.prefixReference = serializeReference(null, node.prefix.name);
-      b.prefixOffset = node.prefix.offset;
-    }
-    b.isDeferred = node.deferredKeyword != null;
-    b.uri = node.uri.stringValue;
-    b.uriOffset = node.uri.offset;
-    b.uriEnd = node.uri.end;
-    unlinkedImports.add(b);
-  }
-
-  @override
-  void visitLibraryDirective(LibraryDirective node) {
-    libraryName =
-        node.name.components.map((SimpleIdentifier id) => id.name).join('.');
-    libraryNameOffset = node.name.offset;
-    libraryNameLength = node.name.length;
-    isCoreLibrary = libraryName == 'dart.core';
-    isCoreLibraryDefiningUnit = isCoreLibrary;
-    libraryDocumentationComment =
-        serializeDocumentation(node.documentationComment);
-    libraryAnnotations = serializeAnnotations(node.metadata);
-  }
-
-  @override
-  void visitMethodDeclaration(MethodDeclaration node) {
-    executables.add(serializeExecutable(
-        node,
-        node.name.name,
-        node.name.offset,
-        node.isGetter,
-        node.isSetter,
-        node.returnType,
-        node.parameters,
-        node.body,
-        false,
-        node.isStatic,
-        node.documentationComment,
-        node.metadata,
-        node.typeParameters,
-        node.externalKeyword != null || node.body is NativeFunctionBody,
-        false,
-        false));
-  }
-
-  @override
-  visitMixinDeclaration(MixinDeclaration node) {
-    serializeMixin(
-        node,
-        node.name.name,
-        node.name.offset,
-        node.typeParameters,
-        node.onClause,
-        node.implementsClause,
-        node.members,
-        node.documentationComment,
-        node.metadata);
-  }
-
-  @override
-  void visitPartDirective(PartDirective node) {
-    parts.add(new UnlinkedPartBuilder(
-        uriOffset: node.uri.offset,
-        uriEnd: node.uri.end,
-        annotations: serializeAnnotations(node.metadata)));
-  }
-
-  @override
-  void visitPartOfDirective(PartOfDirective node) {
-    isCoreLibrary = node.libraryName?.name == 'dart.core' ||
-        node.uri?.stringValue == 'core.dart';
-    isPartOf = true;
-  }
-
-  @override
-  UnlinkedParamBuilder visitSimpleFormalParameter(SimpleFormalParameter node) {
-    UnlinkedParamBuilder b = serializeParameter(node);
-    b.type = serializeType(node.type);
-    return b;
-  }
-
-  @override
-  void visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
-    serializeVariables(
-        node.variables, false, node.documentationComment, node.metadata, false);
-  }
-
-  @override
-  UnlinkedTypeParamBuilder visitTypeParameter(TypeParameter node) {
-    UnlinkedTypeParamBuilder b = new UnlinkedTypeParamBuilder();
-    b.name = node.name.name;
-    b.nameOffset = node.name.offset;
-    if (node.bound != null) {
-      b.bound = serializeType(node.bound);
-    }
-    b.annotations = serializeAnnotations(node.metadata);
-    b.codeRange = serializeCodeRange(node);
-    return b;
-  }
-
-  @override
-  void visitVariableDeclarationStatement(VariableDeclarationStatement node) {
-    // TODO(scheglov) Remove when we stop serializing local functions.
-  }
-
-  /// Determines whether a class declaration with the given [typeParameters]
-  /// needs to be assigned a slot to indicate whether it is simply bounded.
-  bool _shouldAssignNotSimplyBoundedSlot(TypeParameterList typeParameters) {
-    if (typeParameters == null) return false;
-    for (var typeParameter in typeParameters.typeParameters) {
-      if (typeParameter.bound != null) return true;
-    }
-    return false;
-  }
-
-  /// Compute the API signature of the unit and record it.
-  static void _computeApiSignature(UnlinkedUnitBuilder b) {
-    ApiSignature apiSignature = new ApiSignature();
-    b.collectApiSignature(apiSignature);
-    b.apiSignature = apiSignature.toByteList();
-  }
-}
-
-/// A [_TypeParameterScope] is a [_Scope] which defines [_ScopedTypeParameter]s.
-class _TypeParameterScope extends _Scope {
-  /// Get the number of [_ScopedTypeParameter]s defined in this
-  /// [_TypeParameterScope].
-  int get length => _definedNames.length;
-}
diff --git a/pkg/analyzer/lib/src/summary/summarize_const_expr.dart b/pkg/analyzer/lib/src/summary/summarize_const_expr.dart
deleted file mode 100644
index 6a931fa..0000000
--- a/pkg/analyzer/lib/src/summary/summarize_const_expr.dart
+++ /dev/null
@@ -1,808 +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 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/ast/token.dart';
-import 'package:analyzer/src/summary/format.dart';
-import 'package:analyzer/src/summary/idl.dart';
-
-/// Serialize the given constructor initializer [node].
-UnlinkedConstructorInitializerBuilder serializeConstructorInitializer(
-    ConstructorInitializer node,
-    UnlinkedExprBuilder serializeConstExpr(Expression expr)) {
-  if (node is ConstructorFieldInitializer) {
-    return new UnlinkedConstructorInitializerBuilder(
-        kind: UnlinkedConstructorInitializerKind.field,
-        name: node.fieldName.name,
-        expression: serializeConstExpr(node.expression));
-  }
-
-  List<UnlinkedExprBuilder> arguments = <UnlinkedExprBuilder>[];
-  List<String> argumentNames = <String>[];
-  void serializeArguments(List<Expression> args) {
-    for (Expression arg in args) {
-      if (arg is NamedExpression) {
-        NamedExpression namedExpression = arg;
-        argumentNames.add(namedExpression.name.label.name);
-        arg = namedExpression.expression;
-      }
-      arguments.add(serializeConstExpr(arg));
-    }
-  }
-
-  if (node is AssertInitializer) {
-    serializeArguments(node.message != null
-        ? [node.condition, node.message]
-        : [node.condition]);
-    return new UnlinkedConstructorInitializerBuilder(
-        kind: UnlinkedConstructorInitializerKind.assertInvocation,
-        arguments: arguments);
-  }
-  if (node is RedirectingConstructorInvocation) {
-    serializeArguments(node.argumentList.arguments);
-    return new UnlinkedConstructorInitializerBuilder(
-        kind: UnlinkedConstructorInitializerKind.thisInvocation,
-        name: node?.constructorName?.name,
-        arguments: arguments,
-        argumentNames: argumentNames);
-  }
-  if (node is SuperConstructorInvocation) {
-    serializeArguments(node.argumentList.arguments);
-    return new UnlinkedConstructorInitializerBuilder(
-        kind: UnlinkedConstructorInitializerKind.superInvocation,
-        name: node?.constructorName?.name,
-        arguments: arguments,
-        argumentNames: argumentNames);
-  }
-  throw new StateError('Unexpected initializer type ${node.runtimeType}');
-}
-
-/// Converts all the tokens between [startToken] and [endToken] (inclusive) into
-/// a string which, when scanned, will yield the same tokens back.
-String tokensToString(Token startToken, Token endToken) {
-  var buffer = StringBuffer();
-  var token = startToken;
-  var spaceNeeded = false;
-  while (true) {
-    if (token.type == TokenType.STRING_INTERPOLATION_EXPRESSION) {
-      buffer.write(token.lexeme);
-      buffer.write(tokensToString(token.next, token.endGroup));
-      spaceNeeded = false;
-      token = token.endGroup;
-    } else if (token.type == TokenType.STRING_INTERPOLATION_IDENTIFIER) {
-      buffer.write(token.lexeme);
-      buffer.write(token.next.lexeme);
-      spaceNeeded = false;
-      token = token.next;
-    } else {
-      if (spaceNeeded) buffer.write(' ');
-      buffer.write(token.lexeme);
-      spaceNeeded = true;
-    }
-    if (identical(token, endToken)) break;
-    token = token.next;
-  }
-  return buffer.toString();
-}
-
-/// Instances of this class keep track of intermediate state during
-/// serialization of a single constant [Expression].
-abstract class AbstractConstExprSerializer {
-  /// Whether an expression that should be a constant is being serialized.
-  ///
-  /// For constants we need to store more than we need just for type inference,
-  /// because we need to be able to restore these AST to evaluate actual values
-  /// of constants. So, we need to store constructor arguments, elements for
-  /// list and map literals even if these literals are typed.
-  final bool forConst;
-
-  /// See [UnlinkedExprBuilder.isValidConst].
-  bool isValidConst = true;
-
-  /// See [UnlinkedExprBuilder.name].
-  String name = null;
-
-  /// See [UnlinkedExprBuilder.operations].
-  final List<UnlinkedExprOperation> operations = <UnlinkedExprOperation>[];
-
-  /// See [UnlinkedExprBuilder.assignmentOperators].
-  final List<UnlinkedExprAssignOperator> assignmentOperators =
-      <UnlinkedExprAssignOperator>[];
-
-  /// See [UnlinkedExprBuilder.ints].
-  final List<int> ints = <int>[];
-
-  /// See [UnlinkedExprBuilder.doubles].
-  final List<double> doubles = <double>[];
-
-  /// See [UnlinkedExprBuilder.strings].
-  final List<String> strings = <String>[];
-
-  /// See [UnlinkedExprBuilder.references].
-  final List<EntityRefBuilder> references = <EntityRefBuilder>[];
-
-  AbstractConstExprSerializer(this.forConst);
-
-  /// Return `true` if the given [name] is a parameter reference.
-  bool isParameterName(String name);
-
-  /// Removes the [count] variables that were most recently added to the scope
-  /// by [pushVariableName].
-  void popVariableNames(int count);
-
-  /// Pushes a variable with the given [name] onto the current scope.
-  void pushVariableName(String name);
-
-  /// Serialize the given [expr] expression into this serializer state.
-  void serialize(Expression expr) {
-    try {
-      if (expr is NamedExpression) {
-        NamedExpression namedExpression = expr;
-        name = namedExpression.name.label.name;
-        expr = namedExpression.expression;
-      }
-      _serialize(expr);
-    } on StateError {
-      isValidConst = false;
-      operations.clear();
-      assignmentOperators.clear();
-      ints.clear();
-      doubles.clear();
-      strings.clear();
-      references.clear();
-    }
-  }
-
-  /// Serialize the given [annotation] into this serializer state.
-  void serializeAnnotation(Annotation annotation);
-
-  /// Return [EntityRefBuilder] that corresponds to the constructor having name
-  /// [name] in the class identified by [typeName].
-  EntityRefBuilder serializeConstructorRef(Identifier typeName,
-      TypeArgumentList typeArguments, SimpleIdentifier name);
-
-  /// Return a pair of ints showing how the given [functionExpression] is nested
-  /// within the constant currently being serialized.  The first int indicates
-  /// how many levels of function nesting must be popped in order to reach the
-  /// parent of the [functionExpression].  The second int is the index of the
-  /// [functionExpression] within its parent element.
-  ///
-  /// If the constant being summarized is in a context where local function
-  /// references are not allowed, return `null`.
-  List<int> serializeFunctionExpression(FunctionExpression functionExpression);
-
-  /// Return [EntityRefBuilder] that corresponds to the [type], which is defined
-  /// using generic function type syntax. These may appear as the type arguments
-  /// of a const list, etc.
-  EntityRefBuilder serializeGenericFunctionType(GenericFunctionType type);
-
-  /// Return [EntityRefBuilder] that corresponds to the given [identifier].
-  EntityRefBuilder serializeIdentifier(Identifier identifier);
-
-  /// Return [EntityRefBuilder] that corresponds to the given [expr], which
-  /// must be a sequence of identifiers.
-  EntityRefBuilder serializeIdentifierSequence(Expression expr);
-
-  void serializeInstanceCreation(EntityRefBuilder constructor,
-      ArgumentList argumentList, bool typeArgumentsProvided) {
-    _serializeArguments(argumentList, typeArgumentsProvided);
-    references.add(constructor);
-    operations.add(UnlinkedExprOperation.invokeConstructor);
-  }
-
-  /// Return [EntityRefBuilder] that corresponds to the given [type].
-  EntityRefBuilder serializeType(TypeAnnotation type) {
-    if (type is TypeName) {
-      return serializeTypeName(type?.name, type?.typeArguments,
-          computeNullabilitySuffix(type.question));
-    }
-    if (type is GenericFunctionType) {
-      return serializeGenericFunctionType(type);
-    }
-    throw new ArgumentError(
-        'Cannot serialize an instance of ${type.runtimeType}');
-  }
-
-  /// Return [EntityRefBuilder] that corresponds to the type with the given
-  /// [name] and [arguments].
-  EntityRefBuilder serializeTypeName(Identifier name,
-      TypeArgumentList arguments, EntityRefNullabilitySuffix nullabilitySuffix);
-
-  /// Return the [UnlinkedExprBuilder] that corresponds to the state of this
-  /// serializer.
-  UnlinkedExprBuilder toBuilder(Token startToken, Token endToken) {
-    return new UnlinkedExprBuilder(
-        isValidConst: isValidConst,
-        operations: operations,
-        assignmentOperators: assignmentOperators,
-        ints: ints,
-        doubles: doubles,
-        strings: strings,
-        references: references,
-        sourceRepresentation: tokensToString(startToken, endToken));
-  }
-
-  /// Return `true` if the given [expr] is a sequence of identifiers.
-  bool _isIdentifierSequence(Expression expr) {
-    while (expr != null) {
-      if (expr is SimpleIdentifier) {
-        AstNode parent = expr.parent;
-        if (parent is MethodInvocation && parent.methodName == expr) {
-          if (parent.isCascaded) {
-            return false;
-          }
-          return parent.target == null || _isIdentifierSequence(parent.target);
-        }
-        if (isParameterName(expr.name)) {
-          return false;
-        }
-        return true;
-      } else if (expr is PrefixedIdentifier) {
-        expr = (expr as PrefixedIdentifier).prefix;
-      } else if (expr is PropertyAccess) {
-        expr = (expr as PropertyAccess).target;
-      } else {
-        return false;
-      }
-    }
-    return false;
-  }
-
-  /// Push the operation for the given assignable [expr].
-  void _pushAssignable(Expression expr) {
-    if (_isIdentifierSequence(expr)) {
-      EntityRefBuilder ref = serializeIdentifierSequence(expr);
-      references.add(ref);
-      operations.add(UnlinkedExprOperation.assignToRef);
-    } else if (expr is SimpleIdentifier && isParameterName(expr.name)) {
-      strings.add(expr.name);
-      operations.add(UnlinkedExprOperation.assignToParameter);
-    } else if (expr is PropertyAccess) {
-      if (!expr.isCascaded) {
-        _serialize(expr.target);
-      }
-      strings.add(expr.propertyName.name);
-      operations.add(UnlinkedExprOperation.assignToProperty);
-    } else if (expr is IndexExpression) {
-      if (!expr.isCascaded) {
-        _serialize(expr.target);
-      }
-      _serialize(expr.index);
-      operations.add(UnlinkedExprOperation.assignToIndex);
-    } else if (expr is PrefixedIdentifier) {
-      strings.add(expr.prefix.name);
-      operations.add(UnlinkedExprOperation.pushParameter);
-      strings.add(expr.identifier.name);
-      operations.add(UnlinkedExprOperation.assignToProperty);
-    } else {
-      throw new StateError('Unsupported assignable: $expr');
-    }
-  }
-
-  void _pushInt(int value) {
-    value ??= 0;
-    assert(value >= 0);
-    if (value >= 0x100000000) {
-      int numOfComponents = 0;
-      ints.add(numOfComponents);
-      void pushComponents(int value) {
-        if (value >= 0x100000000) {
-          pushComponents(value ~/ 0x100000000);
-        }
-        numOfComponents++;
-        ints.add(value & 0xFFFFFFFF);
-      }
-
-      pushComponents(value);
-      ints[ints.length - 1 - numOfComponents] = numOfComponents;
-      operations.add(UnlinkedExprOperation.pushLongInt);
-    } else {
-      operations.add(UnlinkedExprOperation.pushInt);
-      ints.add(value);
-    }
-  }
-
-  /// Serialize the given [expr] expression into this serializer state.
-  void _serialize(Expression expr, {bool emptyExpressionPermitted: false}) {
-    if (emptyExpressionPermitted && expr == null) {
-      operations.add(UnlinkedExprOperation.pushEmptyExpression);
-    } else if (expr is IntegerLiteral) {
-      int value = expr.value ?? 0;
-      if (value >= 0) {
-        _pushInt(value);
-      } else {
-        _pushInt(-value);
-        operations.add(UnlinkedExprOperation.negate);
-      }
-    } else if (expr is DoubleLiteral) {
-      operations.add(UnlinkedExprOperation.pushDouble);
-      doubles.add(expr.value);
-    } else if (expr is BooleanLiteral) {
-      if (expr.value) {
-        operations.add(UnlinkedExprOperation.pushTrue);
-      } else {
-        operations.add(UnlinkedExprOperation.pushFalse);
-      }
-    } else if (expr is StringLiteral) {
-      _serializeString(expr);
-    } else if (expr is SymbolLiteral) {
-      strings.add(expr.components.map((token) => token.lexeme).join('.'));
-      operations.add(UnlinkedExprOperation.makeSymbol);
-    } else if (expr is NullLiteral) {
-      operations.add(UnlinkedExprOperation.pushNull);
-    } else if (expr is Identifier) {
-      if (expr is SimpleIdentifier && isParameterName(expr.name)) {
-        strings.add(expr.name);
-        operations.add(UnlinkedExprOperation.pushParameter);
-      } else if (expr is PrefixedIdentifier &&
-          isParameterName(expr.prefix.name)) {
-        strings.add(expr.prefix.name);
-        operations.add(UnlinkedExprOperation.pushParameter);
-        strings.add(expr.identifier.name);
-        operations.add(UnlinkedExprOperation.extractProperty);
-      } else {
-        references.add(serializeIdentifier(expr));
-        operations.add(UnlinkedExprOperation.pushReference);
-      }
-    } else if (expr is InstanceCreationExpression) {
-      if (!expr.isConst) {
-        isValidConst = false;
-      }
-      TypeName typeName = expr.constructorName.type;
-      serializeInstanceCreation(
-          serializeConstructorRef(
-              typeName.name, typeName.typeArguments, expr.constructorName.name),
-          expr.argumentList,
-          typeName.typeArguments != null);
-    } else if (expr is ListLiteral) {
-      _serializeListLiteral(expr);
-    } else if (expr is SetOrMapLiteral) {
-      _serializeSetOrMapLiteral(expr);
-    } else if (expr is MethodInvocation) {
-      _serializeMethodInvocation(expr);
-    } else if (expr is BinaryExpression) {
-      _serializeBinaryExpression(expr);
-    } else if (expr is ConditionalExpression) {
-      _serialize(expr.condition);
-      _serialize(expr.thenExpression);
-      _serialize(expr.elseExpression);
-      operations.add(UnlinkedExprOperation.conditional);
-    } else if (expr is PrefixExpression) {
-      _serializePrefixExpression(expr);
-    } else if (expr is PostfixExpression) {
-      _serializePostfixExpression(expr);
-    } else if (expr is PropertyAccess) {
-      _serializePropertyAccess(expr);
-    } else if (expr is ParenthesizedExpression) {
-      _serialize(expr.expression);
-    } else if (expr is IndexExpression) {
-      isValidConst = false;
-      _serialize(expr.target);
-      _serialize(expr.index);
-      operations.add(UnlinkedExprOperation.extractIndex);
-    } else if (expr is AssignmentExpression) {
-      _serializeAssignment(expr);
-    } else if (expr is CascadeExpression) {
-      isValidConst = false;
-      _serialize(expr.target);
-    } else if (expr is FunctionExpression) {
-      isValidConst = false;
-      List<int> indices = serializeFunctionExpression(expr);
-      if (indices != null) {
-        ints.addAll(serializeFunctionExpression(expr));
-        operations.add(UnlinkedExprOperation.pushLocalFunctionReference);
-      } else {
-        // Invalid expression; just push null.
-        operations.add(UnlinkedExprOperation.pushNull);
-      }
-    } else if (expr is FunctionExpressionInvocation) {
-      isValidConst = false;
-      _serialize(expr.function);
-      _serializeArguments(expr.argumentList, expr.typeArguments != null);
-      strings.add('call');
-      _serializeTypeArguments(expr.typeArguments);
-      operations.add(UnlinkedExprOperation.invokeMethod);
-    } else if (expr is AsExpression) {
-      isValidConst = false;
-      _serialize(expr.expression);
-      references.add(serializeType(expr.type));
-      operations.add(UnlinkedExprOperation.typeCast);
-    } else if (expr is IsExpression) {
-      isValidConst = false;
-      _serialize(expr.expression);
-      references.add(serializeType(expr.type));
-      operations.add(UnlinkedExprOperation.typeCheck);
-      if (expr.notOperator != null) {
-        operations.add(UnlinkedExprOperation.not);
-      }
-    } else if (expr is SuperExpression) {
-      operations.add(UnlinkedExprOperation.pushSuper);
-    } else if (expr is ThisExpression) {
-      operations.add(UnlinkedExprOperation.pushThis);
-    } else if (expr is ThrowExpression) {
-      isValidConst = false;
-      _serialize(expr.expression);
-      operations.add(UnlinkedExprOperation.throwException);
-    } else if (expr is AwaitExpression) {
-      isValidConst = false;
-      _serialize(expr.expression);
-      operations.add(UnlinkedExprOperation.await);
-    } else {
-      throw new StateError('Unknown expression type: $expr');
-    }
-  }
-
-  void _serializeArguments(
-      ArgumentList argumentList, bool typeArgumentsProvided) {
-    if (forConst || !typeArgumentsProvided) {
-      List<Expression> arguments = argumentList.arguments;
-      // Serialize the arguments.
-      List<String> argumentNames = <String>[];
-      arguments.forEach((arg) {
-        if (arg is NamedExpression) {
-          argumentNames.add(arg.name.label.name);
-          _serialize(arg.expression);
-        } else {
-          _serialize(arg);
-        }
-      });
-      // Add numbers of named and positional arguments, and the op-code.
-      ints.add(argumentNames.length);
-      strings.addAll(argumentNames);
-      ints.add(arguments.length - argumentNames.length);
-    } else {
-      ints.add(0);
-      ints.add(0);
-    }
-  }
-
-  void _serializeAssignment(AssignmentExpression expr) {
-    isValidConst = false;
-    // Push the value.
-    _serialize(expr.rightHandSide);
-    // Push the assignment operator.
-    TokenType operator = expr.operator.type;
-    UnlinkedExprAssignOperator assignmentOperator;
-    if (operator == TokenType.EQ) {
-      assignmentOperator = UnlinkedExprAssignOperator.assign;
-    } else if (operator == TokenType.QUESTION_QUESTION_EQ) {
-      assignmentOperator = UnlinkedExprAssignOperator.ifNull;
-    } else if (operator == TokenType.STAR_EQ) {
-      assignmentOperator = UnlinkedExprAssignOperator.multiply;
-    } else if (operator == TokenType.SLASH_EQ) {
-      assignmentOperator = UnlinkedExprAssignOperator.divide;
-    } else if (operator == TokenType.TILDE_SLASH_EQ) {
-      assignmentOperator = UnlinkedExprAssignOperator.floorDivide;
-    } else if (operator == TokenType.PERCENT_EQ) {
-      assignmentOperator = UnlinkedExprAssignOperator.modulo;
-    } else if (operator == TokenType.PLUS_EQ) {
-      assignmentOperator = UnlinkedExprAssignOperator.plus;
-    } else if (operator == TokenType.MINUS_EQ) {
-      assignmentOperator = UnlinkedExprAssignOperator.minus;
-    } else if (operator == TokenType.LT_LT_EQ) {
-      assignmentOperator = UnlinkedExprAssignOperator.shiftLeft;
-    } else if (operator == TokenType.GT_GT_EQ) {
-      assignmentOperator = UnlinkedExprAssignOperator.shiftRight;
-    } else if (operator == TokenType.AMPERSAND_EQ) {
-      assignmentOperator = UnlinkedExprAssignOperator.bitAnd;
-    } else if (operator == TokenType.CARET_EQ) {
-      assignmentOperator = UnlinkedExprAssignOperator.bitXor;
-    } else if (operator == TokenType.BAR_EQ) {
-      assignmentOperator = UnlinkedExprAssignOperator.bitOr;
-    } else {
-      throw new StateError('Unknown assignment operator: $operator');
-    }
-    assignmentOperators.add(assignmentOperator);
-    // Push the assignment to the LHS.
-    _pushAssignable(expr.leftHandSide);
-  }
-
-  void _serializeBinaryExpression(BinaryExpression expr) {
-    _serialize(expr.leftOperand);
-    _serialize(expr.rightOperand);
-    TokenType operator = expr.operator.type;
-    if (operator == TokenType.EQ_EQ) {
-      operations.add(UnlinkedExprOperation.equal);
-    } else if (operator == TokenType.BANG_EQ) {
-      operations.add(UnlinkedExprOperation.notEqual);
-    } else if (operator == TokenType.AMPERSAND_AMPERSAND) {
-      operations.add(UnlinkedExprOperation.and);
-    } else if (operator == TokenType.BAR_BAR) {
-      operations.add(UnlinkedExprOperation.or);
-    } else if (operator == TokenType.CARET) {
-      operations.add(UnlinkedExprOperation.bitXor);
-    } else if (operator == TokenType.AMPERSAND) {
-      operations.add(UnlinkedExprOperation.bitAnd);
-    } else if (operator == TokenType.BAR) {
-      operations.add(UnlinkedExprOperation.bitOr);
-    } else if (operator == TokenType.GT_GT) {
-      operations.add(UnlinkedExprOperation.bitShiftRight);
-    } else if (operator == TokenType.GT_GT_GT) {
-      operations.add(UnlinkedExprOperation.bitShiftRightLogical);
-    } else if (operator == TokenType.LT_LT) {
-      operations.add(UnlinkedExprOperation.bitShiftLeft);
-    } else if (operator == TokenType.PLUS) {
-      operations.add(UnlinkedExprOperation.add);
-    } else if (operator == TokenType.MINUS) {
-      operations.add(UnlinkedExprOperation.subtract);
-    } else if (operator == TokenType.STAR) {
-      operations.add(UnlinkedExprOperation.multiply);
-    } else if (operator == TokenType.SLASH) {
-      operations.add(UnlinkedExprOperation.divide);
-    } else if (operator == TokenType.TILDE_SLASH) {
-      operations.add(UnlinkedExprOperation.floorDivide);
-    } else if (operator == TokenType.GT) {
-      operations.add(UnlinkedExprOperation.greater);
-    } else if (operator == TokenType.LT) {
-      operations.add(UnlinkedExprOperation.less);
-    } else if (operator == TokenType.GT_EQ) {
-      operations.add(UnlinkedExprOperation.greaterEqual);
-    } else if (operator == TokenType.LT_EQ) {
-      operations.add(UnlinkedExprOperation.lessEqual);
-    } else if (operator == TokenType.PERCENT) {
-      operations.add(UnlinkedExprOperation.modulo);
-    } else if (operator == TokenType.QUESTION_QUESTION) {
-      operations.add(UnlinkedExprOperation.ifNull);
-    } else {
-      throw new StateError('Unknown operator: $operator');
-    }
-  }
-
-  void _serializeCollectionElement(CollectionElement element) {
-    if (element is Expression) {
-      _serialize(element);
-    } else if (element is MapLiteralEntry) {
-      _serialize(element.key);
-      _serialize(element.value);
-      operations.add(UnlinkedExprOperation.makeMapLiteralEntry);
-    } else if (element is SpreadElement) {
-      _serialize(element.expression);
-      bool isNullAware = element.spreadOperator.type ==
-          TokenType.PERIOD_PERIOD_PERIOD_QUESTION;
-      operations.add(isNullAware
-          ? UnlinkedExprOperation.nullAwareSpreadElement
-          : UnlinkedExprOperation.spreadElement);
-    } else if (element is IfElement) {
-      _serialize(element.condition);
-      _serializeCollectionElement(element.thenElement);
-      var elseElement = element.elseElement;
-      if (elseElement == null) {
-        operations.add(UnlinkedExprOperation.ifElement);
-      } else {
-        _serializeCollectionElement(elseElement);
-        operations.add(UnlinkedExprOperation.ifElseElement);
-      }
-    } else if (element is ForElement) {
-      isValidConst = false;
-      var parts = element.forLoopParts;
-      int numVariablesToPop = 0;
-      if (parts is ForParts) {
-        if (parts is ForPartsWithExpression) {
-          _serialize(parts.initialization, emptyExpressionPermitted: true);
-        } else if (parts is ForPartsWithDeclarations) {
-          for (var variable in parts.variables.variables) {
-            operations.add(UnlinkedExprOperation.variableDeclarationStart);
-            var name = variable.name.name;
-            strings.add(name);
-            pushVariableName(name);
-            ++numVariablesToPop;
-            _serialize(variable.initializer, emptyExpressionPermitted: true);
-            operations.add(UnlinkedExprOperation.variableDeclaration);
-            ints.add(0);
-          }
-          var type = parts.variables.type;
-          if (type == null) {
-            operations
-                .add(UnlinkedExprOperation.forInitializerDeclarationsUntyped);
-          } else {
-            references.add(serializeType(type));
-            operations
-                .add(UnlinkedExprOperation.forInitializerDeclarationsTyped);
-          }
-          ints.add(parts.variables.variables.length);
-        } else {
-          throw StateError('Unrecognized for parts');
-        }
-        _serialize(parts.condition, emptyExpressionPermitted: true);
-        for (var updater in parts.updaters) {
-          _serialize(updater);
-        }
-        operations.add(UnlinkedExprOperation.forParts);
-        ints.add(parts.updaters.length);
-      } else if (parts is ForEachParts) {
-        if (parts is ForEachPartsWithIdentifier) {
-          _serialize(parts.identifier);
-          _serialize(parts.iterable);
-          operations.add(UnlinkedExprOperation.forEachPartsWithIdentifier);
-        } else if (parts is ForEachPartsWithDeclaration) {
-          _serialize(parts.iterable);
-          var type = parts.loopVariable.type;
-          if (type == null) {
-            operations
-                .add(UnlinkedExprOperation.forEachPartsWithUntypedDeclaration);
-          } else {
-            references.add(serializeType(type));
-            operations
-                .add(UnlinkedExprOperation.forEachPartsWithTypedDeclaration);
-          }
-          var name = parts.loopVariable.identifier.name;
-          strings.add(name);
-          pushVariableName(name);
-          ++numVariablesToPop;
-        } else {
-          throw StateError('Unrecognized for parts');
-        }
-      } else {
-        throw StateError('Unrecognized for parts');
-      }
-      _serializeCollectionElement(element.body);
-      popVariableNames(numVariablesToPop);
-      operations.add(element.awaitKeyword == null
-          ? UnlinkedExprOperation.forElement
-          : UnlinkedExprOperation.forElementWithAwait);
-    } else {
-      throw new StateError('Unsupported CollectionElement: $element');
-    }
-  }
-
-  void _serializeListLiteral(ListLiteral expr) {
-    if (forConst || expr.typeArguments == null) {
-      List<CollectionElement> elements = expr.elements;
-      elements.forEach(_serializeCollectionElement);
-      ints.add(elements.length);
-    } else {
-      ints.add(0);
-    }
-    if (expr.typeArguments != null &&
-        expr.typeArguments.arguments.length == 1) {
-      references.add(serializeType(expr.typeArguments.arguments[0]));
-      operations.add(UnlinkedExprOperation.makeTypedList);
-    } else {
-      operations.add(UnlinkedExprOperation.makeUntypedList);
-    }
-  }
-
-  void _serializeMethodInvocation(MethodInvocation invocation) {
-    Expression target = invocation.target;
-    SimpleIdentifier methodName = invocation.methodName;
-    ArgumentList argumentList = invocation.argumentList;
-    if (_isIdentifierSequence(methodName)) {
-      EntityRefBuilder ref = serializeIdentifierSequence(methodName);
-      _serializeArguments(argumentList, invocation.typeArguments != null);
-      references.add(ref);
-      _serializeTypeArguments(invocation.typeArguments);
-      operations.add(UnlinkedExprOperation.invokeMethodRef);
-    } else {
-      if (!invocation.isCascaded) {
-        _serialize(target);
-      }
-      _serializeArguments(argumentList, invocation.typeArguments != null);
-      strings.add(methodName.name);
-      _serializeTypeArguments(invocation.typeArguments);
-      operations.add(UnlinkedExprOperation.invokeMethod);
-    }
-  }
-
-  void _serializePostfixExpression(PostfixExpression expr) {
-    TokenType operator = expr.operator.type;
-    Expression operand = expr.operand;
-    if (operator == TokenType.PLUS_PLUS) {
-      _serializePrefixPostfixIncDec(
-          operand, UnlinkedExprAssignOperator.postfixIncrement);
-    } else if (operator == TokenType.MINUS_MINUS) {
-      _serializePrefixPostfixIncDec(
-          operand, UnlinkedExprAssignOperator.postfixDecrement);
-    } else {
-      throw new StateError('Unknown operator: $operator');
-    }
-  }
-
-  void _serializePrefixExpression(PrefixExpression expr) {
-    TokenType operator = expr.operator.type;
-    Expression operand = expr.operand;
-    if (operator == TokenType.BANG) {
-      _serialize(operand);
-      operations.add(UnlinkedExprOperation.not);
-    } else if (operator == TokenType.MINUS) {
-      _serialize(operand);
-      operations.add(UnlinkedExprOperation.negate);
-    } else if (operator == TokenType.TILDE) {
-      _serialize(operand);
-      operations.add(UnlinkedExprOperation.complement);
-    } else if (operator == TokenType.PLUS_PLUS) {
-      _serializePrefixPostfixIncDec(
-          operand, UnlinkedExprAssignOperator.prefixIncrement);
-    } else if (operator == TokenType.MINUS_MINUS) {
-      _serializePrefixPostfixIncDec(
-          operand, UnlinkedExprAssignOperator.prefixDecrement);
-    } else {
-      throw new StateError('Unknown operator: $operator');
-    }
-  }
-
-  void _serializePrefixPostfixIncDec(
-      Expression operand, UnlinkedExprAssignOperator operator) {
-    isValidConst = false;
-    assignmentOperators.add(operator);
-    _pushAssignable(operand);
-  }
-
-  void _serializePropertyAccess(PropertyAccess expr) {
-    if (_isIdentifierSequence(expr)) {
-      EntityRefBuilder ref = serializeIdentifierSequence(expr);
-      references.add(ref);
-      operations.add(UnlinkedExprOperation.pushReference);
-    } else {
-      if (!expr.isCascaded) {
-        _serialize(expr.target);
-      }
-      strings.add(expr.propertyName.name);
-      operations.add(UnlinkedExprOperation.extractProperty);
-    }
-  }
-
-  void _serializeSetOrMapLiteral(SetOrMapLiteral expr) {
-    if (forConst || expr.typeArguments == null) {
-      for (CollectionElement element in expr.elements) {
-        _serializeCollectionElement(element);
-      }
-      ints.add(expr.elements.length);
-    } else {
-      ints.add(0);
-    }
-
-    List<TypeAnnotation> typeArguments = expr.typeArguments?.arguments;
-    if (typeArguments != null && typeArguments.length == 2) {
-      references.add(serializeType(typeArguments[0]));
-      references.add(serializeType(typeArguments[1]));
-      operations.add(UnlinkedExprOperation.makeTypedMap2);
-    } else if (typeArguments != null && typeArguments.length == 1) {
-      references.add(serializeType(typeArguments[0]));
-      operations.add(UnlinkedExprOperation.makeTypedSet);
-    } else {
-      operations.add(UnlinkedExprOperation.makeUntypedSetOrMap);
-    }
-  }
-
-  void _serializeString(StringLiteral expr) {
-    if (expr is AdjacentStrings) {
-      if (expr.strings.every((string) => string is SimpleStringLiteral)) {
-        operations.add(UnlinkedExprOperation.pushString);
-        strings.add(expr.stringValue);
-      } else {
-        expr.strings.forEach(_serializeString);
-        operations.add(UnlinkedExprOperation.concatenate);
-        ints.add(expr.strings.length);
-      }
-    } else if (expr is SimpleStringLiteral) {
-      operations.add(UnlinkedExprOperation.pushString);
-      strings.add(expr.value);
-    } else {
-      StringInterpolation interpolation = expr as StringInterpolation;
-      for (InterpolationElement element in interpolation.elements) {
-        if (element is InterpolationString) {
-          operations.add(UnlinkedExprOperation.pushString);
-          strings.add(element.value);
-        } else {
-          _serialize((element as InterpolationExpression).expression);
-        }
-      }
-      operations.add(UnlinkedExprOperation.concatenate);
-      ints.add(interpolation.elements.length);
-    }
-  }
-
-  void _serializeTypeArguments(TypeArgumentList typeArguments) {
-    if (typeArguments == null) {
-      ints.add(0);
-    } else {
-      ints.add(typeArguments.arguments.length);
-      for (TypeAnnotation type in typeArguments.arguments) {
-        references.add(serializeType(type));
-      }
-    }
-  }
-
-  EntityRefNullabilitySuffix computeNullabilitySuffix(Token question);
-}
diff --git a/pkg/analyzer/lib/src/summary/summary_file_builder.dart b/pkg/analyzer/lib/src/summary/summary_file_builder.dart
index 9068bfd..b42a5a4 100644
--- a/pkg/analyzer/lib/src/summary/summary_file_builder.dart
+++ b/pkg/analyzer/lib/src/summary/summary_file_builder.dart
@@ -4,14 +4,12 @@
 
 import 'dart:collection';
 
-import 'package:analyzer/dart/analysis/declared_variables.dart';
 import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/token.dart';
 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/analysis/driver.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';
@@ -19,10 +17,6 @@
 import 'package:analyzer/src/generated/parser.dart';
 import 'package:analyzer/src/generated/sdk.dart';
 import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/summary/format.dart';
-import 'package:analyzer/src/summary/idl.dart';
-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;
@@ -76,7 +70,6 @@
   final Iterable<Source> librarySources;
 
   final Set<String> libraryUris = new Set<String>();
-  final Map<String, UnlinkedUnit> unlinkedMap = <String, UnlinkedUnit>{};
   final List<summary2.LinkInputLibrary> inputLibraries = [];
 
   final PackageBundleAssembler bundleAssembler = new PackageBundleAssembler();
@@ -89,24 +82,14 @@
   List<int> build() {
     librarySources.forEach(_addLibrary);
 
-    var useSummary2 = AnalysisDriver.useSummary2;
-    try {
-      AnalysisDriver.useSummary2 = false;
-      Map<String, LinkedLibraryBuilder> map = link(libraryUris, (uri) {
-        throw new StateError('Unexpected call to GetDependencyCallback($uri).');
-      }, (uri) {
-        UnlinkedUnit unlinked = unlinkedMap[uri];
-        if (unlinked == null) {
-          throw new StateError('Unable to find unresolved unit $uri.');
-        }
-        return unlinked;
-      }, DeclaredVariables(), context.analysisOptions);
-      map.forEach(bundleAssembler.addLinkedLibrary);
-    } finally {
-      AnalysisDriver.useSummary2 = useSummary2;
-    }
+    var elementFactory = summary2.LinkedElementFactory(
+      context,
+      null,
+      summary2.Reference.root(),
+    );
 
-    _link2();
+    var linkResult = summary2.link(elementFactory, inputLibraries);
+    bundleAssembler.setBundle2(linkResult.bundle);
 
     return bundleAssembler.assemble().toBuffer();
   }
@@ -120,7 +103,6 @@
     var inputUnits = <summary2.LinkInputUnit>[];
 
     CompilationUnit definingUnit = _parse(source);
-    _addUnlinked(source, definingUnit);
     inputUnits.add(
       summary2.LinkInputUnit(null, source, false, definingUnit),
     );
@@ -134,7 +116,6 @@
         String partUri = directive.uri.stringValue;
         Source partSource = context.sourceFactory.resolveUri(source, partUri);
         CompilationUnit partUnit = _parse(partSource);
-        _addUnlinked(partSource, partUnit);
         inputUnits.add(
           summary2.LinkInputUnit(partUri, partSource, false, partUnit),
         );
@@ -146,24 +127,6 @@
     );
   }
 
-  void _addUnlinked(Source source, CompilationUnit unit) {
-    String uriStr = source.uri.toString();
-    UnlinkedUnitBuilder unlinked = serializeAstUnlinked(unit);
-    unlinkedMap[uriStr] = unlinked;
-    bundleAssembler.addUnlinkedUnit(source, unlinked);
-  }
-
-  void _link2() {
-    var elementFactory = summary2.LinkedElementFactory(
-      context,
-      null,
-      summary2.Reference.root(),
-    );
-
-    var linkResult = summary2.link(elementFactory, inputLibraries);
-    bundleAssembler.setBundle2(linkResult.bundle);
-  }
-
   CompilationUnit _parse(Source source) {
     AnalysisErrorListener errorListener = AnalysisErrorListener.NULL_LISTENER;
     String code = source.contents.data;
diff --git a/pkg/analyzer/lib/src/summary2/linked_unit_context.dart b/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
index 6e15f41..ef725a0 100644
--- a/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
+++ b/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
@@ -20,6 +20,7 @@
 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/type_builder.dart';
 
 /// The context of a unit - the context of the bundle, and the unit tokens.
 class LinkedUnitContext {
@@ -238,7 +239,12 @@
   }
 
   DartType getDefaultType(TypeParameter node) {
-    return LazyTypeParameter.getDefaultType(_astReader, node);
+    var type = LazyTypeParameter.getDefaultType(_astReader, node);
+    if (type is TypeBuilder) {
+      type = (type as TypeBuilder).build();
+      LazyAst.setDefaultType(node, type);
+    }
+    return type;
   }
 
   String getDefaultValueCode(AstNode node) {
diff --git a/pkg/analyzer/lib/src/summary2/top_level_inference.dart b/pkg/analyzer/lib/src/summary2/top_level_inference.dart
index f4273a7..2cef609 100644
--- a/pkg/analyzer/lib/src/summary2/top_level_inference.dart
+++ b/pkg/analyzer/lib/src/summary2/top_level_inference.dart
@@ -40,6 +40,7 @@
   final Linker linker;
 
   LibraryElement _library;
+  bool _enclosingClassHasConstConstructor = false;
   Scope _scope;
 
   ConstantInitializersResolver(this.linker);
@@ -59,11 +60,15 @@
   }
 
   void _resolveClassFields(ClassElement class_) {
+    _enclosingClassHasConstConstructor =
+        class_.constructors.any((c) => c.isConst);
+
     var node = _getLinkedNode(class_);
     _scope = LinkingNodeContext.get(node).scope;
     for (var element in class_.fields) {
       _resolveVariable(element);
     }
+    _enclosingClassHasConstConstructor = false;
   }
 
   void _resolveExtensionFields(ExtensionElement extension_) {
@@ -82,15 +87,18 @@
 
     VariableDeclarationList declarationList = variable.parent;
     var typeNode = declarationList.type;
-    if (declarationList.isConst && typeNode != null) {
-      var holder = ElementHolder();
-      variable.initializer.accept(LocalElementBuilder(holder, null));
-      (element as VariableElementImpl).encloseElements(holder.functions);
+    if (typeNode != null) {
+      if (declarationList.isConst ||
+          declarationList.isFinal && _enclosingClassHasConstConstructor) {
+        var holder = ElementHolder();
+        variable.initializer.accept(LocalElementBuilder(holder, null));
+        (element as VariableElementImpl).encloseElements(holder.functions);
 
-      InferenceContext.setType(variable.initializer, typeNode.type);
-      var astResolver = AstResolver(linker, _library, _scope);
-      astResolver.rewriteAst(variable.initializer);
-      astResolver.resolve(variable.initializer);
+        InferenceContext.setType(variable.initializer, typeNode.type);
+        var astResolver = AstResolver(linker, _library, _scope);
+        astResolver.rewriteAst(variable.initializer);
+        astResolver.resolve(variable.initializer);
+      }
     }
   }
 }
diff --git a/pkg/analyzer/lib/src/task/strong_mode.dart b/pkg/analyzer/lib/src/task/strong_mode.dart
index 21fcc0a..d0e19d8 100644
--- a/pkg/analyzer/lib/src/task/strong_mode.dart
+++ b/pkg/analyzer/lib/src/task/strong_mode.dart
@@ -14,8 +14,6 @@
 import 'package:analyzer/src/generated/resolver.dart' show TypeProvider;
 import 'package:analyzer/src/summary/format.dart';
 import 'package:analyzer/src/summary/idl.dart';
-import 'package:analyzer/src/summary/link.dart'
-    show FieldElementForLink_ClassField, ParameterElementForLink;
 import 'package:analyzer/src/summary2/lazy_ast.dart';
 
 /**
@@ -177,9 +175,6 @@
               kind: TopLevelInferenceErrorKind.overrideConflictParameterType,
             ),
           );
-        } else if (parameter is ParameterElementForLink) {
-          parameter.setInferenceError(new TopLevelInferenceErrorBuilder(
-              kind: TopLevelInferenceErrorKind.overrideConflictParameterType));
         }
         return typeProvider.dynamicType;
       }
@@ -428,9 +423,6 @@
             kind: TopLevelInferenceErrorKind.overrideConflictFieldType,
           ),
         );
-      } else if (field is FieldElementForLink_ClassField) {
-        field.setInferenceError(new TopLevelInferenceErrorBuilder(
-            kind: TopLevelInferenceErrorKind.overrideConflictFieldType));
       }
       return;
     }
diff --git a/pkg/analyzer/pubspec.yaml b/pkg/analyzer/pubspec.yaml
index a1a5220..a4345eb 100644
--- a/pkg/analyzer/pubspec.yaml
+++ b/pkg/analyzer/pubspec.yaml
@@ -1,5 +1,5 @@
 name: analyzer
-version: 0.38.4
+version: 0.38.5-dev
 author: Dart Team <misc@dartlang.org>
 description: This package provides a library that performs static analysis of Dart code.
 homepage: https://github.com/dart-lang/sdk/tree/master/pkg/analyzer
diff --git a/pkg/analyzer/test/file_system/physical_resource_provider_watch_test.dart b/pkg/analyzer/test/file_system/physical_resource_provider_watch_test.dart
index 6f68a1e..bac4ad2 100644
--- a/pkg/analyzer/test/file_system/physical_resource_provider_watch_test.dart
+++ b/pkg/analyzer/test/file_system/physical_resource_provider_watch_test.dart
@@ -7,7 +7,7 @@
 
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/file_system/physical_file_system.dart';
-import 'package:path/path.dart' as pathLib;
+import 'package:path/path.dart' as path;
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 import 'package:watcher/watcher.dart';
@@ -25,10 +25,10 @@
 @reflectiveTest
 class PhysicalResourceProviderWatchTest extends BaseTest {
   test_watchFile_delete() {
-    var path = pathLib.join(tempPath, 'foo');
-    var file = new io.File(path);
+    var filePath = path.join(tempPath, 'foo');
+    var file = new io.File(filePath);
     file.writeAsStringSync('contents 1');
-    return _watchingFile(path, (changesReceived) {
+    return _watchingFile(filePath, (changesReceived) {
       expect(changesReceived, hasLength(0));
       file.deleteSync();
       return _delayed(() {
@@ -43,22 +43,22 @@
         } else {
           expect(changesReceived[0].type, equals(ChangeType.REMOVE));
         }
-        expect(changesReceived[0].path, equals(path));
+        expect(changesReceived[0].path, equals(filePath));
       });
     });
   }
 
   test_watchFile_modify() {
-    var path = pathLib.join(tempPath, 'foo');
-    var file = new io.File(path);
+    var filePath = path.join(tempPath, 'foo');
+    var file = new io.File(filePath);
     file.writeAsStringSync('contents 1');
-    return _watchingFile(path, (changesReceived) {
+    return _watchingFile(filePath, (changesReceived) {
       expect(changesReceived, hasLength(0));
       file.writeAsStringSync('contents 2');
       return _delayed(() {
         expect(changesReceived, hasLength(1));
         expect(changesReceived[0].type, equals(ChangeType.MODIFY));
-        expect(changesReceived[0].path, equals(path));
+        expect(changesReceived[0].path, equals(filePath));
       });
     });
   }
@@ -66,26 +66,26 @@
   test_watchFolder_createFile() {
     return _watchingFolder(tempPath, (changesReceived) {
       expect(changesReceived, hasLength(0));
-      var path = pathLib.join(tempPath, 'foo');
-      new io.File(path).writeAsStringSync('contents');
+      var filePath = path.join(tempPath, 'foo');
+      new io.File(filePath).writeAsStringSync('contents');
       return _delayed(() {
         // There should be an "add" event indicating that the file was added.
         // Depending on how long it took to write the contents, it may be
         // followed by "modify" events.
         expect(changesReceived, isNotEmpty);
         expect(changesReceived[0].type, equals(ChangeType.ADD));
-        expect(changesReceived[0].path, equals(path));
+        expect(changesReceived[0].path, equals(filePath));
         for (int i = 1; i < changesReceived.length; i++) {
           expect(changesReceived[i].type, equals(ChangeType.MODIFY));
-          expect(changesReceived[i].path, equals(path));
+          expect(changesReceived[i].path, equals(filePath));
         }
       });
     });
   }
 
   test_watchFolder_deleteFile() {
-    var path = pathLib.join(tempPath, 'foo');
-    var file = new io.File(path);
+    var filePath = path.join(tempPath, 'foo');
+    var file = new io.File(filePath);
     file.writeAsStringSync('contents 1');
     return _watchingFolder(tempPath, (changesReceived) {
       expect(changesReceived, hasLength(0));
@@ -93,14 +93,14 @@
       return _delayed(() {
         expect(changesReceived, hasLength(1));
         expect(changesReceived[0].type, equals(ChangeType.REMOVE));
-        expect(changesReceived[0].path, equals(path));
+        expect(changesReceived[0].path, equals(filePath));
       });
     });
   }
 
   test_watchFolder_modifyFile() {
-    var path = pathLib.join(tempPath, 'foo');
-    var file = new io.File(path);
+    var filePath = path.join(tempPath, 'foo');
+    var file = new io.File(filePath);
     file.writeAsStringSync('contents 1');
     return _watchingFolder(tempPath, (changesReceived) {
       expect(changesReceived, hasLength(0));
@@ -108,16 +108,16 @@
       return _delayed(() {
         expect(changesReceived, hasLength(1));
         expect(changesReceived[0].type, equals(ChangeType.MODIFY));
-        expect(changesReceived[0].path, equals(path));
+        expect(changesReceived[0].path, equals(filePath));
       });
     });
   }
 
   test_watchFolder_modifyFile_inSubDir() {
-    var fooPath = pathLib.join(tempPath, 'foo');
+    var fooPath = path.join(tempPath, 'foo');
     new io.Directory(fooPath).createSync();
-    var path = pathLib.join(tempPath, 'bar');
-    var file = new io.File(path);
+    var barPath = path.join(tempPath, 'bar');
+    var file = new io.File(barPath);
     file.writeAsStringSync('contents 1');
     return _watchingFolder(tempPath, (changesReceived) {
       expect(changesReceived, hasLength(0));
@@ -125,7 +125,7 @@
       return _delayed(() {
         expect(changesReceived, anyOf(hasLength(1), hasLength(2)));
         expect(changesReceived[0].type, equals(ChangeType.MODIFY));
-        expect(changesReceived[0].path, equals(path));
+        expect(changesReceived[0].path, equals(barPath));
       });
     });
   }
@@ -137,13 +137,13 @@
     return new Future.delayed(new Duration(seconds: 1), computation);
   }
 
-  _watchingFile(String path, test(List<WatchEvent> changesReceived)) {
+  _watchingFile(String filePath, test(List<WatchEvent> changesReceived)) {
     // Delay before we start watching the file.  This is necessary
     // because on MacOS, file modifications that occur just before we
     // start watching are sometimes misclassified as happening just after
     // we start watching.
     return _delayed(() {
-      File file = PhysicalResourceProvider.INSTANCE.getResource(path);
+      File file = PhysicalResourceProvider.INSTANCE.getResource(filePath);
       var changesReceived = <WatchEvent>[];
       var subscription = file.changes.listen(changesReceived.add);
       // Delay running the rest of the test to allow file.changes propagate.
@@ -153,13 +153,13 @@
     });
   }
 
-  _watchingFolder(String path, test(List<WatchEvent> changesReceived)) {
+  _watchingFolder(String filePath, test(List<WatchEvent> changesReceived)) {
     // Delay before we start watching the folder.  This is necessary
     // because on MacOS, file modifications that occur just before we
     // start watching are sometimes misclassified as happening just after
     // we start watching.
     return _delayed(() {
-      Folder folder = PhysicalResourceProvider.INSTANCE.getResource(path);
+      Folder folder = PhysicalResourceProvider.INSTANCE.getResource(filePath);
       var changesReceived = <WatchEvent>[];
       var subscription = folder.changes.listen(changesReceived.add);
       // Delay running the rest of the test to allow folder.changes to
diff --git a/pkg/analyzer/test/generated/compile_time_error_code.dart b/pkg/analyzer/test/generated/compile_time_error_code.dart
index 49b349f..8a60f47 100644
--- a/pkg/analyzer/test/generated/compile_time_error_code.dart
+++ b/pkg/analyzer/test/generated/compile_time_error_code.dart
@@ -6,7 +6,6 @@
 
 import 'package:analyzer/dart/analysis/declared_variables.dart';
 import 'package:analyzer/error/error.dart';
-import 'package:analyzer/src/dart/analysis/driver.dart';
 import 'package:analyzer/src/dart/analysis/experiments.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer/src/generated/parser.dart' show ParserErrorCode;
@@ -1679,20 +1678,7 @@
     var code = '''
 void g(T f<T>(T x)) {}
 ''';
-    if (AnalysisDriver.useSummary2) {
-      await assertNoErrorsInCode(code);
-    } else {
-      // 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(CompileTimeErrorCode.UNDEFINED_CLASS, 7, 1),
-        error(CompileTimeErrorCode.GENERIC_FUNCTION_TYPED_PARAM_UNSUPPORTED, 7,
-            11),
-        error(CompileTimeErrorCode.UNDEFINED_CLASS, 14, 1),
-      ]);
-    }
+    await assertNoErrorsInCode(code);
   }
 
   test_implementsDeferredClass() async {
@@ -4786,18 +4772,10 @@
   }
 
   test_typeAliasCannotReferenceItself_generic() async {
-    List<ExpectedError> expectedErrors;
-    if (AnalysisDriver.useSummary2) {
-      expectedErrors = [
-        error(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 0, 37),
-        error(StaticTypeWarningCode.RETURN_OF_INVALID_TYPE, 101, 1),
-      ];
-    } else {
-      expectedErrors = [
-        error(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 0, 37),
-        error(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 38, 37),
-      ];
-    }
+    List<ExpectedError> expectedErrors = [
+      error(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 0, 37),
+      error(StaticTypeWarningCode.RETURN_OF_INVALID_TYPE, 101, 1),
+    ];
     await assertErrorsInCode(r'''
 typedef F = void Function(List<G> l);
 typedef G = void Function(List<F> l);
diff --git a/pkg/analyzer/test/generated/invalid_code_test.dart b/pkg/analyzer/test/generated/invalid_code_test.dart
index 6659778..e97dbde 100644
--- a/pkg/analyzer/test/generated/invalid_code_test.dart
+++ b/pkg/analyzer/test/generated/invalid_code_test.dart
@@ -5,7 +5,6 @@
 import 'dart:async';
 
 import 'package:analyzer/dart/analysis/features.dart';
-import 'package:analyzer/src/dart/analysis/driver.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -13,23 +12,11 @@
 
 main() {
   defineReflectiveSuite(() {
-    if (AnalysisDriver.useSummary2) {
-      defineReflectiveTests(InvalidCodeSummary2Test);
-    } else {
-      defineReflectiveTests(InvalidCodeTest);
-    }
+    defineReflectiveTests(InvalidCodeTest);
     defineReflectiveTests(InvalidCodeWithExtensionMethodsTest);
   });
 }
 
-@reflectiveTest
-class InvalidCodeSummary2Test extends InvalidCodeTest {
-  @failingTest
-  test_fuzz_12() {
-    return test_fuzz_12();
-  }
-}
-
 /// Tests for various end-to-end cases when invalid code caused exceptions
 /// in one or another Analyzer subsystem. We are not interested not in specific
 /// errors generated, but we want to make sure that there is at least one,
@@ -159,6 +146,7 @@
 ''');
   }
 
+  @failingTest
   test_fuzz_12() async {
     // This code crashed with summary2 because usually AST reader is lazy,
     // so we did not read metadata `@b` for `c`. But default values must be
diff --git a/pkg/analyzer/test/generated/issues_test.dart b/pkg/analyzer/test/generated/issues_test.dart
new file mode 100644
index 0000000..93b97b9
--- /dev/null
+++ b/pkg/analyzer/test/generated/issues_test.dart
@@ -0,0 +1,33 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../src/dart/resolution/driver_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(IssuesTest);
+  });
+}
+
+/// Tests for various end-to-end cases reported as user issues, where it is
+/// not obvious where to put the test otherwise.
+@reflectiveTest
+class IssuesTest extends DriverResolutionTest {
+  /// https://github.com/dart-lang/sdk/issues/38589
+  test_issue38589() async {
+    await resolveTestCode('''
+mixin M {}
+
+class A implements M {}
+
+class B implements M {}
+
+var b = true;
+var c = b ? A() : B();
+''');
+    assertElementTypeString(findElement.topVar('c').type, 'M');
+  }
+}
diff --git a/pkg/analyzer/test/generated/parser_fasta_listener.dart b/pkg/analyzer/test/generated/parser_fasta_listener.dart
index f3145f8..203d6db 100644
--- a/pkg/analyzer/test/generated/parser_fasta_listener.dart
+++ b/pkg/analyzer/test/generated/parser_fasta_listener.dart
@@ -1152,9 +1152,10 @@
   }
 
   @override
-  void endTypeVariable(Token token, int index, Token extendsOrSuper) {
+  void endTypeVariable(
+      Token token, int index, Token extendsOrSuper, Token variance) {
     end('TypeVariable');
-    super.endTypeVariable(token, index, extendsOrSuper);
+    super.endTypeVariable(token, index, extendsOrSuper, variance);
   }
 
   @override
diff --git a/pkg/analyzer/test/generated/parser_fasta_test.dart b/pkg/analyzer/test/generated/parser_fasta_test.dart
index 1a16278..c92e79d 100644
--- a/pkg/analyzer/test/generated/parser_fasta_test.dart
+++ b/pkg/analyzer/test/generated/parser_fasta_test.dart
@@ -3037,6 +3037,103 @@
     expect(target.operand.toSource(), 'obj');
   }
 
+  void test_nullCheckOnIndex3() {
+    // https://github.com/dart-lang/sdk/issues/37708
+    var unit = parseCompilationUnit('f() { foo.bar![arg]; }');
+    var funct = unit.declarations[0] as FunctionDeclaration;
+    var body = funct.functionExpression.body as BlockFunctionBody;
+    var statement = body.block.statements[0] as ExpressionStatement;
+    var expression = statement.expression as IndexExpression;
+    expect(expression.index.toSource(), 'arg');
+    var target = expression.target as PostfixExpression;
+    expect(target.operand.toSource(), 'foo.bar');
+    expect(target.operator.lexeme, '!');
+  }
+
+  void test_nullCheckOnIndex4() {
+    // https://github.com/dart-lang/sdk/issues/37708
+    var unit = parseCompilationUnit('f() { foo!.bar![arg]; }');
+    var funct = unit.declarations[0] as FunctionDeclaration;
+    var body = funct.functionExpression.body as BlockFunctionBody;
+    var statement = body.block.statements[0] as ExpressionStatement;
+    var expression = statement.expression as IndexExpression;
+    var fooBarTarget = expression.target as PostfixExpression;
+    expect(fooBarTarget.toSource(), "foo!.bar!");
+    var propertyAccess = fooBarTarget.operand as PropertyAccess;
+    var targetFoo = propertyAccess.target as PostfixExpression;
+    expect(targetFoo.operand.toSource(), "foo");
+    expect(targetFoo.operator.lexeme, "!");
+    expect(propertyAccess.propertyName.toSource(), "bar");
+    expect(fooBarTarget.operator.lexeme, '!');
+    expect(expression.index.toSource(), 'arg');
+  }
+
+  void test_nullCheckOnIndex5() {
+    // https://github.com/dart-lang/sdk/issues/37708
+    var unit = parseCompilationUnit('f() { foo.bar![arg]![arg2]; }');
+    var funct = unit.declarations[0] as FunctionDeclaration;
+    var body = funct.functionExpression.body as BlockFunctionBody;
+    var statement = body.block.statements[0] as ExpressionStatement;
+    var expression = statement.expression as IndexExpression;
+    expect(expression.index.toSource(), 'arg2');
+    var target = expression.target as PostfixExpression;
+    expect(target.operator.lexeme, '!');
+    expression = target.operand as IndexExpression;
+    expect(expression.index.toSource(), 'arg');
+    target = expression.target as PostfixExpression;
+    expect(target.operator.lexeme, '!');
+    expect(target.operand.toSource(), 'foo.bar');
+  }
+
+  void test_nullCheckOnIndex6() {
+    // https://github.com/dart-lang/sdk/issues/37708
+    var unit = parseCompilationUnit('f() { foo!.bar![arg]![arg2]; }');
+    var funct = unit.declarations[0] as FunctionDeclaration;
+    var body = funct.functionExpression.body as BlockFunctionBody;
+    var statement = body.block.statements[0] as ExpressionStatement;
+
+    // expression is "foo!.bar![arg]![arg2]"
+    var expression = statement.expression as IndexExpression;
+    expect(expression.index.toSource(), 'arg2');
+
+    // target is "foo!.bar![arg]!"
+    var target = expression.target as PostfixExpression;
+    expect(target.operator.lexeme, '!');
+
+    // expression is "foo!.bar![arg]"
+    expression = target.operand as IndexExpression;
+    expect(expression.index.toSource(), 'arg');
+
+    // target is "foo!.bar!"
+    target = expression.target as PostfixExpression;
+    expect(target.operator.lexeme, '!');
+
+    // propertyAccess is "foo!.bar"
+    PropertyAccess propertyAccess = target.operand as PropertyAccess;
+    expect(propertyAccess.propertyName.toSource(), "bar");
+
+    // target is "foo!"
+    target = propertyAccess.target as PostfixExpression;
+    expect(target.operator.lexeme, '!');
+
+    expect(target.operand.toSource(), "foo");
+  }
+
+  void test_nullCheckBeforeIndex() {
+    // https://github.com/dart-lang/sdk/issues/37708
+    var unit = parseCompilationUnit('f() { foo.bar!.baz[arg]; }');
+    var funct = unit.declarations[0] as FunctionDeclaration;
+    var body = funct.functionExpression.body as BlockFunctionBody;
+    var statement = body.block.statements[0] as ExpressionStatement;
+    var expression = statement.expression as IndexExpression;
+    expect(expression.index.toSource(), 'arg');
+    var propertyAccess = expression.target as PropertyAccess;
+    expect(propertyAccess.propertyName.toSource(), 'baz');
+    var target = propertyAccess.target as PostfixExpression;
+    expect(target.operand.toSource(), 'foo.bar');
+    expect(target.operator.lexeme, '!');
+  }
+
   void test_nullCheckOnLiteral_disabled() {
     parseCompilationUnit('f() { var x = 0!; }',
         errors: [expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 15, 1)],
diff --git a/pkg/analyzer/test/generated/resolver_test.dart b/pkg/analyzer/test/generated/resolver_test.dart
index c49393b..f7c425f 100644
--- a/pkg/analyzer/test/generated/resolver_test.dart
+++ b/pkg/analyzer/test/generated/resolver_test.dart
@@ -1085,7 +1085,7 @@
     _listener.assertNoErrors();
   }
 
-  void setUp({bool shouldSetElementSupertypes: false}) {
+  void setUp() {
     _listener = new GatheringErrorListener();
     AnalysisContext context = TestAnalysisContext();
     Source librarySource = new FileSource(getFile("/lib.dart"));
@@ -1102,9 +1102,7 @@
     libraryScope = new LibraryScope(element);
     _visitor = new TypeResolverVisitor(
         element, librarySource, _typeProvider, _listener,
-        featureSet: featureSet,
-        nameScope: libraryScope,
-        shouldSetElementSupertypes: shouldSetElementSupertypes);
+        featureSet: featureSet, nameScope: libraryScope);
   }
 
   test_modeApi() async {
@@ -1550,57 +1548,6 @@
     _listener.assertNoErrors();
   }
 
-  test_visitClassDeclaration() async {
-    // class A extends B with C implements D {}
-    // class B {}
-    // class C {}
-    // class D {}
-    setUp(shouldSetElementSupertypes: true);
-    ClassElement elementA = ElementFactory.classElement2("A");
-    ClassElement elementB = ElementFactory.classElement2("B");
-    ClassElement elementC = ElementFactory.classElement2("C");
-    ClassElement elementD = ElementFactory.classElement2("D");
-    ExtendsClause extendsClause =
-        AstTestFactory.extendsClause(AstTestFactory.typeName(elementB));
-    WithClause withClause =
-        AstTestFactory.withClause([AstTestFactory.typeName(elementC)]);
-    ImplementsClause implementsClause =
-        AstTestFactory.implementsClause([AstTestFactory.typeName(elementD)]);
-    ClassDeclaration declaration = AstTestFactory.classDeclaration(
-        null, "A", null, extendsClause, withClause, implementsClause);
-    declaration.name.staticElement = elementA;
-    _resolveNode(declaration, [elementA, elementB, elementC, elementD]);
-    expect(elementA.supertype, interfaceType(elementB));
-    List<InterfaceType> mixins = elementA.mixins;
-    expect(mixins, hasLength(1));
-    expect(mixins[0], interfaceType(elementC));
-    List<InterfaceType> interfaces = elementA.interfaces;
-    expect(interfaces, hasLength(1));
-    expect(interfaces[0], interfaceType(elementD));
-    _listener.assertNoErrors();
-  }
-
-  test_visitClassDeclaration_instanceMemberCollidesWithClass() async {
-    // class A {}
-    // class B extends A {
-    //   void A() {}
-    // }
-    setUp(shouldSetElementSupertypes: true);
-    ClassElementImpl elementA = ElementFactory.classElement2("A");
-    ClassElementImpl elementB = ElementFactory.classElement2("B");
-    elementB.methods = <MethodElement>[
-      ElementFactory.methodElement("A", VoidTypeImpl.instance)
-    ];
-    ExtendsClause extendsClause =
-        AstTestFactory.extendsClause(AstTestFactory.typeName(elementA));
-    ClassDeclaration declaration = AstTestFactory.classDeclaration(
-        null, "B", null, extendsClause, null, null);
-    declaration.name.staticElement = elementB;
-    _resolveNode(declaration, [elementA, elementB]);
-    expect(elementB.supertype, interfaceType(elementA));
-    _listener.assertNoErrors();
-  }
-
   test_visitFieldFormalParameter_functionType() async {
     InterfaceType intType = _typeProvider.intType;
     TypeName intTypeName = AstTestFactory.typeName4('int');
diff --git a/pkg/analyzer/test/generated/static_type_warning_code_test.dart b/pkg/analyzer/test/generated/static_type_warning_code_test.dart
index b9c570d..59ffc3d 100644
--- a/pkg/analyzer/test/generated/static_type_warning_code_test.dart
+++ b/pkg/analyzer/test/generated/static_type_warning_code_test.dart
@@ -1063,7 +1063,7 @@
     ]);
   }
 
-  test_typeParameterSupertypeOfItsBound() async {
+  test_typeParameterSupertypeOfItsBound_1of1() async {
     await assertErrorsInCode(r'''
 class A<T extends T> {
 }
@@ -1072,6 +1072,17 @@
     ]);
   }
 
+  test_typeParameterSupertypeOfItsBound_2of3() async {
+    await assertErrorsInCode(r'''
+class A<T1 extends T3, T2, T3 extends T1> {
+}
+''', [
+      error(StaticTypeWarningCode.TYPE_PARAMETER_SUPERTYPE_OF_ITS_BOUND, 8, 13),
+      error(
+          StaticTypeWarningCode.TYPE_PARAMETER_SUPERTYPE_OF_ITS_BOUND, 27, 13),
+    ]);
+  }
+
   test_typePromotion_booleanAnd_useInRight_accessedInClosureRight_mutated() async {
     await assertErrorsInCode(r'''
 callMe(f()) { f(); }
diff --git a/pkg/analyzer/test/generated/strong_mode_test.dart b/pkg/analyzer/test/generated/strong_mode_test.dart
index 8557eb0..7f1e8fe 100644
--- a/pkg/analyzer/test/generated/strong_mode_test.dart
+++ b/pkg/analyzer/test/generated/strong_mode_test.dart
@@ -9,7 +9,6 @@
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/nullability_suffix.dart';
 import 'package:analyzer/dart/element/type.dart';
-import 'package:analyzer/src/dart/analysis/driver.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer/src/generated/engine.dart';
@@ -2700,12 +2699,8 @@
     for (ExpressionStatement stmt in stmts) {
       MethodInvocation invoke = stmt.expression;
       FunctionType fType = invoke.staticInvokeType;
-      if (AnalysisDriver.useSummary2) {
-        expect('$fType',
-            'void Function(T Function(T), int Function(T, T), T Function(T))');
-      } else {
-        expect(fType.typeArguments[0].toString(), 'T');
-      }
+      expect('$fType',
+          'void Function(T Function(T), int Function(T, T), T Function(T))');
     }
   }
 
@@ -2732,11 +2727,7 @@
     for (ExpressionStatement stmt in stmts) {
       MethodInvocation invoke = stmt.expression;
       FunctionType fType = invoke.staticInvokeType;
-      if (AnalysisDriver.useSummary2) {
-        expect('$fType', 'void Function(List<T>, int Function(T, T), List<T>)');
-      } else {
-        expect(fType.typeArguments[0].toString(), 'T');
-      }
+      expect('$fType', 'void Function(List<T>, int Function(T, T), List<T>)');
     }
   }
 
@@ -2763,11 +2754,7 @@
     for (ExpressionStatement stmt in stmts) {
       MethodInvocation invoke = stmt.expression;
       FunctionType fType = invoke.staticInvokeType;
-      if (AnalysisDriver.useSummary2) {
-        expect('$fType', 'void Function(T, int Function(T, T), T)');
-      } else {
-        expect(fType.typeArguments[0].toString(), 'T');
-      }
+      expect('$fType', 'void Function(T, int Function(T, T), T)');
     }
   }
 
@@ -4218,9 +4205,6 @@
   }
 
   test_genericFunction_parameter() async {
-    // TODO(paulberry): remove when dartbug.com/28515 fixed.
-    if (!AnalysisDriver.useSummary2) return;
-
     await assertNoErrorsInCode(r'''
 void g(T f<T>(T x)) {}
 ''');
@@ -4385,9 +4369,6 @@
   }
 
   test_genericMethod_functionExpressionInvocation_functionTypedParameter_explicit() async {
-    // TODO(paulberry): remove when dartbug.com/28515 fixed.
-    if (!AnalysisDriver.useSummary2) return;
-
     await assertNoErrorsInCode(r'''
 void test<S>(T pf<T>(T e)) {
   var paramCall = (pf)<int>(3);
@@ -4397,9 +4378,6 @@
   }
 
   test_genericMethod_functionExpressionInvocation_functionTypedParameter_inferred() async {
-    // TODO(paulberry): remove when dartbug.com/28515 fixed.
-    if (!AnalysisDriver.useSummary2) return;
-
     await assertNoErrorsInCode(r'''
 void test<S>(T pf<T>(T e)) {
   var paramCall = (pf)(3);
@@ -4409,9 +4387,6 @@
   }
 
   test_genericMethod_functionExpressionInvocation_inferred() async {
-    // TODO(paulberry): remove when dartbug.com/28515 fixed.
-    if (!AnalysisDriver.useSummary2) return;
-
     await assertNoErrorsInCode(r'''
 class C<E> {
   T f<T>(T e) => null;
@@ -4477,9 +4452,6 @@
   }
 
   test_genericMethod_functionInvocation_functionTypedParameter_explicit() async {
-    // TODO(paulberry): remove when dartbug.com/28515 fixed.
-    if (!AnalysisDriver.useSummary2) return;
-
     await assertNoErrorsInCode(r'''
 void test<S>(T pf<T>(T e)) {
   var paramCall = pf<int>(3);
@@ -4489,9 +4461,6 @@
   }
 
   test_genericMethod_functionInvocation_functionTypedParameter_inferred() async {
-    // TODO(paulberry): remove when dartbug.com/28515 fixed.
-    if (!AnalysisDriver.useSummary2) return;
-
     await assertNoErrorsInCode(r'''
 void test<S>(T pf<T>(T e)) {
   var paramCall = pf(3);
@@ -4554,9 +4523,6 @@
   }
 
   test_genericMethod_functionTypedParameter_tearoff() async {
-    // TODO(paulberry): remove when dartbug.com/28515 fixed.
-    if (!AnalysisDriver.useSummary2) return;
-
     await assertNoErrorsInCode(r'''
 void test<S>(T pf<T>(T e)) {
   var paramTearOff = pf;
diff --git a/pkg/analyzer/test/generated/test_all.dart b/pkg/analyzer/test/generated/test_all.dart
index f4d11a7..8f0cb6f 100644
--- a/pkg/analyzer/test/generated/test_all.dart
+++ b/pkg/analyzer/test/generated/test_all.dart
@@ -16,6 +16,7 @@
 import 'error_suppression_test.dart' as error_suppression;
 import 'inheritance_manager_test.dart' as inheritance_manager_test;
 import 'invalid_code_test.dart' as invalid_code;
+import 'issues_test.dart' as issues;
 import 'java_core_test.dart' as java_core_test;
 import 'java_io_test.dart' as java_io_test;
 import 'non_error_resolver_test.dart' as non_error_resolver;
@@ -47,6 +48,7 @@
     error_suppression.main();
     inheritance_manager_test.main();
     invalid_code.main();
+    issues.main();
     java_core_test.main();
     java_io_test.main();
     non_error_resolver.main();
diff --git a/pkg/analyzer/test/generated/utilities_test.dart b/pkg/analyzer/test/generated/utilities_test.dart
index d5f31a8..b1a5532 100644
--- a/pkg/analyzer/test/generated/utilities_test.dart
+++ b/pkg/analyzer/test/generated/utilities_test.dart
@@ -3659,6 +3659,7 @@
   void test_equals() {
     SourceRange r = new SourceRange(10, 1);
     expect(r == null, isFalse);
+    // ignore: unrelated_type_equality_checks
     expect(r == this, isFalse);
     expect(r == new SourceRange(20, 2), isFalse);
     expect(r == new SourceRange(10, 1), isTrue);
diff --git a/pkg/analyzer/test/id_tests/constant_test.dart b/pkg/analyzer/test/id_tests/constant_test.dart
index d2d5509..bf88745 100644
--- a/pkg/analyzer/test/id_tests/constant_test.dart
+++ b/pkg/analyzer/test/id_tests/constant_test.dart
@@ -88,7 +88,7 @@
       }
     } else if (type is FunctionType) {
       var element = value.toFunctionValue();
-      return 'Function(${element.name})';
+      return 'Function(${element.name},type=${value.type})';
     }
     throw UnimplementedError('_stringify for type $type');
   }
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 35828ff..8746dc1 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
@@ -10,7 +10,6 @@
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/nullability_suffix.dart';
 import 'package:analyzer/dart/element/type.dart';
-import 'package:analyzer/src/dart/analysis/driver.dart';
 import 'package:analyzer/src/dart/analysis/experiments.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/member.dart';
@@ -4784,11 +4783,6 @@
     var gType = findNode.typeName('Consumer<T>');
     var gTypeType = gType.type as FunctionType;
 
-    if (!AnalysisDriver.useSummary2) {
-      var gTypeTypeArgument = gTypeType.typeArguments[0] as TypeParameterType;
-      expect(gTypeTypeArgument.element, same(tElement));
-    }
-
     var gTypeParameterType =
         gTypeType.namedParameterTypes['u'] as TypeParameterType;
     expect(gTypeParameterType.element, same(tElement));
@@ -4817,11 +4811,6 @@
     var gType = findNode.typeName('Consumer<T>');
     var gTypeType = gType.type as FunctionType;
 
-    if (!AnalysisDriver.useSummary2) {
-      var gTypeTypeArgument = gTypeType.typeArguments[0] as TypeParameterType;
-      expect(gTypeTypeArgument.element, same(tElement));
-    }
-
     var gTypeParameterType =
         gTypeType.normalParameterTypes[0] as TypeParameterType;
     expect(gTypeParameterType.element, same(tElement));
@@ -4850,11 +4839,6 @@
     var gType = findNode.typeName('Consumer<T>');
     var gTypeType = gType.type as FunctionType;
 
-    if (!AnalysisDriver.useSummary2) {
-      var gTypeTypeArgument = gTypeType.typeArguments[0] as TypeParameterType;
-      expect(gTypeTypeArgument.element, same(tElement));
-    }
-
     var gTypeParameterType =
         gTypeType.optionalParameterTypes[0] as TypeParameterType;
     expect(gTypeParameterType.element, same(tElement));
@@ -4883,11 +4867,6 @@
     var gType = findNode.typeName('Producer<T>');
     var gTypeType = gType.type as FunctionType;
 
-    if (!AnalysisDriver.useSummary2) {
-      var gTypeTypeArgument = gTypeType.typeArguments[0] as TypeParameterType;
-      expect(gTypeTypeArgument.element, same(tElement));
-    }
-
     var gTypeReturnType = gTypeType.returnType as TypeParameterType;
     expect(gTypeReturnType.element, same(tElement));
 
@@ -5453,8 +5432,7 @@
   }
 
   test_methodInvocation_instanceMethod_genericClass_genericMethod() async {
-    try {
-      addTestFile(r'''
+    addTestFile(r'''
 main() {
   new C<int>().m(1, 2.3);
 }
@@ -5462,41 +5440,22 @@
   Map<T, U> m<U>(T a, U b) => null;
 }
 ''');
-      await resolveTestFile();
-      MethodElement mElement = findElement.method('m');
+    await resolveTestFile();
+    MethodElement mElement = findElement.method('m');
 
-      {
-        var invocation = findNode.methodInvocation('m(1, 2.3)');
-        List<Expression> arguments = invocation.argumentList.arguments;
+    {
+      var invocation = findNode.methodInvocation('m(1, 2.3)');
+      List<Expression> arguments = invocation.argumentList.arguments;
 
-        var invokeTypeStr = 'Map<int, double> Function(int, double)';
-        assertType(invocation, 'Map<int, double>');
-        assertInvokeType(invocation, invokeTypeStr);
+      var invokeTypeStr = 'Map<int, double> Function(int, double)';
+      assertType(invocation, 'Map<int, double>');
+      assertInvokeType(invocation, invokeTypeStr);
 
-        assertMember(invocation.methodName, mElement, {'T': 'int'});
-        assertType(invocation.methodName, 'Map<int, U> Function<U>(int, U)');
+      assertMember(invocation.methodName, mElement, {'T': 'int'});
+      assertType(invocation.methodName, 'Map<int, U> Function<U>(int, U)');
 
-        if (AnalysisDriver.useSummary2) {
-          _assertArgumentToParameter2(arguments[0], 'int');
-          _assertArgumentToParameter2(arguments[1], 'double');
-        } else {
-          _assertArgumentToParameter(arguments[0], mElement.parameters[0]);
-          _assertArgumentToParameter(arguments[1], mElement.parameters[1]);
-        }
-      }
-      if (!AnalysisDriver.useSummary2) {
-        throw 'Test passed - expected to fail.';
-      }
-    } on String {
-      rethrow;
-    } catch (_) {
-      // This test started failing in summary1, because we assign
-      // corresponding parameter elements from FunctionType, which became
-      // structural, and does not know its element anymore.
-      // We should fix this up by using MethodMember parameters instead.
-      if (AnalysisDriver.useSummary2) {
-        rethrow;
-      }
+      _assertArgumentToParameter2(arguments[0], 'int');
+      _assertArgumentToParameter2(arguments[1], 'double');
     }
   }
 
@@ -5597,9 +5556,6 @@
 ''');
     await resolveTestFile();
 
-    FunctionTypeAlias funDeclaration = result.unit.declarations[0];
-    FunctionTypeAliasElement funElement = funDeclaration.declaredElement;
-
     ClassDeclaration cDeclaration = result.unit.declarations[1];
 
     MethodDeclaration fDeclaration = cDeclaration.members[0];
@@ -5617,13 +5573,8 @@
     expect(invocation.staticType, typeProvider.stringType);
 
     List<Expression> arguments = invocation.argumentList.arguments;
-    if (AnalysisDriver.useSummary2) {
-      _assertArgumentToParameter2(arguments[0], 'int');
-      _assertArgumentToParameter2(arguments[1], 'int');
-    } else {
-      _assertArgumentToParameter(arguments[0], funElement.parameters[0]);
-      _assertArgumentToParameter(arguments[1], funElement.parameters[1]);
-    }
+    _assertArgumentToParameter2(arguments[0], 'int');
+    _assertArgumentToParameter2(arguments[1], 'int');
   }
 
   test_methodInvocation_notFunction_local_dynamic() async {
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
index ef0509e..276fc93 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
@@ -23,7 +23,6 @@
 import 'package:analyzer/src/generated/sdk.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/summary/idl.dart';
-import 'package:analyzer/src/summary/package_bundle_reader.dart';
 import 'package:analyzer/src/test_utilities/mock_sdk.dart';
 import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
 import 'package:test/test.dart';
@@ -37,9 +36,6 @@
   defineReflectiveSuite(() {
     defineReflectiveTests(AnalysisDriverSchedulerTest);
     defineReflectiveTests(AnalysisDriverTest);
-    if (!AnalysisDriver.useSummary2) {
-      defineReflectiveTests(AnalysisDriverSummary1Test);
-    }
     defineReflectiveTests(CacheAllAnalysisDriverTest);
   });
 }
@@ -346,374 +342,6 @@
   }
 }
 
-/// TODO(paulberry): migrate this test away from the task model.
-/// See dartbug.com/35734.
-@reflectiveTest
-class AnalysisDriverSummary1Test extends BaseAnalysisDriverTest {
-  test_externalSummaries() async {
-    var a = convertPath('/a.dart');
-    var b = convertPath('/b.dart');
-    newFile(a, content: r'''
-class A {}
-''');
-    newFile(b, content: r'''
-import 'a.dart';
-var a = new A();
-''');
-
-    // Prepare the store with a.dart and everything it needs.
-    SummaryDataStore summaryStore =
-        await createAnalysisDriver().test.getSummaryStore(a);
-
-    // There are at least a.dart and dart:core libraries.
-    String aUri = toUriStr(a);
-    expect(summaryStore.unlinkedMap.keys, contains(aUri));
-    expect(summaryStore.linkedMap.keys, contains(aUri));
-    expect(summaryStore.unlinkedMap.keys, contains('dart:core'));
-    expect(summaryStore.linkedMap.keys, contains('dart:core'));
-
-    // Remove a.dart from the file system.
-    deleteFile(a);
-
-    // We don't need a.dart file when we analyze with the summary store.
-    // Still no analysis errors.
-    AnalysisDriver driver =
-        createAnalysisDriver(externalSummaries: summaryStore);
-    ResolvedUnitResult result = await driver.getResult(b);
-    expect(result.errors, isEmpty);
-  }
-
-  test_externalSummaries_partReuse() async {
-    var a = convertPath('/a.dart');
-    var b = convertPath('/b.dart');
-    var c = convertPath('/c.dart');
-    newFile(a, content: r'''
-library a;
-part 'b.dart';
-class A {}
-''');
-    newFile(b, content: r'''
-part of a;
-class _B {}
-''');
-    newFile(c, content: r'''
-library a;
-import 'a.dart';
-part 'b.dart';
-var a = new A();
-var b = new _B();
-''');
-
-    // Prepare the store with a.dart and everything it needs.
-    SummaryDataStore summaryStore =
-        await createAnalysisDriver().test.getSummaryStore(a);
-
-    String aUri = toUriStr(a);
-    String bUri = toUriStr(b);
-    // There are unlinked units for a.dart and b.dart files.
-    expect(summaryStore.hasUnlinkedUnit(aUri), isTrue);
-    expect(summaryStore.hasUnlinkedUnit(bUri), isTrue);
-    // Only a.dart is linked, because b.dart is not a library.
-    expect(summaryStore.hasLinkedLibrary(aUri), isTrue);
-    expect(summaryStore.hasLinkedLibrary(bUri), isFalse);
-
-    // Remove a.dart from the file system.
-    // Keep b.dart, because we (re)use it as a part.
-    deleteFile(a);
-
-    // We don't need a.dart file when we analyze with the summary store.
-    // We can instantiate the class A the library a.dart.
-    // We can instantiate the class _A the part b.dart.
-    AnalysisDriver driver =
-        createAnalysisDriver(externalSummaries: summaryStore);
-    ResolvedUnitResult result = await driver.getResult(c);
-    expect(result.errors, isEmpty);
-  }
-
-  test_getLibraryByUri_external() async {
-    var a = convertPath('/test/lib/a.dart');
-    var b = convertPath('/test/lib/b.dart');
-
-    String aUriStr = 'package:test/a.dart';
-    String bUriStr = 'package:test/b.dart';
-
-    newFile(a, content: r'''
-part 'b.dart';
-
-class A {}
-''');
-
-    newFile(b, content: r'''
-part of 'a.dart';
-
-class B {}
-''');
-
-    // Prepare the store with package:test/test.dart URI.
-    var store = await createAnalysisDriver().test.getSummaryStore(a);
-
-    // package:test/test.dart is in the store.
-    expect(store.unlinkedMap.keys, contains(aUriStr));
-    expect(store.unlinkedMap.keys, contains(bUriStr));
-    expect(store.linkedMap.keys, contains(aUriStr));
-    expect(store.linkedMap.keys, isNot(contains(bUriStr)));
-
-    // Remove the files from the file system.
-    deleteFile(a);
-    deleteFile(b);
-
-    // We can resynthesize the library from the store.
-    var driver = createAnalysisDriver(externalSummaries: store);
-
-    // Ask by URI, so we get the "external" FileState.
-    var aUri = Uri.parse(aUriStr);
-    var aFile = driver.fsState.getFileForUri(aUri);
-    expect(aFile.uri, aUri);
-    expect(aFile.path, isNull);
-
-    // We still can resynthesize the library.
-    // The URI is known to be external, so we don't talk to the file.
-    var library = await driver.getLibraryByUri(aUriStr);
-    expect(library.getType('A'), isNotNull);
-    expect(library.getType('B'), isNotNull);
-
-    // It is an error to ask for a library when we know that it is a part.
-    expect(() async {
-      await driver.getLibraryByUri(bUriStr);
-    }, throwsArgumentError);
-  }
-
-  test_getLibraryByUri_sdk_analyze() async {
-    LibraryElement coreLibrary = await driver.getLibraryByUri('dart:core');
-    expect(coreLibrary, isNotNull);
-    expect(coreLibrary.getType('Object'), isNotNull);
-    expect(coreLibrary.getType('int'), isNotNull);
-  }
-
-  test_getLibraryByUri_sdk_resynthesize() async {
-    String corePath = sdk.mapDartUri('dart:core').fullName;
-    String asyncPath = sdk.mapDartUri('dart:async').fullName;
-    var sdkStore = await createAnalysisDriver().test.getSummaryStore(corePath);
-
-    // There are dart:core and dart:async in the store.
-    expect(sdkStore.unlinkedMap.keys, contains('dart:core'));
-    expect(sdkStore.unlinkedMap.keys, contains('dart:async'));
-    expect(sdkStore.linkedMap.keys, contains('dart:core'));
-    expect(sdkStore.linkedMap.keys, contains('dart:async'));
-
-    // Remove dart:core and dart:async.
-    // So, the new driver below cannot parse and summarize them.
-    deleteFile(corePath);
-    deleteFile(asyncPath);
-
-    // We still get get dart:core library element.
-    AnalysisDriver driver = createAnalysisDriver(externalSummaries: sdkStore);
-    LibraryElement coreLibrary = await driver.getLibraryByUri('dart:core');
-    expect(coreLibrary, isNotNull);
-    expect(coreLibrary.getType('Object'), isNotNull);
-  }
-
-  test_getParsedLibrary_external() async {
-    var a1 = convertPath('/aaa/lib/a1.dart');
-    var a2 = convertPath('/aaa/lib/a2.dart');
-
-    var a1UriStr = 'package:aaa/a1.dart';
-    var a2UriStr = 'package:aaa/a2.dart';
-
-    newFile(a1, content: "part 'a2.dart';  class A {}");
-    newFile(a2, content: "part of 'a1.dart';");
-
-    // Build the store with the library.
-    var store = await createAnalysisDriver().test.getSummaryStore(a1);
-    expect(store.unlinkedMap.keys, contains(a1UriStr));
-    expect(store.unlinkedMap.keys, contains(a2UriStr));
-    expect(store.linkedMap.keys, contains(a1UriStr));
-
-    var driver = createAnalysisDriver(externalSummaries: store);
-    var libraryElement = await driver.getLibraryByUri(a1UriStr);
-    var classA = libraryElement.library.getType('A');
-
-    var parsedLibrary = driver.getParsedLibrary(a1);
-    expect(parsedLibrary, isNotNull);
-    expect(parsedLibrary.state, ResultState.NOT_A_FILE);
-    expect(() {
-      parsedLibrary.getElementDeclaration(classA);
-    }, throwsStateError);
-
-    // It is an error to ask for a library when we know that it is a part.
-    expect(() {
-      driver.getParsedLibrary(a2);
-    }, throwsArgumentError);
-  }
-
-  test_getParsedLibraryByUri_external() async {
-    var a1 = convertPath('/aaa/lib/a1.dart');
-    var a2 = convertPath('/aaa/lib/a2.dart');
-
-    var a1UriStr = 'package:aaa/a1.dart';
-    var a2UriStr = 'package:aaa/a2.dart';
-
-    var a1Uri = Uri.parse(a1UriStr);
-    var a2Uri = Uri.parse(a2UriStr);
-
-    newFile(a1, content: "part 'a2.dart';  class A {}");
-    newFile(a2, content: "part of 'a1.dart';");
-
-    // Build the store with the library.
-    var store = await createAnalysisDriver().test.getSummaryStore(a1);
-    expect(store.unlinkedMap.keys, contains(a1UriStr));
-    expect(store.unlinkedMap.keys, contains(a2UriStr));
-    expect(store.linkedMap.keys, contains(a1UriStr));
-
-    var driver = createAnalysisDriver(externalSummaries: store);
-    var libraryElement = await driver.getLibraryByUri(a1UriStr);
-    var classA = libraryElement.library.getType('A');
-
-    {
-      var parsedLibrary = driver.getParsedLibraryByUri(a1Uri);
-      expect(parsedLibrary, isNotNull);
-      expect(parsedLibrary.state, ResultState.NOT_A_FILE);
-      expect(() {
-        parsedLibrary.getElementDeclaration(classA);
-      }, throwsStateError);
-    }
-
-    // We can also get the result from the session.
-    {
-      var session = driver.currentSession;
-      var parsedLibrary = session.getParsedLibraryByElement(libraryElement);
-      expect(parsedLibrary, isNotNull);
-      expect(parsedLibrary.state, ResultState.NOT_A_FILE);
-      expect(() {
-        parsedLibrary.getElementDeclaration(classA);
-      }, throwsStateError);
-    }
-
-    // It is an error to ask for a library when we know that it is a part.
-    expect(() {
-      driver.getParsedLibraryByUri(a2Uri);
-    }, throwsArgumentError);
-  }
-
-  test_getResolvedLibrary_external() async {
-    var a1 = convertPath('/aaa/lib/a1.dart');
-    var a2 = convertPath('/aaa/lib/a2.dart');
-
-    var a1UriStr = 'package:aaa/a1.dart';
-    var a2UriStr = 'package:aaa/a2.dart';
-
-    newFile(a1, content: "part 'a2.dart';  class A {}");
-    newFile(a2, content: "part of 'a1.dart';");
-
-    // Build the store with the library.
-    var store = await createAnalysisDriver().test.getSummaryStore(a1);
-    expect(store.unlinkedMap.keys, contains(a1UriStr));
-    expect(store.unlinkedMap.keys, contains(a2UriStr));
-    expect(store.linkedMap.keys, contains(a1UriStr));
-
-    var driver = createAnalysisDriver(externalSummaries: store);
-    var libraryElement = await driver.getLibraryByUri(a1UriStr);
-    var classA = libraryElement.library.getType('A');
-
-    var resolvedLibrary = await driver.getResolvedLibrary(a1);
-    expect(resolvedLibrary, isNotNull);
-    expect(resolvedLibrary.state, ResultState.NOT_A_FILE);
-    expect(() {
-      resolvedLibrary.getElementDeclaration(classA);
-    }, throwsStateError);
-
-    // It is an error to ask for a library when we know that it is a part.
-    expect(() async {
-      await driver.getResolvedLibrary(a2);
-    }, throwsArgumentError);
-  }
-
-  test_getResolvedLibraryByUri_external() async {
-    var a1 = convertPath('/aaa/lib/a1.dart');
-    var a2 = convertPath('/aaa/lib/a2.dart');
-
-    var a1UriStr = 'package:aaa/a1.dart';
-    var a2UriStr = 'package:aaa/a2.dart';
-
-    var a1Uri = Uri.parse(a1UriStr);
-    var a2Uri = Uri.parse(a2UriStr);
-
-    newFile(a1, content: "part 'a2.dart';  class A {}");
-    newFile(a2, content: "part of 'a1.dart';");
-
-    // Build the store with the library.
-    var store = await createAnalysisDriver().test.getSummaryStore(a1);
-    expect(store.unlinkedMap.keys, contains(a1UriStr));
-    expect(store.unlinkedMap.keys, contains(a2UriStr));
-    expect(store.linkedMap.keys, contains(a1UriStr));
-
-    var driver = createAnalysisDriver(externalSummaries: store);
-    var libraryElement = await driver.getLibraryByUri(a1UriStr);
-    var classA = libraryElement.library.getType('A');
-
-    {
-      var resolvedLibrary = await driver.getResolvedLibraryByUri(a1Uri);
-      expect(resolvedLibrary, isNotNull);
-      expect(resolvedLibrary.state, ResultState.NOT_A_FILE);
-      expect(() {
-        resolvedLibrary.getElementDeclaration(classA);
-      }, throwsStateError);
-    }
-
-    // We can also get the result from the session.
-    {
-      var session = driver.currentSession;
-      var resolvedLibrary =
-          await session.getResolvedLibraryByElement(libraryElement);
-      expect(resolvedLibrary, isNotNull);
-      expect(resolvedLibrary.state, ResultState.NOT_A_FILE);
-      expect(() {
-        resolvedLibrary.getElementDeclaration(classA);
-      }, throwsStateError);
-    }
-
-    // It is an error to ask for a library when we know that it is a part.
-    expect(() async {
-      await driver.getResolvedLibraryByUri(a2Uri);
-    }, throwsArgumentError);
-  }
-
-  test_isLibraryByUri() async {
-    var a1 = '/aaa/lib/a1.dart';
-    var a2 = '/aaa/lib/a2.dart';
-    var b1 = '/bbb/lib/b1.dart';
-    var b2 = '/bbb/lib/b2.dart';
-
-    String a1UriStr = 'package:aaa/a1.dart';
-    String a2UriStr = 'package:aaa/a2.dart';
-    String b1UriStr = 'package:bbb/b1.dart';
-    String b2UriStr = 'package:bbb/b2.dart';
-
-    newFile(a1, content: "part 'a2.dart';");
-    newFile(a2, content: "part of 'a1.dart';");
-    newFile(b1, content: "part 'b2.dart';");
-    newFile(b2, content: "part of 'b1.dart';");
-
-    // Build the store with the library.
-    var store =
-        await createAnalysisDriver().test.getSummaryStore(convertPath(a1));
-    expect(store.unlinkedMap.keys, contains(a1UriStr));
-    expect(store.unlinkedMap.keys, contains(a2UriStr));
-    expect(store.linkedMap.keys, contains(a1UriStr));
-
-    // Remove the stored files from the file system.
-    deleteFile(a1);
-    deleteFile(a2);
-
-    // We can ask isLibraryByUri() for both external and local units.
-    AnalysisDriver driver = createAnalysisDriver(externalSummaries: store);
-    expect(driver.isLibraryByUri(Uri.parse(a1UriStr)), isTrue);
-    expect(driver.isLibraryByUri(Uri.parse(a2UriStr)), isFalse);
-    expect(driver.isLibraryByUri(Uri.parse(b1UriStr)), isTrue);
-    expect(driver.isLibraryByUri(Uri.parse(b2UriStr)), isFalse);
-  }
-}
-
 @reflectiveTest
 class AnalysisDriverTest extends BaseAnalysisDriverTest {
   test_addedFiles() async {
diff --git a/pkg/analyzer/test/src/dart/analysis/file_state_test.dart b/pkg/analyzer/test/src/dart/analysis/file_state_test.dart
index af25455..c0c347e 100644
--- a/pkg/analyzer/test/src/dart/analysis/file_state_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/file_state_test.dart
@@ -7,7 +7,6 @@
 
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/src/dart/analysis/byte_store.dart';
-import 'package:analyzer/src/dart/analysis/driver.dart';
 import 'package:analyzer/src/dart/analysis/file_state.dart';
 import 'package:analyzer/src/dart/analysis/library_graph.dart';
 import 'package:analyzer/src/dart/analysis/performance_logger.dart';
@@ -119,13 +118,8 @@
     expect(_excludeSdk(file.directReferencedFiles), isEmpty);
     expect(file.isPart, isFalse);
     expect(file.library, isNull);
-    if (AnalysisDriver.useSummary2) {
-      expect(file.unlinked2, isNotNull);
-      expect(file.unlinked2.exports, isEmpty);
-    } else {
-      expect(file.unlinked, isNotNull);
-      expect(file.unlinked.classes, isEmpty);
-    }
+    expect(file.unlinked2, isNotNull);
+    expect(file.unlinked2.exports, isEmpty);
   }
 
   test_getFileForPath_emptyUri() {
@@ -215,13 +209,7 @@
 
     expect(file.isPart, isFalse);
     expect(file.library, isNull);
-    if (AnalysisDriver.useSummary2) {
-      expect(file.unlinked2, isNotNull);
-    } else {
-      expect(file.unlinked, isNotNull);
-      expect(file.unlinked.classes, hasLength(1));
-      expect(file.unlinked.classes[0].name, 'A1');
-    }
+    expect(file.unlinked2, isNotNull);
 
     expect(_excludeSdk(file.importedFiles), hasLength(2));
     expect(file.importedFiles[0].path, a2);
@@ -292,13 +280,7 @@
     expect(file_a2.path, a2);
     expect(file_a2.uri, Uri.parse('package:aaa/a2.dart'));
 
-    if (AnalysisDriver.useSummary2) {
-      expect(file_a2.unlinked2, isNotNull);
-    } else {
-      expect(file_a2.unlinked, isNotNull);
-      expect(file_a2.unlinked.classes, hasLength(1));
-      expect(file_a2.unlinked.classes[0].name, 'A2');
-    }
+    expect(file_a2.unlinked2, isNotNull);
 
     expect(_excludeSdk(file_a2.importedFiles), isEmpty);
     expect(file_a2.exportedFiles, isEmpty);
@@ -515,11 +497,7 @@
 class A {}
 ''');
     FileState file = fileSystemState.getFileForPath(path);
-    if (AnalysisDriver.useSummary2) {
-      expect(file.definedTopLevelNames, contains('A'));
-    } else {
-      expect(file.unlinked.classes[0].name, 'A');
-    }
+    expect(file.definedTopLevelNames, contains('A'));
     List<int> signature = file.apiSignature;
 
     // Update the resource and refresh the file state.
@@ -529,11 +507,7 @@
     bool apiSignatureChanged = file.refresh();
     expect(apiSignatureChanged, isTrue);
 
-    if (AnalysisDriver.useSummary2) {
-      expect(file.definedTopLevelNames, contains('B'));
-    } else {
-      expect(file.unlinked.classes[0].name, 'B');
-    }
+    expect(file.definedTopLevelNames, contains('B'));
     expect(file.apiSignature, isNot(signature));
   }
 
@@ -569,22 +543,14 @@
 
     // Get the file, prepare unlinked.
     FileState file = fileSystemState.getFileForPath(path);
-    if (AnalysisDriver.useSummary2) {
-      expect(file.unlinked2, isNotNull);
-    } else {
-      expect(file.unlinked, isNotNull);
-    }
+    expect(file.unlinked2, isNotNull);
 
     // Make the unlinked unit in the byte store zero-length, damaged.
     byteStore.put(file.test.unlinkedKey, <int>[]);
 
     // Refresh should not fail, zero bytes in the store are ignored.
     file.refresh();
-    if (AnalysisDriver.useSummary2) {
-      expect(file.unlinked2, isNotNull);
-    } else {
-      expect(file.unlinked, isNotNull);
-    }
+    expect(file.unlinked2, isNotNull);
   }
 
   test_subtypedNames() {
diff --git a/pkg/analyzer/test/src/dart/element/element_test.dart b/pkg/analyzer/test/src/dart/element/element_test.dart
index f0489be..9d5b46d 100644
--- a/pkg/analyzer/test/src/dart/element/element_test.dart
+++ b/pkg/analyzer/test/src/dart/element/element_test.dart
@@ -959,7 +959,9 @@
     );
     classElement.fields = <FieldElement>[field];
     expect(field == field, isTrue);
+    // ignore: unrelated_type_equality_checks
     expect(field == field.getter, isFalse);
+    // ignore: unrelated_type_equality_checks
     expect(field == field.setter, isFalse);
     expect(field.getter == field.setter, isFalse);
   }
@@ -1077,6 +1079,7 @@
 
   void test_equals_notEqual_notLocation() {
     ElementLocationImpl first = new ElementLocationImpl.con2("a;b;c");
+    // ignore: unrelated_type_equality_checks
     expect(first == "a;b;d", isFalse);
   }
 
@@ -3529,7 +3532,9 @@
     PropertyAccessorElementHandle handle =
         new PropertyAccessorElementHandle(null, element.location);
     expect(element.hashCode, handle.hashCode);
+    // ignore: unrelated_type_equality_checks
     expect(element == handle, isTrue);
+    // ignore: unrelated_type_equality_checks
     expect(handle == element, isTrue);
   }
 
@@ -3544,7 +3549,9 @@
     PropertyAccessorElementHandle handle =
         new PropertyAccessorElementHandle(null, element.location);
     expect(element.hashCode, handle.hashCode);
+    // ignore: unrelated_type_equality_checks
     expect(element == handle, isTrue);
+    // ignore: unrelated_type_equality_checks
     expect(handle == element, isTrue);
   }
 }
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 17352e4..c364469 100644
--- a/pkg/analyzer/test/src/dart/element/type_algebra_test.dart
+++ b/pkg/analyzer/test/src/dart/element/type_algebra_test.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/nullability_suffix.dart';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/type_algebra.dart';
@@ -20,6 +21,7 @@
     defineReflectiveTests(SubstituteFromPairsTest);
     defineReflectiveTests(SubstituteFromUpperAndLowerBoundsTest);
     defineReflectiveTests(SubstituteTest);
+    defineReflectiveTests(SubstituteWithNullabilityTest);
   });
 }
 
@@ -276,19 +278,57 @@
     var result = substitute(type, substitution);
     expect(result, same(type));
   }
+}
 
-  void _assertSubstitution(
-    DartType type,
-    Map<TypeParameterElement, DartType> substitution,
-    String expected,
-  ) {
-    var result = substitute(type, substitution);
-    assertElementTypeString(result, expected);
+@reflectiveTest
+class SubstituteWithNullabilityTest extends _Base {
+  SubstituteWithNullabilityTest() : super(useNnbd: true);
+
+  test_interface_none() async {
+    // class A<T> {}
+    var T = typeParameter('T');
+    var A = class_(name: 'A', typeParameters: [T]);
+
+    var U = typeParameter('U');
+    var type = interfaceType(A,
+        typeArguments: [typeParameterType(U)],
+        nullabilitySuffix: NullabilitySuffix.none);
+    _assertSubstitution(type, {U: intType}, 'A<int>');
+  }
+
+  test_interface_question() async {
+    // class A<T> {}
+    var T = typeParameter('T');
+    var A = class_(name: 'A', typeParameters: [T]);
+
+    var U = typeParameter('U');
+    var type = interfaceType(A,
+        typeArguments: [typeParameterType(U)],
+        nullabilitySuffix: NullabilitySuffix.question);
+    _assertSubstitution(type, {U: intType}, 'A<int>?');
+  }
+
+  test_interface_star() async {
+    // class A<T> {}
+    var T = typeParameter('T');
+    var A = class_(name: 'A', typeParameters: [T]);
+
+    var U = typeParameter('U');
+    var type = interfaceType(A,
+        typeArguments: [typeParameterType(U)],
+        nullabilitySuffix: NullabilitySuffix.star);
+    _assertSubstitution(type, {U: intType}, 'A<int>*');
   }
 }
 
 class _Base with ElementsTypesMixin {
-  final typeProvider = TestTypeProvider();
+  final TestTypeProvider typeProvider;
+
+  final bool useNnbd;
+
+  _Base({this.useNnbd = false})
+      : typeProvider = TestTypeProvider(null, null,
+            useNnbd ? NullabilitySuffix.none : NullabilitySuffix.question);
 
   InterfaceType get boolType => typeProvider.boolType;
 
@@ -297,11 +337,20 @@
   InterfaceType get intType => typeProvider.intType;
 
   /// Whether `DartType.toString()` with nullability should be asked.
-  bool get typeToStringWithNullability => false;
+  bool get typeToStringWithNullability => useNnbd;
 
   void assertElementTypeString(DartType type, String expected) {
     TypeImpl typeImpl = type;
     expect(typeImpl.toString(withNullability: typeToStringWithNullability),
         expected);
   }
+
+  void _assertSubstitution(
+    DartType type,
+    Map<TypeParameterElement, DartType> substitution,
+    String expected,
+  ) {
+    var result = substitute(type, substitution);
+    assertElementTypeString(result, expected);
+  }
 }
diff --git a/pkg/analyzer/test/src/dart/resolution/optional_const_test.dart b/pkg/analyzer/test/src/dart/resolution/optional_const_test.dart
index 5fbe1d7..cdb8590 100644
--- a/pkg/analyzer/test/src/dart/resolution/optional_const_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/optional_const_test.dart
@@ -3,11 +3,8 @@
 // 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/src/dart/analysis/driver.dart';
 import 'package:analyzer/src/dart/element/element.dart';
-import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'driver_resolution.dart';
@@ -164,12 +161,8 @@
   }
 
   ImportElement _importOfA() {
-    if (AnalysisDriver.useSummary2) {
-      var importOfB = findElement.import('package:test/b.dart');
-      return importOfB.importedLibrary.imports[0];
-    } else {
-      return null;
-    }
+    var importOfB = findElement.import('package:test/b.dart');
+    return importOfB.importedLibrary.imports[0];
   }
 
   Future<InstanceCreationExpression> _resolveImplicitConst(String expr,
@@ -207,10 +200,6 @@
     var v = vg.variable as ConstVariableElement;
 
     InstanceCreationExpression creation = v.constantInitializer;
-    if (!AnalysisDriver.useSummary2) {
-      expect(creation.keyword.keyword, Keyword.CONST);
-    }
-
     return creation;
   }
 }
diff --git a/pkg/analyzer/test/src/diagnostics/inference_failure_on_function_return_type_test.dart b/pkg/analyzer/test/src/diagnostics/inference_failure_on_function_return_type_test.dart
index 263cebb..f8fe9c5 100644
--- a/pkg/analyzer/test/src/diagnostics/inference_failure_on_function_return_type_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/inference_failure_on_function_return_type_test.dart
@@ -60,6 +60,38 @@
 ''', [error(HintCode.INFERENCE_FAILURE_ON_FUNCTION_RETURN_TYPE, 12, 9)]);
   }
 
+  test_classInstanceMethod_overriding() async {
+    await assertNoErrorsInCode(r'''
+class C {
+  int f() => 7;
+}
+
+class D extends C {
+  f() => 9;
+}
+
+class E implements C {
+  f() => 9;
+}
+
+class F with C {
+  f() => 9;
+}
+
+mixin M on C {
+  f() => 9;
+}
+
+mixin N {
+  int g() => 7;
+}
+
+class G with N {
+  g() => 9;
+}
+''');
+  }
+
   test_classInstanceMethod_withReturnType() async {
     await assertNoErrorsInCode(r'''
 class C {
@@ -77,11 +109,11 @@
   }
 
   test_classInstanceSetter() async {
-    await assertErrorsInCode(r'''
+    await assertNoErrorsInCode(r'''
 class C {
   set f(int x) => print(x);
 }
-''', [error(HintCode.INFERENCE_FAILURE_ON_FUNCTION_RETURN_TYPE, 12, 25)]);
+''');
   }
 
   test_classStaticMethod() async {
@@ -124,6 +156,22 @@
 ''');
   }
 
+  test_genericFunctionType() async {
+    await assertErrorsInCode(r'''
+Function(int) f = (int n) {
+  print(n);
+};
+''', [error(HintCode.INFERENCE_FAILURE_ON_FUNCTION_RETURN_TYPE, 0, 13)]);
+  }
+
+  test_genericFunctionType_withReturnType() async {
+    await assertNoErrorsInCode(r'''
+void Function(int) f = (int n) {
+  print(n);
+};
+''');
+  }
+
   test_localFunction() async {
     await assertNoErrorsInCode(r'''
 class C {
@@ -169,4 +217,28 @@
 dynamic f() => 7;
 ''');
   }
+
+  test_typedef_classic() async {
+    await assertErrorsInCode(r'''
+typedef Callback(int i);
+''', [error(HintCode.INFERENCE_FAILURE_ON_FUNCTION_RETURN_TYPE, 0, 24)]);
+  }
+
+  test_typedef_classic_withReturnType() async {
+    await assertNoErrorsInCode(r'''
+typedef void Callback(int i);
+''');
+  }
+
+  test_typedef_modern() async {
+    await assertErrorsInCode(r'''
+typedef Callback = Function(int i);
+''', [error(HintCode.INFERENCE_FAILURE_ON_FUNCTION_RETURN_TYPE, 0, 35)]);
+  }
+
+  test_typedef_modern_withReturnType() async {
+    await assertNoErrorsInCode(r'''
+typedef Callback = void Function(int i);
+''');
+  }
 }
diff --git a/pkg/analyzer/test/src/diagnostics/missing_required_param_test.dart b/pkg/analyzer/test/src/diagnostics/missing_required_param_test.dart
index bbc42ec..de01ca4 100644
--- a/pkg/analyzer/test/src/diagnostics/missing_required_param_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/missing_required_param_test.dart
@@ -3,7 +3,6 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/dart/analysis/features.dart';
-import 'package:analyzer/src/dart/analysis/driver.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/test_utilities/package_mixin.dart';
@@ -165,10 +164,15 @@
     assertTestErrorsWithCodes([HintCode.MISSING_REQUIRED_PARAM_WITH_DETAILS]);
   }
 
+  @FailingTest(reason: r'''
+MISSING_REQUIRED_PARAM cannot be reported here with summary2, because
+the return type of `C.m` is a structural FunctionType, which does
+not know its elements, and does not know that there was a parameter
+marked `@required`. There is exactly one such typedef in Flutter.
+''')
   test_typedef_functionParam() async {
     addMetaPackage();
-    try {
-      await assertErrorsInCode(r'''
+    await assertErrorsInCode(r'''
 import 'package:meta/meta.dart';
 
 String test(C c) => c.m()();
@@ -179,17 +183,8 @@
   F m() => ({@required String x}) => null;
 }
 ''', [
-        error(HintCode.MISSING_REQUIRED_PARAM, 54, 7),
-      ]);
-    } catch (_) {
-      // MISSING_REQUIRED_PARAM cannot be reported here with summary2, because
-      // the return type of `C.m` is a structural FunctionType, which does
-      // not know its elements, and does not know that there was a parameter
-      // marked `@required`. There is exactly one such typedef in Flutter.
-      if (!AnalysisDriver.useSummary2) {
-        rethrow;
-      }
-    }
+      error(HintCode.MISSING_REQUIRED_PARAM, 54, 7),
+    ]);
   }
 
   /// Resolve the test file at [path].
diff --git a/pkg/analyzer/test/src/fasta/recovery/partial_code/forEach_statement_test.dart b/pkg/analyzer/test/src/fasta/recovery/partial_code/for_each_statement_test.dart
similarity index 100%
rename from pkg/analyzer/test/src/fasta/recovery/partial_code/forEach_statement_test.dart
rename to pkg/analyzer/test/src/fasta/recovery/partial_code/for_each_statement_test.dart
diff --git a/pkg/analyzer/test/src/fasta/recovery/partial_code/test_all.dart b/pkg/analyzer/test/src/fasta/recovery/partial_code/test_all.dart
index 0b20072..06c1d0f 100644
--- a/pkg/analyzer/test/src/fasta/recovery/partial_code/test_all.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/partial_code/test_all.dart
@@ -15,7 +15,7 @@
 import 'export_directive_test.dart' as export_directive;
 import 'extension_declaration_test.dart' as extension_declaration;
 import 'field_declaration_test.dart' as field_declaration;
-import 'forEach_statement_test.dart' as forEach_statement;
+import 'for_each_statement_test.dart' as for_each_statement;
 import 'for_statement_test.dart' as for_statement;
 import 'if_statement_test.dart' as if_statement;
 import 'import_directive_test.dart' as import_directive;
@@ -50,7 +50,7 @@
     extension_declaration.main();
     field_declaration.main();
     for_statement.main();
-    forEach_statement.main();
+    for_each_statement.main();
     if_statement.main();
     import_directive.main();
     index_expression.main();
diff --git a/pkg/analyzer/test/src/summary/element_text.dart b/pkg/analyzer/test/src/summary/element_text.dart
index d0ffbb9..6831be1 100644
--- a/pkg/analyzer/test/src/summary/element_text.dart
+++ b/pkg/analyzer/test/src/summary/element_text.dart
@@ -15,6 +15,8 @@
 import 'package:analyzer/src/summary/idl.dart';
 import 'package:test/test.dart';
 
+import 'resolved_ast_printer.dart';
+
 /**
  * Set this path to automatically replace expectations in invocations of
  * [checkElementText] with the new actual texts.
@@ -53,19 +55,24 @@
  * taking into account the specified 'withX' options. Then compare the
  * actual text with the given [expected] one.
  */
-void checkElementText(LibraryElement library, String expected,
-    {bool withCodeRanges: false,
-    bool withConstElements: true,
-    bool withExportScope: false,
-    bool withOffsets: false,
-    bool withSyntheticAccessors: false,
-    bool withSyntheticFields: false,
-    bool withTypes: false,
-    bool annotateNullability: false}) {
+void checkElementText(
+  LibraryElement library,
+  String expected, {
+  bool withCodeRanges: false,
+  bool withConstElements: true,
+  bool withExportScope: false,
+  bool withFullyResolvedAst: false,
+  bool withOffsets: false,
+  bool withSyntheticAccessors: false,
+  bool withSyntheticFields: false,
+  bool withTypes: false,
+  bool annotateNullability: false,
+}) {
   var writer = new _ElementWriter(
       withCodeRanges: withCodeRanges,
       withConstElements: withConstElements,
       withExportScope: withExportScope,
+      withFullyResolvedAst: withFullyResolvedAst,
       withOffsets: withOffsets,
       withSyntheticAccessors: withSyntheticAccessors,
       withSyntheticFields: withSyntheticFields,
@@ -133,6 +140,7 @@
 class _ElementWriter {
   final bool withCodeRanges;
   final bool withExportScope;
+  final bool withFullyResolvedAst;
   final bool withOffsets;
   final bool withConstElements;
   final bool withSyntheticAccessors;
@@ -145,6 +153,7 @@
       {this.withCodeRanges,
       this.withConstElements: true,
       this.withExportScope: false,
+      this.withFullyResolvedAst: false,
       this.withOffsets: false,
       this.withSyntheticAccessors: false,
       this.withSyntheticFields: false,
@@ -531,7 +540,14 @@
     }
   }
 
-  void writeNode(AstNode e, [Expression enclosing]) {
+  void writeNode(AstNode e, {String indent: '', Expression enclosing}) {
+    if (withFullyResolvedAst) {
+      buffer.writeln();
+      var printer = ResolvedAstPrinter(buffer, indent);
+      e.accept(printer);
+      return;
+    }
+
     bool needsParenthesis = e is Expression &&
         enclosing != null &&
         e.precedence < enclosing.precedence;
@@ -568,11 +584,11 @@
       }
       buffer.write(')');
     } else if (e is BinaryExpression) {
-      writeNode(e.leftOperand, e);
+      writeNode(e.leftOperand, enclosing: e);
       buffer.write(' ');
       buffer.write(e.operator.lexeme);
       buffer.write(' ');
-      writeNode(e.rightOperand, e);
+      writeNode(e.rightOperand, enclosing: e);
     } else if (e is BooleanLiteral) {
       buffer.write(e.value);
     } else if (e is ConditionalExpression) {
@@ -673,16 +689,16 @@
     } else if (e is NullLiteral) {
       buffer.write('null');
     } else if (e is ParenthesizedExpression) {
-      writeNode(e.expression, e);
+      writeNode(e.expression, enclosing: e);
     } else if (e is PrefixExpression) {
       buffer.write(e.operator.lexeme);
-      writeNode(e.operand, e);
+      writeNode(e.operand, enclosing: e);
     } else if (e is PrefixedIdentifier) {
       writeNode(e.prefix);
       buffer.write('.');
       writeNode(e.identifier);
     } else if (e is PropertyAccess) {
-      writeNode(e.target, e);
+      writeNode(e.target, enclosing: e);
       buffer.write('.');
       writeNode(e.propertyName);
     } else if (e is RedirectingConstructorInvocation) {
@@ -949,7 +965,13 @@
       Expression initializer = (e as ConstVariableElement).constantInitializer;
       if (initializer != null) {
         buffer.write(' = ');
-        writeNode(initializer);
+        writeNode(
+          initializer,
+          indent: ' ' * (e is FieldElement ? 4 : 2),
+        );
+        if (withFullyResolvedAst) {
+          return;
+        }
       }
     }
 
diff --git a/pkg/analyzer/test/src/summary/expr_builder_test.dart b/pkg/analyzer/test/src/summary/expr_builder_test.dart
deleted file mode 100644
index c73bee8..0000000
--- a/pkg/analyzer/test/src/summary/expr_builder_test.dart
+++ /dev/null
@@ -1,895 +0,0 @@
-// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:analyzer/dart/analysis/features.dart';
-import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/ast/token.dart';
-import 'package:analyzer/error/listener.dart';
-import 'package:analyzer/src/dart/analysis/driver.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/generated/parser.dart';
-import 'package:analyzer/src/string_source.dart';
-import 'package:analyzer/src/summary/expr_builder.dart';
-import 'package:analyzer/src/summary/idl.dart';
-import 'package:analyzer/src/summary/resynthesize.dart';
-import 'package:analyzer/src/summary/summarize_const_expr.dart';
-import 'package:test/test.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-import 'resynthesize_common.dart';
-import 'test_strategies.dart';
-
-main() {
-  if (AnalysisDriver.useSummary2) {
-    test('fake', () {});
-    return;
-  }
-  defineReflectiveSuite(() {
-    defineReflectiveTests(ExprBuilderTest);
-    defineReflectiveTests(ExprBuilderWithConstantUpdateTest);
-    defineReflectiveTests(TokensToStringTest);
-  });
-}
-
-@reflectiveTest
-class ExprBuilderTest extends ResynthesizeTestStrategyTwoPhase
-    with ExprBuilderTestCases, ExprBuilderTestHelpers {}
-
-/// Mixin containing test cases exercising the [ExprBuilder].  Intended to be
-/// applied to a class implementing [ResynthesizeTestStrategy], along with the
-/// mixin [ExprBuilderTestHelpers].
-mixin ExprBuilderTestCases implements ExprBuilderTestHelpers {
-  void test_add() {
-    checkSimpleExpression('0 + 1');
-  }
-
-  void test_and() {
-    checkSimpleExpression('false && true');
-  }
-
-  void test_assignToIndex() {
-    checkSimpleExpression('items[0] = 1',
-        extraDeclarations: 'var items = [0, 1, 2]');
-  }
-
-  void test_assignToIndex_compound_multiply() {
-    checkSimpleExpression('items[0] *= 1',
-        extraDeclarations: 'var items = [0, 1, 2]');
-  }
-
-  void test_assignToProperty() {
-    checkSimpleExpression('new A().f = 1', extraDeclarations: r'''
-class A {
-  int f = 0;
-}
-''');
-  }
-
-  void test_assignToProperty_compound_plus() {
-    checkSimpleExpression('new A().f += 1', extraDeclarations: r'''
-class A {
-  int f = 0;
-}
-''');
-  }
-
-  void test_assignToProperty_compound_suffixIncrement() {
-    checkSimpleExpression('new A().f++', extraDeclarations: r'''
-class A {
-  int f = 0;
-}
-''');
-  }
-
-  void test_assignToRef() {
-    checkSimpleExpression('y = 0', extraDeclarations: 'var y;');
-  }
-
-  void test_await() {
-    checkSimpleExpression('() async => await 0');
-  }
-
-  void test_bitAnd() {
-    checkSimpleExpression('0 & 1');
-  }
-
-  void test_bitOr() {
-    checkSimpleExpression('0 | 1');
-  }
-
-  void test_bitShiftLeft() {
-    checkSimpleExpression('0 << 1');
-  }
-
-  void test_bitShiftRight() {
-    checkSimpleExpression('0 >> 1');
-  }
-
-  void test_bitXor() {
-    checkSimpleExpression('0 ^ 1');
-  }
-
-  void test_cascade() {
-    // Cascade sections don't matter for type inference.
-    // The type of a cascade is the type of the target.
-    checkSimpleExpression('new C()..f1 = 1..m(2, 3)..f2 = 4',
-        extraDeclarations: r'''
-class C {
-  int f1;
-  int f2;
-  int m(int a, int b) => 0;
-}
-''',
-        expectedText: 'new C()');
-  }
-
-  void test_closure_invalid_const() {
-    checkInvalidConst('() => 0');
-  }
-
-  void test_complement() {
-    checkSimpleExpression('~0');
-  }
-
-  void test_compoundAssignment_bitAnd() {
-    checkCompoundAssignment('y &= 0');
-  }
-
-  void test_compoundAssignment_bitOr() {
-    checkCompoundAssignment('y |= 0');
-  }
-
-  void test_compoundAssignment_bitXor() {
-    checkCompoundAssignment('y ^= 0');
-  }
-
-  void test_compoundAssignment_divide() {
-    checkCompoundAssignment('y /= 0');
-  }
-
-  void test_compoundAssignment_floorDivide() {
-    checkCompoundAssignment('y ~/= 0');
-  }
-
-  void test_compoundAssignment_ifNull() {
-    checkCompoundAssignment('y ??= 0');
-  }
-
-  void test_compoundAssignment_minus() {
-    checkCompoundAssignment('y -= 0');
-  }
-
-  void test_compoundAssignment_modulo() {
-    checkCompoundAssignment('y %= 0');
-  }
-
-  void test_compoundAssignment_multiply() {
-    checkCompoundAssignment('y *= 0');
-  }
-
-  void test_compoundAssignment_plus() {
-    checkCompoundAssignment('y += 0');
-  }
-
-  void test_compoundAssignment_postfixDecrement() {
-    checkCompoundAssignment('y--');
-  }
-
-  void test_compoundAssignment_postfixIncrement() {
-    checkCompoundAssignment('y++');
-  }
-
-  void test_compoundAssignment_prefixDecrement() {
-    checkCompoundAssignment('--y');
-  }
-
-  void test_compoundAssignment_prefixIncrement() {
-    checkCompoundAssignment('++y');
-  }
-
-  void test_compoundAssignment_shiftLeft() {
-    checkCompoundAssignment('y <<= 0');
-  }
-
-  void test_compoundAssignment_shiftRight() {
-    checkCompoundAssignment('y >>= 0');
-  }
-
-  void test_concatenate() {
-    var expr = buildTopLevelVariable(r'var x = "${0}";') as StringInterpolation;
-    expect(expr.elements, hasLength(3));
-    expect((expr.elements[0] as InterpolationString).value, '');
-    expect((expr.elements[1] as InterpolationExpression).expression.toString(),
-        '0');
-    expect((expr.elements[2] as InterpolationString).value, '');
-  }
-
-  void test_conditional() {
-    checkSimpleExpression('false ? 0 : 1');
-  }
-
-  void test_divide() {
-    checkSimpleExpression('0 / 1');
-  }
-
-  void test_equal() {
-    checkSimpleExpression('0 == 1');
-  }
-
-  void test_extractIndex() {
-    checkSimpleExpression('items[0]',
-        extraDeclarations: 'var items = [0, 1, 2]');
-  }
-
-  void test_extractProperty() {
-    checkSimpleExpression("'x'.length");
-  }
-
-  void test_floorDivide() {
-    checkSimpleExpression('0 ~/ 1');
-  }
-
-  void test_greater() {
-    checkSimpleExpression('0 > 1');
-  }
-
-  void test_greaterEqual() {
-    checkSimpleExpression('0 >= 1');
-  }
-
-  void test_ifNull() {
-    checkSimpleExpression('0 ?? 1');
-  }
-
-  void test_invokeConstructor_const() {
-    checkSimpleExpression('const C()',
-        extraDeclarations: '''
-class C {
-  const C();
-}
-''',
-        requireValidConst: true);
-  }
-
-  void test_invokeConstructor_generic_hasTypeArguments() {
-    checkSimpleExpression('new Map<int, List<String>>()');
-  }
-
-  void test_invokeConstructor_generic_noTypeArguments() {
-    checkSimpleExpression('new Map()');
-  }
-
-  void test_invokeMethod() {
-    checkSimpleExpression('new C().foo(1, 2)', extraDeclarations: r'''
-class C {
-  int foo(int a, int b) => 0;
-}
-''');
-  }
-
-  void test_invokeMethod_namedArguments() {
-    checkSimpleExpression('new C().foo(a: 1, c: 3)', extraDeclarations: r'''
-class C {
-  int foo({int a, int b, int c}) => 0;
-}
-''');
-  }
-
-  void test_invokeMethod_typeArguments() {
-    checkSimpleExpression('new C().foo<int, double>(1, 2.3)',
-        extraDeclarations: r'''
-class C {
-  int foo<T, U>(T a, U b) => 0;
-}
-''',
-        expectedText: 'new C().foo<int, double>()');
-  }
-
-  void test_invokeMethodRef() {
-    checkSimpleExpression('identical(0, 0)');
-  }
-
-  void test_less() {
-    checkSimpleExpression('0 < 1');
-  }
-
-  void test_lessEqual() {
-    checkSimpleExpression('0 <= 1');
-  }
-
-  void test_list_for() {
-    var sourceText = '[for (i = 0; i < 10; i++) i]';
-    // Resynthesis inserts synthetic "const" tokens; work around that.
-    var expectedText = 'const $sourceText';
-    checkSimpleExpression(sourceText,
-        expectedText: expectedText, extraDeclarations: 'int i;');
-  }
-
-  void test_list_for_each_with_declaration_typed() {
-    var sourceText = '[for (int i in const []) i]';
-    // Resynthesis inserts synthetic "const" tokens; work around that.
-    var expectedText = 'const $sourceText';
-    var list = checkSimpleExpression(sourceText, expectedText: expectedText)
-        as ListLiteral;
-    var forElement = list.elements[0] as ForElement;
-    var loopParts = forElement.forLoopParts as ForEachPartsWithDeclaration;
-    var iElement = loopParts.loopVariable.identifier.staticElement;
-    var iRef = forElement.body as SimpleIdentifier;
-    expect(iRef.staticElement, same(iElement));
-  }
-
-  void test_list_for_each_with_declaration_untyped() {
-    var sourceText = '[for (var i in const []) i]';
-    // Resynthesis inserts synthetic "const" tokens; work around that.
-    var expectedText = 'const $sourceText';
-    var list = checkSimpleExpression(sourceText, expectedText: expectedText)
-        as ListLiteral;
-    var forElement = list.elements[0] as ForElement;
-    var loopParts = forElement.forLoopParts as ForEachPartsWithDeclaration;
-    var iElement = loopParts.loopVariable.identifier.staticElement;
-    var iRef = forElement.body as SimpleIdentifier;
-    expect(iRef.staticElement, same(iElement));
-  }
-
-  void test_list_for_each_with_identifier() {
-    var sourceText = '[for (i in const []) i]';
-    // Resynthesis inserts synthetic "const" tokens; work around that.
-    var expectedText = 'const $sourceText';
-    checkSimpleExpression(sourceText,
-        expectedText: expectedText, extraDeclarations: 'int i;');
-  }
-
-  void test_list_for_each_with_identifier_await() {
-    var sourceText = '[await for (i in const []) i]';
-    // Resynthesis inserts synthetic "const" tokens; work around that.
-    var expectedText = 'const $sourceText';
-    checkSimpleExpression(sourceText,
-        expectedText: expectedText, extraDeclarations: 'int i;');
-  }
-
-  void test_list_for_empty_condition() {
-    var sourceText = '[for (i = 0;; i++) i]';
-    // Resynthesis inserts synthetic "const" tokens; work around that.
-    var expectedText = 'const $sourceText';
-    checkSimpleExpression(sourceText,
-        expectedText: expectedText, extraDeclarations: 'int i;');
-  }
-
-  void test_list_for_empty_initializer() {
-    var sourceText = '[for (; i < 10; i++) i]';
-    // Resynthesis inserts synthetic "const" tokens; work around that.
-    var expectedText = 'const $sourceText';
-    checkSimpleExpression(sourceText,
-        expectedText: expectedText, extraDeclarations: 'int i;');
-  }
-
-  void test_list_for_two_updaters() {
-    var sourceText = '[for (i = 0; i < 10; i++, j++) i]';
-    // Resynthesis inserts synthetic "const" tokens; work around that.
-    var expectedText = 'const $sourceText';
-    checkSimpleExpression(sourceText,
-        expectedText: expectedText, extraDeclarations: 'int i; int j;');
-  }
-
-  void test_list_for_with_one_declaration_typed() {
-    var sourceText = '[for (int i = 0; i < 10; i++) i]';
-    // Resynthesis inserts synthetic "const" tokens; work around that.
-    var expectedText = 'const $sourceText';
-    var list = checkSimpleExpression(sourceText, expectedText: expectedText)
-        as ListLiteral;
-    var forElement = list.elements[0] as ForElement;
-    var loopParts = forElement.forLoopParts as ForPartsWithDeclarations;
-    var iElement = loopParts.variables.variables[0].name.staticElement;
-    var condition = loopParts.condition as BinaryExpression;
-    var iRef1 = condition.leftOperand as SimpleIdentifier;
-    expect(iRef1.staticElement, same(iElement));
-    var updater = loopParts.updaters[0] as PostfixExpression;
-    var iRef2 = updater.operand as SimpleIdentifier;
-    expect(iRef2.staticElement, same(iElement));
-    var iRef3 = forElement.body as SimpleIdentifier;
-    expect(iRef3.staticElement, same(iElement));
-  }
-
-  void test_list_for_with_one_declaration_untyped() {
-    var sourceText = '[for (var i = 0; i < 10; i++) i]';
-    // Resynthesis inserts synthetic "const" tokens; work around that.
-    var expectedText = 'const $sourceText';
-    var list = checkSimpleExpression(sourceText, expectedText: expectedText)
-        as ListLiteral;
-    var forElement = list.elements[0] as ForElement;
-    var loopParts = forElement.forLoopParts as ForPartsWithDeclarations;
-    var iElement = loopParts.variables.variables[0].name.staticElement;
-    var condition = loopParts.condition as BinaryExpression;
-    var iRef1 = condition.leftOperand as SimpleIdentifier;
-    expect(iRef1.staticElement, same(iElement));
-    var updater = loopParts.updaters[0] as PostfixExpression;
-    var iRef2 = updater.operand as SimpleIdentifier;
-    expect(iRef2.staticElement, same(iElement));
-    var iRef3 = forElement.body as SimpleIdentifier;
-    expect(iRef3.staticElement, same(iElement));
-  }
-
-  void test_list_for_with_two_declarations_untyped() {
-    var sourceText = '[for (var i = 0, j = 0; i < 10; j++) i]';
-    // Resynthesis inserts synthetic "const" tokens; work around that.
-    var expectedText = 'const $sourceText';
-    var list = checkSimpleExpression(sourceText, expectedText: expectedText)
-        as ListLiteral;
-    var forElement = list.elements[0] as ForElement;
-    var loopParts = forElement.forLoopParts as ForPartsWithDeclarations;
-    var iElement = loopParts.variables.variables[0].name.staticElement;
-    var jElement = loopParts.variables.variables[1].name.staticElement;
-    var condition = loopParts.condition as BinaryExpression;
-    var iRef1 = condition.leftOperand as SimpleIdentifier;
-    expect(iRef1.staticElement, same(iElement));
-    var updater = loopParts.updaters[0] as PostfixExpression;
-    var jRef = updater.operand as SimpleIdentifier;
-    expect(jRef.staticElement, same(jElement));
-    var iRef2 = forElement.body as SimpleIdentifier;
-    expect(iRef2.staticElement, same(iElement));
-  }
-
-  void test_list_for_with_uninitialized_declaration_untyped() {
-    var sourceText = '[for (var i; i < 10; i++) i]';
-    // Resynthesis inserts synthetic "const" tokens; work around that.
-    var expectedText = 'const $sourceText';
-    var list = checkSimpleExpression(sourceText, expectedText: expectedText)
-        as ListLiteral;
-    var forElement = list.elements[0] as ForElement;
-    var loopParts = forElement.forLoopParts as ForPartsWithDeclarations;
-    var iElement = loopParts.variables.variables[0].name.staticElement;
-    var condition = loopParts.condition as BinaryExpression;
-    var iRef1 = condition.leftOperand as SimpleIdentifier;
-    expect(iRef1.staticElement, same(iElement));
-    var updater = loopParts.updaters[0] as PostfixExpression;
-    var iRef2 = updater.operand as SimpleIdentifier;
-    expect(iRef2.staticElement, same(iElement));
-    var iRef3 = forElement.body as SimpleIdentifier;
-    expect(iRef3.staticElement, same(iElement));
-  }
-
-  void test_list_for_zero_updaters() {
-    var sourceText = '[for (i = 0; i < 10;) i]';
-    // Resynthesis inserts synthetic "const" tokens; work around that.
-    var expectedText = 'const $sourceText';
-    checkSimpleExpression(sourceText,
-        expectedText: expectedText, extraDeclarations: 'int i;');
-  }
-
-  void test_makeSymbol() {
-    checkSimpleExpression('#foo');
-  }
-
-  void test_makeTypedList_const() {
-    checkSimpleExpression('const <int>[]');
-  }
-
-  void test_makeTypedMap_const() {
-    checkSimpleExpression('const <int, bool>{}');
-  }
-
-  void test_makeUntypedList_const() {
-    checkSimpleExpression('const [0]');
-  }
-
-  void test_makeUntypedMap_const() {
-    checkSimpleExpression('const {0 : false}');
-  }
-
-  void test_map_for() {
-    var sourceText = '{1 : 2, for (i = 0; i < 10; i++) i : i}';
-    // Resynthesis inserts synthetic "const" tokens; work around that.
-    var expectedText = 'const $sourceText';
-    checkSimpleExpression(sourceText,
-        expectedText: expectedText, extraDeclarations: 'int i;');
-  }
-
-  void test_modulo() {
-    checkSimpleExpression('0 % 1');
-  }
-
-  void test_multiply() {
-    checkSimpleExpression('0 * 1');
-  }
-
-  void test_negate() {
-    checkSimpleExpression('-1');
-  }
-
-  void test_not() {
-    checkSimpleExpression('!true');
-  }
-
-  void test_notEqual() {
-    checkSimpleExpression('0 != 1');
-  }
-
-  void test_or() {
-    checkSimpleExpression('false || true');
-  }
-
-  void test_pushDouble() {
-    checkSimpleExpression('0.5');
-  }
-
-  void test_pushFalse() {
-    checkSimpleExpression('false');
-  }
-
-  void test_pushInt() {
-    checkSimpleExpression('0');
-  }
-
-  void test_pushLocalFunctionReference() {
-    checkSimpleExpression('() => 0');
-  }
-
-  void test_pushLocalFunctionReference_async() {
-    checkSimpleExpression('() async => 0');
-  }
-
-  void test_pushLocalFunctionReference_block() {
-    checkSimpleExpression('() {}');
-  }
-
-  void test_pushLocalFunctionReference_namedParam_untyped() {
-    checkSimpleExpression('({x}) => 0');
-  }
-
-  @failingTest
-  void test_pushLocalFunctionReference_nested() {
-    var expr =
-        checkSimpleExpression('(x) => (y) => x + y') as FunctionExpression;
-    var outerFunctionElement = expr.declaredElement;
-    var xElement = outerFunctionElement.parameters[0];
-    var x = expr.parameters.parameters[0];
-    expect(x.declaredElement, same(xElement));
-    var outerBody = expr.body as ExpressionFunctionBody;
-    var outerBodyExpr = outerBody.expression as FunctionExpression;
-    var innerFunctionElement = outerBodyExpr.declaredElement;
-    var yElement = innerFunctionElement.parameters[0];
-    var y = outerBodyExpr.parameters.parameters[0];
-    expect(y.declaredElement, same(yElement));
-    var innerBody = outerBodyExpr.body as ExpressionFunctionBody;
-    var innerBodyExpr = innerBody.expression as BinaryExpression;
-    var xRef = innerBodyExpr.leftOperand as SimpleIdentifier;
-    var yRef = innerBodyExpr.rightOperand as SimpleIdentifier;
-    expect(xRef.staticElement, same(xElement));
-    expect(yRef.staticElement, same(yElement));
-  }
-
-  @failingTest
-  void test_pushLocalFunctionReference_paramReference() {
-    var expr = checkSimpleExpression('(x, y) => x + y') as FunctionExpression;
-    var localFunctionElement = expr.declaredElement;
-    var xElement = localFunctionElement.parameters[0];
-    var yElement = localFunctionElement.parameters[1];
-    var x = expr.parameters.parameters[0];
-    var y = expr.parameters.parameters[1];
-    expect(x.declaredElement, same(xElement));
-    expect(y.declaredElement, same(yElement));
-    var body = expr.body as ExpressionFunctionBody;
-    var bodyExpr = body.expression as BinaryExpression;
-    var xRef = bodyExpr.leftOperand as SimpleIdentifier;
-    var yRef = bodyExpr.rightOperand as SimpleIdentifier;
-    expect(xRef.staticElement, same(xElement));
-    expect(yRef.staticElement, same(yElement));
-  }
-
-  void test_pushLocalFunctionReference_positionalParam_untyped() {
-    checkSimpleExpression('([x]) => 0');
-  }
-
-  void test_pushLocalFunctionReference_requiredParam_typed() {
-    var expr = checkSimpleExpression('(int x) => 0', expectedText: '(x) => 0')
-        as FunctionExpression;
-    var functionElement = expr.declaredElement;
-    var xElement = functionElement.parameters[0] as ParameterElementImpl;
-    expect(xElement.type.toString(), 'int');
-  }
-
-  void test_pushLocalFunctionReference_requiredParam_untyped() {
-    checkSimpleExpression('(x) => 0');
-  }
-
-  void test_pushLongInt() {
-    checkSimpleExpression('4294967296');
-  }
-
-  void test_pushNull() {
-    checkSimpleExpression('null');
-  }
-
-  void test_pushParameter() {
-    checkConstructorInitializer('''
-class C {
-  int x;
-  const C(int p) : x = p;
-}
-''', 'p');
-  }
-
-  void test_pushReference() {
-    checkSimpleExpression('int');
-  }
-
-  void test_pushReference_sequence() {
-    checkSimpleExpression('a.b.f', extraDeclarations: r'''
-var a = new A();
-class A {
-  B b = new B();
-}
-class B {
-  int f = 0;
-}
-''');
-  }
-
-  void test_pushString() {
-    checkSimpleExpression("'foo'");
-  }
-
-  void test_pushTrue() {
-    checkSimpleExpression('true');
-  }
-
-  void test_set_for() {
-    var sourceText = '{1, for (i = 0; i < 10; i++) i}';
-    // Resynthesis inserts synthetic "const" tokens; work around that.
-    var expectedText = 'const $sourceText';
-    checkSimpleExpression(sourceText,
-        expectedText: expectedText, extraDeclarations: 'int i;');
-  }
-
-  void test_subtract() {
-    checkSimpleExpression('0 - 1');
-  }
-
-  void test_throwException() {
-    checkSimpleExpression('throw 0');
-  }
-
-  void test_typeCast() {
-    checkSimpleExpression('0 as num');
-  }
-
-  void test_typeCheck() {
-    checkSimpleExpression('0 is num');
-  }
-
-  void test_typeCheck_negated() {
-    checkSimpleExpression('0 is! num', expectedText: '!(0 is num)');
-  }
-}
-
-/// Mixin containing helper methods for testing the [ExprBuilder]. Intended to
-/// be applied to a class implementing [ResynthesizeTestStrategy].
-mixin ExprBuilderTestHelpers implements ResynthesizeTestStrategy {
-  Expression buildConstructorInitializer(String sourceText,
-      {String className: 'C',
-      String initializerName: 'x',
-      bool requireValidConst: false}) {
-    var resynthesizer = encodeSource(sourceText);
-    var library = resynthesizer.getLibraryElement(testSource.uri.toString());
-    var c = library.getType(className);
-    var constructor = c.unnamedConstructor as ConstructorElementImpl;
-    var serializedExecutable = constructor.serializedExecutable;
-    var x = serializedExecutable.constantInitializers
-        .singleWhere((i) => i.name == initializerName);
-    return buildExpression(resynthesizer, constructor, x.expression,
-        serializedExecutable.localFunctions,
-        requireValidConst: requireValidConst);
-  }
-
-  Expression buildExpression(
-      TestSummaryResynthesizer resynthesizer,
-      ElementImpl context,
-      UnlinkedExpr unlinkedExpr,
-      List<UnlinkedExecutable> localFunctions,
-      {bool requireValidConst: false}) {
-    var library = resynthesizer.getLibraryElement(testSource.uri.toString());
-    var unit = library.definingCompilationUnit as CompilationUnitElementImpl;
-    var unitResynthesizerContext =
-        unit.resynthesizerContext as SummaryResynthesizerContext;
-    var unitResynthesizer = unitResynthesizerContext.unitResynthesizer;
-    var exprBuilder = new ExprBuilder(unitResynthesizer, context, unlinkedExpr,
-        requireValidConst: requireValidConst, localFunctions: localFunctions);
-    return exprBuilder.build();
-  }
-
-  Expression buildTopLevelVariable(String sourceText,
-      {String variableName: 'x', bool requireValidConst: false}) {
-    var resynthesizer = encodeSource(sourceText);
-    var library = resynthesizer.getLibraryElement(testSource.uri.toString());
-    var unit = library.definingCompilationUnit as CompilationUnitElementImpl;
-    TopLevelVariableElementImpl x =
-        unit.topLevelVariables.singleWhere((e) => e.name == variableName);
-    return buildExpression(
-        resynthesizer,
-        x,
-        x.unlinkedVariableForTesting.initializer.bodyExpr,
-        x.unlinkedVariableForTesting.initializer.localFunctions,
-        requireValidConst: requireValidConst);
-  }
-
-  void checkCompoundAssignment(String exprText) {
-    checkSimpleExpression(exprText, extraDeclarations: 'var y;');
-  }
-
-  void checkConstructorInitializer(String sourceText, String expectedText,
-      {String className: 'C',
-      String initializerName: 'x',
-      bool requireValidConst: false}) {
-    Expression expr = buildConstructorInitializer(sourceText,
-        className: className,
-        initializerName: initializerName,
-        requireValidConst: requireValidConst);
-    expect(expr.toString(), expectedText);
-  }
-
-  void checkInvalidConst(String expressionText) {
-    checkTopLevelVariable('var x = $expressionText;', 'null',
-        requireValidConst: true);
-  }
-
-  Expression checkSimpleExpression(String expressionText,
-      {String expectedText,
-      String extraDeclarations: '',
-      bool requireValidConst: false}) {
-    return checkTopLevelVariable('var x = $expressionText;\n$extraDeclarations',
-        expectedText ?? expressionText,
-        requireValidConst: requireValidConst);
-  }
-
-  Expression checkTopLevelVariable(String sourceText, String expectedText,
-      {String variableName: 'x', bool requireValidConst: false}) {
-    Expression expr = buildTopLevelVariable(sourceText,
-        variableName: variableName, requireValidConst: requireValidConst);
-    expect(expr.toString(), expectedText);
-    return expr;
-  }
-
-  TestSummaryResynthesizer encodeSource(String text) {
-    var source = addTestSource(text);
-    return encodeLibrary(source);
-  }
-}
-
-@reflectiveTest
-class ExprBuilderWithConstantUpdateTest extends ResynthesizeTestStrategyTwoPhase
-    with ExprBuilderTestHelpers {
-  @override
-  FeatureSet get featureSet => new FeatureSet.forTesting(
-      sdkVersion: '2.2.2',
-      additionalFeatures: [Feature.constant_update_2018, Feature.triple_shift]);
-
-  void test_bitShiftRightLogical() {
-    checkSimpleExpression('0 >>> 1');
-  }
-}
-
-@reflectiveTest
-class TokensToStringTest {
-  final featureSet = FeatureSet.forTesting(sdkVersion: '2.2.2');
-
-  void test_empty_list_no_space() {
-    // This is an interesting test case because "[]" is scanned as a single
-    // token, but the parser splits it into two.
-    _check('[]');
-  }
-
-  void test_empty_list_with_space() {
-    _check('[ ]');
-  }
-
-  void test_gt_gt_gt_in_type() {
-    // This is an interesting test case because ">>>" is scanned as a single
-    // token, but the parser splits it into three.
-    _check('A<B<C>>>[]');
-  }
-
-  void test_gt_gt_gt_in_type_split_both() {
-    _check('A<B<C> > >[]');
-  }
-
-  void test_gt_gt_gt_in_type_split_left() {
-    _check('A<B<C> >>[]');
-  }
-
-  void test_gt_gt_gt_in_type_split_right() {
-    _check('A<B<C>> >[]');
-  }
-
-  void test_gt_gt_in_type() {
-    // This is an interesting test case because ">>" is scanned as a single
-    // token, but the parser splits it into two.
-    _check('<A<B>>[]');
-  }
-
-  void test_gt_gt_in_type_split() {
-    _check('A<B> >[]');
-  }
-
-  void test_identifier() {
-    _check('foo');
-  }
-
-  void test_interpolation_expr_at_end_of_string() {
-    _check(r'"foo${bar}"');
-  }
-
-  void test_interpolation_expr_at_start_of_string() {
-    _check(r'"${foo}bar"');
-  }
-
-  void test_interpolation_expr_inside_string() {
-    _check(r'"foo${bar}baz"');
-  }
-
-  void test_interpolation_var_at_end_of_string() {
-    _check(r'"foo$bar"');
-  }
-
-  void test_interpolation_var_at_start_of_string() {
-    _check(r'"$foo bar"');
-  }
-
-  void test_interpolation_var_inside_string() {
-    _check(r'"foo$bar baz"');
-  }
-
-  void test_simple_string() {
-    _check('"foo"');
-  }
-
-  void _check(String originalString) {
-    var expression = _parseExpression(originalString);
-    var originalTokens =
-        _extractTokenList(expression.beginToken, expression.endToken);
-    var newString = tokensToString(expression.beginToken, expression.endToken);
-    var errorListener = AnalysisErrorListener.NULL_LISTENER;
-    var reader = new CharSequenceReader(newString);
-    var stringSource = new StringSource(newString, null);
-    var scanner = new Scanner(stringSource, reader, errorListener)
-      ..configureFeatures(featureSet);
-    var startToken = scanner.tokenize();
-    var newTokens = _extractTokenList(startToken);
-    expect(newTokens, originalTokens);
-  }
-
-  List<String> _extractTokenList(Token startToken, [Token endToken]) {
-    var result = <String>[];
-    while (!startToken.isEof) {
-      if (!startToken.isSynthetic) result.add(startToken.lexeme);
-      if (identical(startToken, endToken)) break;
-      startToken = startToken.next;
-    }
-    return result;
-  }
-
-  Expression _parseExpression(String expressionString) {
-    // Note: to normalize the token string it's not sufficient to tokenize it
-    // and then pass the tokens to `tokensToString`; we also need to parse it
-    // because parsing modifies the token stream (splitting up `[]`, `>>`, and
-    // `>>>` tokens when circumstances warrant).
-    //
-    // We wrap the expression in "f() async => ...;" to ensure that the await
-    // keyword is properly parsed.
-    var sourceText = 'f() async => $expressionString;';
-    var errorListener = AnalysisErrorListener.NULL_LISTENER;
-    var reader = new CharSequenceReader(sourceText);
-    var stringSource = new StringSource(sourceText, null);
-    var scanner = new Scanner(stringSource, reader, errorListener)
-      ..configureFeatures(featureSet);
-    var startToken = scanner.tokenize();
-    var parser =
-        new Parser(stringSource, errorListener, featureSet: featureSet);
-    var compilationUnit = parser.parseCompilationUnit(startToken);
-    var f = compilationUnit.declarations[0] as FunctionDeclaration;
-    var body = f.functionExpression.body as ExpressionFunctionBody;
-    return body.expression;
-  }
-}
diff --git a/pkg/analyzer/test/src/summary/linker_test.dart b/pkg/analyzer/test/src/summary/linker_test.dart
deleted file mode 100644
index bb34cbd..0000000
--- a/pkg/analyzer/test/src/summary/linker_test.dart
+++ /dev/null
@@ -1,1031 +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 'package:analyzer/dart/element/type.dart';
-import 'package:analyzer/src/dart/analysis/driver.dart';
-import 'package:analyzer/src/dart/element/element.dart';
-import 'package:analyzer/src/summary/idl.dart';
-import 'package:analyzer/src/summary/link.dart';
-import 'package:test/test.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-import 'test_strategies.dart';
-
-main() {
-  if (AnalysisDriver.useSummary2) {
-    test('fake', () {});
-    return;
-  }
-  defineReflectiveSuite(() {
-    defineReflectiveTests(LinkerUnitTest);
-  });
-}
-
-@reflectiveTest
-class LinkerUnitTest extends SummaryLinkerTestStrategyTwoPhase
-    with LinkerUnitTestCases {}
-
-/// Test cases that exercise the summary linker in a white-box fashion.
-///
-/// These test cases may be mixed into any class derived from
-/// [SummaryLinkerTestStrategy], allowing the linker to be unit-tested in a
-/// variety of ways.
-mixin LinkerUnitTestCases implements SummaryLinkerTestStrategy {
-  Matcher get isUndefined => const TypeMatcher<UndefinedElementForLink>();
-
-  LibraryElementForLink getLibrary(String uri) {
-    return linker.getLibrary(Uri.parse(uri));
-  }
-
-  void test_baseClass_genericWithAccessor() {
-    createLinker('''
-class B<T> {
-  int get i => null;
-}
-class C<U> extends B<U> {
-  var j;
-}
-    ''');
-    LibraryElementForLink library = linker.getLibrary(testDartUri);
-    library.libraryCycleForLink.ensureLinked();
-    // No assertions--just make sure it doesn't crash.
-  }
-
-  void test_baseClass_genericWithField() {
-    createLinker('''
-class B<T> {
-  int i = 0;
-}
-class C<T> extends B<T> {
-  void f() {}
-}
-''');
-    LibraryElementForLink library = linker.getLibrary(testDartUri);
-    library.libraryCycleForLink.ensureLinked();
-    // No assertions--just make sure it doesn't crash.
-  }
-
-  void test_baseClass_genericWithFunctionTypedParameter() {
-    createLinker('''
-class B<T> {
-  void f(void g(T t));
-}
-class C<U> extends B<U> {
-  void f(g) {}
-}
-''');
-    LibraryElementForLink library = linker.getLibrary(testDartUri);
-    library.libraryCycleForLink.ensureLinked();
-    // No assertions--just make sure it doesn't crash.
-  }
-
-  void test_baseClass_genericWithGenericMethod() {
-    createLinker('''
-class B<T> {
-  List<U> f<U>(U u) => null;
-}
-class C<V> extends B<V> {
-  var j;
-}
-''');
-    LibraryElementForLink library = linker.getLibrary(testDartUri);
-    library.libraryCycleForLink.ensureLinked();
-    // No assertions--just make sure it doesn't crash.
-  }
-
-  void test_baseClass_genericWithGenericMethod_returnsGenericFuture() {
-    createLinker('''
-import 'dart:async';
-class B<T> {
-  Future<T> f() => null;
-}
-class C<T> extends B<T> {
-  Future<T> f() => null;
-}
-''');
-    LibraryElementForLink library = linker.getLibrary(testDartUri);
-    library.libraryCycleForLink.ensureLinked();
-    // No assertions--just make sure it doesn't crash.
-  }
-
-  void test_baseClass_genericWithStaticFinal() {
-    createLinker('''
-class B<T> {
-  static final int i = 0;
-}
-class C<T> extends B<T> {
-  void f() {}
-}
-''');
-    LibraryElementForLink library = linker.getLibrary(testDartUri);
-    library.libraryCycleForLink.ensureLinked();
-  }
-
-  void test_baseClass_withPrivateField() {
-    createLinker('''
-class B {
-  var _b;
-}
-class C extends B {
-  var c;
-}
-''');
-    LibraryElementForLink library = linker.getLibrary(testDartUri);
-    library.libraryCycleForLink.ensureLinked();
-    // No assertions--just make sure it doesn't crash.
-  }
-
-  void test_bundle_refers_to_bundle() {
-    var bundle1 = createPackageBundle('''
-var x = 0;
-''', path: '/a.dart');
-    addBundle('/a.ds', bundle1);
-    var bundle2 = createPackageBundle('''
-import "a.dart";
-var y = x;
-''', path: '/b.dart');
-    addBundle('/a.ds', bundle1);
-    addBundle('/b.ds', bundle2);
-    createLinker('''
-import "b.dart";
-var z = y;
-''');
-    LibraryElementForLink library = linker.getLibrary(testDartUri);
-    expect(_getVariable(library.getContainedName('z')).inferredType.toString(),
-        'int');
-  }
-
-  void test_constCycle_viaLength() {
-    createLinker('''
-class C {
-  final y;
-  const C() : y = x.length;
-}
-const x = [const C()];
-''');
-    testLibrary.libraryCycleForLink.ensureLinked();
-    ClassElementForLink classC = testLibrary.getContainedName('C');
-    expect(classC.unnamedConstructor.isCycleFree, false);
-  }
-
-  void test_covariance() {
-    createLinker('''
-class A<T> {
-  void f(covariant T t) {}
-}
-class B<T> extends A<T> {
-  void f(T t) {}
-}
-''');
-    testLibrary.libraryCycleForLink.ensureLinked();
-    ClassElementForLink classA = testLibrary.getContainedName('A');
-    MethodElementForLink methodAF = classA.getContainedName('f');
-    ParameterElementForLink parameterAFT = methodAF.parameters[0];
-    expect(parameterAFT.isCovariant, isTrue);
-    expect(parameterAFT.inheritsCovariant, isFalse);
-    ClassElementForLink classB = testLibrary.getContainedName('B');
-    MethodElementForLink methodBF = classB.getContainedName('f');
-    ParameterElementForLink parameterBFT = methodBF.parameters[0];
-    expect(parameterAFT.isCovariant, isTrue);
-    expect(parameterBFT.inheritsCovariant, isTrue);
-  }
-
-  void test_createPackageBundle_withPackageUri() {
-    PackageBundle bundle = createPackageBundle('''
-class B {
-  void f(int i) {}
-}
-class C extends B {
-  f(i) {} // Inferred param type: int
-}
-''', uri: 'package:foo/bar.dart');
-    UnlinkedExecutable cf = bundle.unlinkedUnits[0].classes[1].executables[0];
-    UnlinkedParam cfi = cf.parameters[0];
-    expect(cfi.inferredTypeSlot, isNot(0));
-    EntityRef typeRef = _lookupInferredType(
-        bundle.linkedLibraries[0].units[0], cfi.inferredTypeSlot);
-    expect(typeRef, isNotNull);
-    expect(bundle.unlinkedUnits[0].references[typeRef.reference].name, 'int');
-  }
-
-  void test_genericTypeAlias_fromBundle() {
-    var bundle = createPackageBundle('''
-typedef F<S> = S Function(num);
-''', path: '/a.dart');
-    addBundle('/a.ds', bundle);
-
-    createLinker('''
-import 'a.dart';
-class A {
-  F<int> f;
-}
-class B implements A {
-  F<int> f;
-}
-''');
-    LibraryElementForLink library = linker.getLibrary(testDartUri);
-    library.libraryCycleForLink.ensureLinked();
-
-    ClassElementForLink_Class B = library.getContainedName('B');
-    expect(B.fields, hasLength(1));
-    FieldElementForLink f = B.fields[0];
-    expect(f.type.toString(), 'int Function(num)');
-  }
-
-  void test_getContainedName_nonStaticField() {
-    createLinker('class C { var f; }');
-    LibraryElementForLink library = linker.getLibrary(testDartUri);
-    ClassElementForLink_Class c = library.getContainedName('C');
-    expect(c.getContainedName('f'), isNot(isUndefined));
-  }
-
-  void test_getContainedName_nonStaticGetter() {
-    createLinker('class C { get g => null; }');
-    LibraryElementForLink library = linker.getLibrary(testDartUri);
-    ClassElementForLink_Class c = library.getContainedName('C');
-    expect(c.getContainedName('g'), isNot(isUndefined));
-  }
-
-  void test_getContainedName_nonStaticMethod() {
-    createLinker('class C { m() {} }');
-    LibraryElementForLink library = linker.getLibrary(testDartUri);
-    ClassElementForLink_Class c = library.getContainedName('C');
-    expect(c.getContainedName('m'), isNot(isUndefined));
-  }
-
-  void test_getContainedName_nonStaticSetter() {
-    createLinker('class C { void set s(value) {} }');
-    LibraryElementForLink library = linker.getLibrary(testDartUri);
-    ClassElementForLink_Class c = library.getContainedName('C');
-    expect(c.getContainedName('s='), isNot(isUndefined));
-  }
-
-  void test_inferredType_closure_fromBundle() {
-    var bundle = createPackageBundle('''
-var x = () {};
-''', path: '/a.dart');
-    addBundle('/a.ds', bundle);
-    createLinker('''
-import 'a.dart';
-var y = x;
-''');
-    LibraryElementForLink library = linker.getLibrary(testDartUri);
-    expect(_getVariable(library.getContainedName('y')).inferredType.toString(),
-        'Null Function()');
-  }
-
-  void test_inferredType_closure_fromBundle_identifierSequence() {
-    var bundle = createPackageBundle('''
-class C {
-  static final x = (D d) => d.e;
-}
-class D {
-  E e;
-}
-class E {}
-''', path: '/a.dart');
-    addBundle('/a.ds', bundle);
-    createLinker('''
-import 'a.dart';
-var y = C.x;
-''');
-    LibraryElementForLink library = linker.getLibrary(testDartUri);
-    expect(_getVariable(library.getContainedName('y')).inferredType.toString(),
-        'E Function(D)');
-  }
-
-  void test_inferredType_implicitFunctionTypeIndices() {
-    var bundle = createPackageBundle('''
-class A {
-  void foo(void bar(int arg)) {}
-}
-class B extends A {
-  void foo(bar) {}
-}
-''', path: '/a.dart');
-    addBundle('/a.ds', bundle);
-    createLinker('''
-import 'a.dart';
-class C extends B {
-  void foo(bar) {}
-}
-''');
-    LibraryElementForLink library = linker.getLibrary(testDartUri);
-    library.libraryCycleForLink.ensureLinked();
-    ClassElementForLink_Class cls = library.getContainedName('C');
-    expect(cls.methods, hasLength(1));
-    MethodElementForLink foo = cls.methods[0];
-    expect(foo.parameters, hasLength(1));
-    FunctionType barType = foo.parameters[0].type;
-    expect(barType.parameters[0].type.toString(), 'int');
-  }
-
-  void test_inferredType_instanceField_conditional_genericFunctions() {
-    createLinker('''
-class C {
-  final f = true ? <T>(T t) => 0 : <T>(T t) => 1;
-}
-''');
-    LibraryElementForLink library = linker.getLibrary(testDartUri);
-    library.libraryCycleForLink.ensureLinked();
-    ClassElementForLink_Class cls = library.getContainedName('C');
-    expect(cls.fields, hasLength(1));
-    var field = cls.fields[0];
-    expect(field.type.toString(), 'int Function<T>(T)');
-  }
-
-  void test_inferredType_instanceField_dynamic() {
-    createLinker('''
-var x;
-class C {
-  var f = x; // Inferred type: dynamic
-}
-''');
-    LibraryElementForLink library = linker.getLibrary(testDartUri);
-    library.libraryCycleForLink.ensureLinked();
-    ClassElementForLink_Class cls = library.getContainedName('C');
-    expect(cls.fields, hasLength(1));
-    var field = cls.fields[0];
-    expect(field.type.toString(), 'dynamic');
-  }
-
-  void test_inferredType_methodParamType_dynamic() {
-    createLinker('''
-clas B {
-  void f(dynamic x) {}
-}
-class C extends B {
-  f(x) {} // Inferred param type: dynamic
-}
-''');
-    LibraryElementForLink library = linker.getLibrary(testDartUri);
-    library.libraryCycleForLink.ensureLinked();
-    ClassElementForLink_Class cls = library.getContainedName('C');
-    expect(cls.methods, hasLength(1));
-    var method = cls.methods[0];
-    expect(method.parameters, hasLength(1));
-    expect(method.parameters[0].type.toString(), 'dynamic');
-  }
-
-  void test_inferredType_methodParamType_genericFunction() {
-    createLinker('''
-class A {
-  void m(Map<T, List<U>> Function<T, U>(T, U) p) {}
-}
-class B<V> extends A {
-  void m(p) {}
-}
-''');
-    LibraryElementForLink library = linker.getLibrary(testDartUri);
-    library.libraryCycleForLink.ensureLinked();
-    ClassElementForLink_Class cls = library.getContainedName('B');
-    expect(cls.methods, hasLength(1));
-    var method = cls.methods[0];
-    expect(method.parameters, hasLength(1));
-    var pType = method.parameters[0].type;
-    expect(pType.toString(), 'Map<T, List<U>> Function<T,U>(T, U)');
-  }
-
-  void test_inferredType_methodReturnType_dynamic() {
-    createLinker('''
-class B {
-  dynamic f() {}
-}
-class C extends B {
-  f() {} // Inferred return type: dynamic
-}
-''');
-    LibraryElementForLink library = linker.getLibrary(testDartUri);
-    library.libraryCycleForLink.ensureLinked();
-    ClassElementForLink_Class cls = library.getContainedName('C');
-    expect(cls.methods, hasLength(1));
-    expect(cls.methods[0].returnType.toString(), 'dynamic');
-  }
-
-  void test_inferredType_methodReturnType_void() {
-    createLinker('''
-class B {
-  void f() {}
-}
-class C extends B {
-  f() {}
-}
-''');
-    LibraryElementForLink library = linker.getLibrary(testDartUri);
-    library.libraryCycleForLink.ensureLinked();
-    ClassElementForLink_Class cls = library.getContainedName('C');
-    expect(cls.methods, hasLength(1));
-    expect(cls.methods[0].returnType.toString(), 'void');
-  }
-
-  void test_inferredType_parameter_genericFunctionType() {
-    var bundle = createPackageBundle('''
-class A<T> {
-  A<R> map<R>(R Function(T) f) => null;
-}
-''', path: '/a.dart');
-    addBundle('/a.ds', bundle);
-    createLinker('''
-import 'a.dart';
-class C extends A<int> {
-  map<R2>(f) => null;
-}
-''');
-    LibraryElementForLink library = linker.getLibrary(testDartUri);
-    library.libraryCycleForLink.ensureLinked();
-    ClassElementForLink_Class c = library.getContainedName('C');
-    expect(c.methods, hasLength(1));
-    MethodElementForLink map = c.methods[0];
-    expect(map.parameters, hasLength(1));
-    FunctionType fType = map.parameters[0].type;
-    expect(fType.returnType.toString(), 'R2');
-    expect(fType.parameters[0].type.toString(), 'int');
-  }
-
-  void test_inferredType_parameter_genericFunctionType_asTypeArgument() {
-    var bundle = createPackageBundle('''
-class A<T> {
-  A<R> map<R>(List<R Function(T)> fs) => null;
-}
-''', path: '/a.dart');
-    addBundle('/a.ds', bundle);
-    createLinker('''
-import 'a.dart';
-class C extends A<int> {
-  map<R2>(fs) => null;
-}
-''');
-    LibraryElementForLink library = linker.getLibrary(testDartUri);
-    library.libraryCycleForLink.ensureLinked();
-    ClassElementForLink_Class c = library.getContainedName('C');
-    expect(c.methods, hasLength(1));
-    MethodElementForLink map = c.methods[0];
-    expect(map.parameters, hasLength(1));
-    InterfaceType iType = map.parameters[0].type;
-    expect(iType.typeArguments, hasLength(1));
-    FunctionType fType = iType.typeArguments[0];
-    expect(fType.returnType.toString(), 'R2');
-    expect(fType.parameters[0].type.toString(), 'int');
-  }
-
-  void test_inferredType_staticField_dynamic() {
-    createLinker('''
-dynamic x = null;
-class C {
-  static var y = x;
-}
-''');
-    expect(
-        _getVariable(linker
-                .getLibrary(testDartUri)
-                .getContainedName('C')
-                .getContainedName('y'))
-            .inferredType
-            .toString(),
-        'dynamic');
-  }
-
-  void test_inferredType_topLevelVariable_dynamic() {
-    createLinker('''
-dynamic x = null;
-var y = x;
-''');
-    expect(
-        _getVariable(linker.getLibrary(testDartUri).getContainedName('y'))
-            .inferredType
-            .toString(),
-        'dynamic');
-  }
-
-  void test_inferredTypeFromOutsideBuildUnit_dynamic() {
-    var bundle = createPackageBundle('''
-var x;
-var y = x; // Inferred type: dynamic
-''', path: '/a.dart');
-    addBundle('/a.ds', bundle);
-    createLinker('''
-import 'a.dart';
-var z = y; // Inferred type: dynamic
-''');
-    LibraryElementForLink library = linker.getLibrary(testDartUri);
-    expect(_getVariable(library.getContainedName('z')).inferredType.toString(),
-        'dynamic');
-  }
-
-  void test_inferredTypeFromOutsideBuildUnit_instanceField() {
-    var bundle = createPackageBundle('''
-class C {
-  var f = 0; // Inferred type: int
-}
-''', path: '/a.dart');
-    addBundle('/a.ds', bundle);
-    createLinker('''
-import 'a.dart';
-var x = new C().f; // Inferred type: int
-''');
-    LibraryElementForLink library = linker.getLibrary(testDartUri);
-    expect(_getVariable(library.getContainedName('x')).inferredType.toString(),
-        'dynamic');
-  }
-
-  void test_inferredTypeFromOutsideBuildUnit_instanceField_toInstanceField() {
-    var bundle = createPackageBundle('''
-class C {
-  var f = 0; // Inferred type: int
-}
-''', path: '/a.dart');
-    addBundle('/a.ds', bundle);
-    createLinker('''
-import 'a.dart';
-class D {
-  var g = new C().f; // Inferred type: int
-}
-''');
-    LibraryElementForLink library = linker.getLibrary(testDartUri);
-    ClassElementForLink_Class classD = library.getContainedName('D');
-    expect(classD.fields[0].inferredType.toString(), 'dynamic');
-  }
-
-  void test_inferredTypeFromOutsideBuildUnit_methodParamType_viaInheritance() {
-    var bundle = createPackageBundle('''
-class B {
-  void f(int i) {}
-}
-class C extends B {
-  f(i) {} // Inferred param type: int
-}
-''', path: '/a.dart');
-    addBundle('/a.ds', bundle);
-    createLinker('''
-import 'a.dart';
-class D extends C {
-  f(i) {} // Inferred param type: int
-}
-''');
-    LibraryElementForLink library = linker.getLibrary(testDartUri);
-    library.libraryCycleForLink.ensureLinked();
-    ClassElementForLink_Class cls = library.getContainedName('D');
-    expect(cls.methods, hasLength(1));
-    var method = cls.methods[0];
-    expect(method.parameters, hasLength(1));
-    expect(method.parameters[0].type.toString(), 'int');
-  }
-
-  void test_inferredTypeFromOutsideBuildUnit_methodReturnType_viaCall() {
-    var bundle = createPackageBundle('''
-class B {
-  int f() => 0;
-}
-class C extends B {
-  f() => 1; // Inferred return type: int
-}
-''', path: '/a.dart');
-    addBundle('/a.ds', bundle);
-    createLinker('''
-import 'a.dart';
-var x = new C().f(); // Inferred type: int
-''');
-    LibraryElementForLink library = linker.getLibrary(testDartUri);
-    expect(_getVariable(library.getContainedName('x')).inferredType.toString(),
-        'int');
-  }
-
-  void test_inferredTypeFromOutsideBuildUnit_methodReturnType_viaInheritance() {
-    var bundle = createPackageBundle('''
-class B {
-  int f() => 0;
-}
-class C extends B {
-  f() => 1; // Inferred return type: int
-}
-''', path: '/a.dart');
-    addBundle('/a.ds', bundle);
-    createLinker('''
-import 'a.dart';
-class D extends C {
-  f() => 2; //Inferred return type: int
-}
-''');
-    LibraryElementForLink library = linker.getLibrary(testDartUri);
-    library.libraryCycleForLink.ensureLinked();
-    ClassElementForLink_Class cls = library.getContainedName('D');
-    expect(cls.methods, hasLength(1));
-    expect(cls.methods[0].returnType.toString(), 'int');
-  }
-
-  void test_inferredTypeFromOutsideBuildUnit_staticField() {
-    var bundle =
-        createPackageBundle('class C { static var f = 0; }', path: '/a.dart');
-    addBundle('/a.ds', bundle);
-    createLinker('import "a.dart"; var x = C.f;', path: '/b.dart');
-    expect(
-        _getVariable(linker.getLibrary(testDartUri).getContainedName('x'))
-            .inferredType
-            .toString(),
-        'int');
-  }
-
-  void test_inferredTypeFromOutsideBuildUnit_topLevelVariable() {
-    var bundle = createPackageBundle('var a = 0;', path: '/a.dart');
-    addBundle('/a.ds', bundle);
-    createLinker('import "a.dart"; var b = a;', path: '/b.dart');
-    expect(
-        _getVariable(linker.getLibrary(testDartUri).getContainedName('b'))
-            .inferredType
-            .toString(),
-        'int');
-  }
-
-  void test_inheritsCovariant_fromBundle() {
-    var bundle = createPackageBundle('''
-class X1 {}
-class X2 extends X1 {}
-class A {
-  void foo(covariant X1 x) {}
-}
-class B extends A {
-  void foo(X2 x) {}
-}
-''', path: '/a.dart');
-    addBundle('/a.ds', bundle);
-
-    // C.foo.x must inherit covariance from B.foo.x, even though it is
-    // resynthesized from the bundle.
-    createLinker('''
-import 'a.dart';
-class C extends B {
-  void foo(X2 x) {}
-}
-''');
-    LibraryElementForLink library = linker.getLibrary(testDartUri);
-    library.libraryCycleForLink.ensureLinked();
-
-    ClassElementForLink_Class C = library.getContainedName('C');
-    expect(C.methods, hasLength(1));
-    MethodElementForLink foo = C.methods[0];
-    expect(foo.parameters, hasLength(1));
-    expect(foo.parameters[0].isCovariant, isTrue);
-  }
-
-  void test_instantiate_param_of_param_to_bounds() {
-    createLinker('''
-class C<T> {}
-class D<T extends num> {}
-final x = new C<D>();
-''');
-    LibraryElementForLink library = linker.getLibrary(testDartUri);
-    library.libraryCycleForLink.ensureLinked();
-    PropertyAccessorElementForLink_Variable x = library.getContainedName('x');
-    ParameterizedType type1 = x.returnType;
-    expect(type1.element.name, 'C');
-    expect(type1.typeArguments, hasLength(1));
-    ParameterizedType type2 = type1.typeArguments[0];
-    expect(type2.element.name, 'D');
-    expect(type2.typeArguments, hasLength(1));
-    DartType type3 = type2.typeArguments[0];
-    expect(type3.toString(), 'num');
-  }
-
-  void test_instantiate_param_to_bounds_class() {
-    createLinker('''
-class C<T extends num> {}
-final x = new C();
-''');
-    LibraryElementForLink library = linker.getLibrary(testDartUri);
-    library.libraryCycleForLink.ensureLinked();
-    PropertyAccessorElementForLink_Variable x = library.getContainedName('x');
-    ParameterizedType type1 = x.returnType;
-    expect(type1.element.name, 'C');
-    expect(type1.typeArguments, hasLength(1));
-    DartType type2 = type1.typeArguments[0];
-    expect(type2.toString(), 'num');
-  }
-
-  void test_instantiate_param_to_bounds_typedef() {
-    createLinker('''
-typedef T F<T extends num>();
-final x = new List<F>();
-''');
-    LibraryElementForLink library = linker.getLibrary(testDartUri);
-    library.libraryCycleForLink.ensureLinked();
-    PropertyAccessorElementForLink_Variable x = library.getContainedName('x');
-    ParameterizedType type1 = x.returnType;
-    expect(type1.element.name, 'List');
-    expect(type1.typeArguments, hasLength(1));
-    FunctionType type2 = type1.typeArguments[0];
-    expect(type2.element.name, 'F');
-    expect(type2.returnType.toString(), 'num');
-  }
-
-  void test_isSimplyBounded_class_in_other_bundle() {
-    var bundle = createPackageBundle('''
-class C<T extends C> {} // Not simply bounded
-class D<T extends D<Null>> {} // Simply bounded
-''', path: '/a.dart');
-    addBundle('/a.ds', bundle);
-
-    createLinker('''
-import 'a.dart';
-class A<T extends C> {} // Not simply bounded
-class B<T extends D> {} // Simply bounded
-''');
-    LibraryElementForLink library = linker.getLibrary(testDartUri);
-    library.libraryCycleForLink.ensureLinked();
-
-    expect(library.getContainedName('A').isSimplyBounded, false);
-    expect(library.getContainedName('B').isSimplyBounded, true);
-  }
-
-  void test_isSimplyBounded_new_typedef_in_other_bundle() {
-    var bundle = createPackageBundle('''
-typedef C<T extends C> = void Function(T x); // Not simply bounded
-typedef D<T extends D<Null>> = void Function(T x); // Simply bounded
-''', path: '/a.dart');
-    addBundle('/a.ds', bundle);
-
-    createLinker('''
-import 'a.dart';
-class A<T extends C> {} // Not simply bounded
-class B<T extends D> {} // Simply bounded
-''');
-    LibraryElementForLink library = linker.getLibrary(testDartUri);
-    library.libraryCycleForLink.ensureLinked();
-
-    expect(library.getContainedName('A').isSimplyBounded, false);
-    expect(library.getContainedName('B').isSimplyBounded, true);
-  }
-
-  void test_isSimplyBounded_old_typedef_in_other_bundle() {
-    var bundle = createPackageBundle('''
-typedef void C<T extends C>(T x); // Not simply bounded
-typedef void D<T extends D<Null>>(T x); // Simply bounded
-''', path: '/a.dart');
-    addBundle('/a.ds', bundle);
-
-    createLinker('''
-import 'a.dart';
-class A<T extends C> {} // Not simply bounded
-class B<T extends D> {} // Simply bounded
-''');
-    LibraryElementForLink library = linker.getLibrary(testDartUri);
-    library.libraryCycleForLink.ensureLinked();
-
-    expect(library.getContainedName('A').isSimplyBounded, false);
-    expect(library.getContainedName('B').isSimplyBounded, true);
-  }
-
-  void test_leastUpperBound_functionAndClass() {
-    createLinker('''
-class C {}
-void f() {}
-var x = {
-  'C': C,
-  'f': f
-};
-''');
-    LibraryElementForLink library = linker.getLibrary(testDartUri);
-    library.libraryCycleForLink.ensureLinked();
-    // No assertions--just make sure it doesn't crash.
-  }
-
-  void test_libraryCycle_ignoresDependenciesOutsideBuildUnit() {
-    createLinker('import "dart:async";');
-    LibraryCycleForLink libraryCycle = testLibrary.libraryCycleForLink;
-    expect(libraryCycle.dependencies, isEmpty);
-    expect(libraryCycle.libraries, [testLibrary]);
-  }
-
-  void test_libraryCycle_linkEnsuresDependenciesLinked() {
-    addNamedSource('/a.dart', 'import "b.dart";');
-    addNamedSource('/b.dart', '');
-    addNamedSource('/c.dart', '');
-    createLinker('import "a.dart"; import "c.dart";');
-    LibraryElementForLink libA = getLibrary('file:///a.dart');
-    LibraryElementForLink libB = getLibrary('file:///b.dart');
-    LibraryElementForLink libC = getLibrary('file:///c.dart');
-    expect(libA.libraryCycleForLink.node.isEvaluated, isFalse);
-    expect(libB.libraryCycleForLink.node.isEvaluated, isFalse);
-    expect(libC.libraryCycleForLink.node.isEvaluated, isFalse);
-    libA.libraryCycleForLink.ensureLinked();
-    expect(libA.libraryCycleForLink.node.isEvaluated, isTrue);
-    expect(libB.libraryCycleForLink.node.isEvaluated, isTrue);
-    expect(libC.libraryCycleForLink.node.isEvaluated, isFalse);
-  }
-
-  void test_libraryCycle_nontrivial() {
-    addNamedSource('/a.dart', 'import "b.dart";');
-    addNamedSource('/b.dart', 'import "a.dart";');
-    createLinker('');
-    LibraryElementForLink libA = getLibrary('file:///a.dart');
-    LibraryElementForLink libB = getLibrary('file:///b.dart');
-    LibraryCycleForLink libraryCycle = libA.libraryCycleForLink;
-    expect(libB.libraryCycleForLink, same(libraryCycle));
-    expect(libraryCycle.dependencies, isEmpty);
-    expect(libraryCycle.libraries, unorderedEquals([libA, libB]));
-  }
-
-  void test_libraryCycle_nontrivial_dependencies() {
-    addNamedSource('/a.dart', '');
-    addNamedSource('/b.dart', '');
-    addNamedSource('/c.dart', 'import "a.dart"; import "d.dart";');
-    addNamedSource('/d.dart', 'import "b.dart"; import "c.dart";');
-    createLinker('');
-    LibraryElementForLink libA = getLibrary('file:///a.dart');
-    LibraryElementForLink libB = getLibrary('file:///b.dart');
-    LibraryElementForLink libC = getLibrary('file:///c.dart');
-    LibraryElementForLink libD = getLibrary('file:///d.dart');
-    LibraryCycleForLink libraryCycle = libC.libraryCycleForLink;
-    expect(libD.libraryCycleForLink, same(libraryCycle));
-    expect(libraryCycle.dependencies,
-        unorderedEquals([libA.libraryCycleForLink, libB.libraryCycleForLink]));
-    expect(libraryCycle.libraries, unorderedEquals([libC, libD]));
-  }
-
-  void test_libraryCycle_nontrivial_via_export() {
-    addNamedSource('/a.dart', 'export "b.dart";');
-    addNamedSource('/b.dart', 'export "a.dart";');
-    createLinker('');
-    LibraryElementForLink libA = getLibrary('file:///a.dart');
-    LibraryElementForLink libB = getLibrary('file:///b.dart');
-    LibraryCycleForLink libraryCycle = libA.libraryCycleForLink;
-    expect(libB.libraryCycleForLink, same(libraryCycle));
-    expect(libraryCycle.dependencies, isEmpty);
-    expect(libraryCycle.libraries, unorderedEquals([libA, libB]));
-  }
-
-  void test_libraryCycle_trivial() {
-    createLinker('');
-    LibraryCycleForLink libraryCycle = testLibrary.libraryCycleForLink;
-    expect(libraryCycle.dependencies, isEmpty);
-    expect(libraryCycle.libraries, [testLibrary]);
-  }
-
-  void test_libraryCycle_trivial_dependencies() {
-    addNamedSource('/a.dart', '');
-    addNamedSource('/b.dart', '');
-    createLinker('import "a.dart"; import "b.dart";');
-    LibraryElementForLink libA = getLibrary('file:///a.dart');
-    LibraryElementForLink libB = getLibrary('file:///b.dart');
-    LibraryCycleForLink libraryCycle = testLibrary.libraryCycleForLink;
-    expect(libraryCycle.dependencies,
-        unorderedEquals([libA.libraryCycleForLink, libB.libraryCycleForLink]));
-    expect(libraryCycle.libraries, [testLibrary]);
-  }
-
-  void test_multiplyInheritedExecutable_differentSignatures() {
-    createLinker('''
-class B {
-  void f() {}
-}
-abstract class I {
-   f();
-}
-class C extends B with I {}
-class D extends C {
-  void f() {}
-}
-''');
-    LibraryElementForLink library = linker.getLibrary(testDartUri);
-    library.libraryCycleForLink.ensureLinked();
-    // No assertions--just make sure it doesn't crash.
-  }
-
-  void test_parameterParentElementForLink_implicitFunctionTypeIndices() {
-    createLinker('void f(a, void g(b, c, d, void h())) {}');
-    TopLevelFunctionElementForLink f = testLibrary.getContainedName('f');
-    expect(f.implicitFunctionTypeIndices, []);
-    ParameterElementForLink g = f.parameters[1];
-    FunctionType gType = g.type;
-    FunctionElementForLink_FunctionTypedParam gTypeElement = gType.element;
-    expect(gTypeElement.implicitFunctionTypeIndices, [1]);
-    ParameterElementForLink h = gTypeElement.parameters[3];
-    FunctionType hType = h.type;
-    FunctionElementForLink_FunctionTypedParam hTypeElement = hType.element;
-    expect(hTypeElement.implicitFunctionTypeIndices, [1, 3]);
-  }
-
-  void test_parameterParentElementForLink_innermostExecutable() {
-    createLinker('void f(void g(void h())) {}');
-    TopLevelFunctionElementForLink f = testLibrary.getContainedName('f');
-    expect(f.typeParameterContext, same(f));
-    ParameterElementForLink g = f.parameters[0];
-    FunctionType gType = g.type;
-    FunctionElementForLink_FunctionTypedParam gTypeElement = gType.element;
-    expect(gTypeElement.typeParameterContext, same(f));
-    ParameterElementForLink h = gTypeElement.parameters[0];
-    FunctionType hType = h.type;
-    FunctionElementForLink_FunctionTypedParam hTypeElement = hType.element;
-    expect(hTypeElement.typeParameterContext, same(f));
-  }
-
-  void test_topLevelFunction_isStatic() {
-    createLinker('f() {}');
-    LibraryElementForLink library = linker.getLibrary(testDartUri);
-    TopLevelFunctionElementForLink f = library.getContainedName('f');
-    expect(f.isStatic, true);
-  }
-
-  void test_topLevelGetter_isStatic() {
-    createLinker('get x => null;');
-    LibraryElementForLink library = linker.getLibrary(testDartUri);
-    PropertyAccessorElementForLink_Executable x = library.getContainedName('x');
-    expect(x.isStatic, true);
-  }
-
-  void test_topLevelSetter_isStatic() {
-    createLinker('void set x(value) {}');
-    LibraryElementForLink library = linker.getLibrary(testDartUri);
-    PropertyAccessorElementForLink_Executable x =
-        library.getContainedName('x=');
-    expect(x.isStatic, true);
-  }
-
-  void test_topLevelVariable_isStatic() {
-    createLinker('var x;');
-    LibraryElementForLink library = linker.getLibrary(testDartUri);
-    PropertyAccessorElementForLink_Variable x = library.getContainedName('x');
-    expect(x.isStatic, true);
-    expect(x.variable.isStatic, true);
-  }
-
-  void test_typeParameter_computeDeBruijnIndex_direct() {
-    createLinker('class C<T, U> {}');
-    ClassElementForLink_Class c = testLibrary.getContainedName('C');
-    TypeParameterElementImpl t = c.typeParameters[0];
-    TypeParameterElementImpl u = c.typeParameters[1];
-    expect(c.computeDeBruijnIndex(t), 2);
-    expect(c.computeDeBruijnIndex(u), 1);
-  }
-
-  void test_typeParameter_computeDeBruijnIndex_indirect() {
-    createLinker('class C<T, U> { f<V, W>() {} }');
-    ClassElementForLink_Class c = testLibrary.getContainedName('C');
-    MethodElementForLink f = c.methods[0];
-    TypeParameterElementImpl t = c.typeParameters[0];
-    TypeParameterElementImpl u = c.typeParameters[1];
-    expect(f.computeDeBruijnIndex(t), 4);
-    expect(f.computeDeBruijnIndex(u), 3);
-  }
-
-  void test_typeParameter_computeDeBruijnIndex_reversed() {
-    createLinker('class C<T, U> { f<V, W>() {} }');
-    ClassElementForLink_Class c = testLibrary.getContainedName('C');
-    MethodElementForLink f = c.methods[0];
-    TypeParameterElementImpl v = f.typeParameters[0];
-    TypeParameterElementImpl w = f.typeParameters[1];
-    expect(c.computeDeBruijnIndex(v), isNull);
-    expect(c.computeDeBruijnIndex(w), isNull);
-  }
-
-  void test_typeParameter_computeDeBruijnIndex_unrelated() {
-    createLinker('class C<T, U> {} class D<V, W> {}');
-    ClassElementForLink_Class c = testLibrary.getContainedName('C');
-    ClassElementForLink_Class d = testLibrary.getContainedName('D');
-    TypeParameterElementImpl t = c.typeParameters[0];
-    TypeParameterElementImpl u = c.typeParameters[1];
-    TypeParameterElementImpl v = d.typeParameters[0];
-    TypeParameterElementImpl w = d.typeParameters[1];
-    expect(c.computeDeBruijnIndex(v), isNull);
-    expect(c.computeDeBruijnIndex(w), isNull);
-    expect(d.computeDeBruijnIndex(t), isNull);
-    expect(d.computeDeBruijnIndex(u), isNull);
-  }
-
-  void test_variable_initializer_presence() {
-    // Any variable declaration with an initializer should have a non-null value
-    // for `initializer`, regardless of whether it is constant and regardless of
-    // whether it has an explicit type.
-    createLinker('''
-const int c = 0;
-int i = 0;
-int j;
-var v = 0;
-''');
-    LibraryElementForLink library = linker.getLibrary(testDartUri);
-    PropertyAccessorElementForLink_Variable c = library.getContainedName('c');
-    expect(c.variable.initializer, isNotNull);
-    PropertyAccessorElementForLink_Variable i = library.getContainedName('i');
-    expect(i.variable.initializer, isNotNull);
-    PropertyAccessorElementForLink_Variable j = library.getContainedName('j');
-    expect(j.variable.initializer, isNull);
-    PropertyAccessorElementForLink_Variable v = library.getContainedName('v');
-    expect(v.variable.initializer, isNotNull);
-  }
-
-  VariableElementForLink _getVariable(ReferenceableElementForLink element) {
-    return (element as PropertyAccessorElementForLink_Variable).variable;
-  }
-
-  /**
-   * Finds the first inferred type stored in [unit] whose slot matches [slot].
-   */
-  EntityRef _lookupInferredType(LinkedUnit unit, int slot) {
-    for (EntityRef ref in unit.types) {
-      if (ref.slot == slot) {
-        return ref;
-      }
-    }
-    return null;
-  }
-}
diff --git a/pkg/analyzer/test/src/summary/prelinker_test.dart b/pkg/analyzer/test/src/summary/prelinker_test.dart
deleted file mode 100644
index aa47aaaa..0000000
--- a/pkg/analyzer/test/src/summary/prelinker_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 'package:analyzer/src/dart/analysis/driver.dart';
-import 'package:test/test.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-import 'summary_common.dart';
-import 'test_strategies.dart';
-
-main() {
-  if (AnalysisDriver.useSummary2) {
-    test('fake', () {});
-    return;
-  }
-  defineReflectiveSuite(() {
-    defineReflectiveTests(PrelinkerTest);
-  });
-}
-
-/// Tests for the pre-linker which exercise it using the old (two-phase) summary
-/// generation strategy.
-///
-/// TODO(paulberry): eliminate these tests once we have transitioned over to
-/// one-step summary generation.
-@reflectiveTest
-class PrelinkerTest extends SummaryBlackBoxTestStrategyPrelink
-    with SummaryTestCases {}
diff --git a/pkg/analyzer/test/src/summary/resolved_ast_printer.dart b/pkg/analyzer/test/src/summary/resolved_ast_printer.dart
new file mode 100644
index 0000000..551cad1
--- /dev/null
+++ b/pkg/analyzer/test/src/summary/resolved_ast_printer.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 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
+
+/// Prints AST as a tree, with properties and children.
+class ResolvedAstPrinter extends ThrowingAstVisitor<void> {
+  StringSink _sink;
+  String _indent = '';
+
+  ResolvedAstPrinter(StringSink sink, String indent)
+      : _sink = sink,
+        _indent = indent;
+
+  @override
+  void visitCompilationUnit(CompilationUnit node) {
+    super.visitCompilationUnit(node);
+  }
+
+  @override
+  void visitIntegerLiteral(IntegerLiteral node) {
+    _writeln('IntegerLiteral(${node.literal.lexeme})');
+    _withIndent(() {
+      _writeln2('staticType: ', node.staticType);
+    });
+  }
+
+  @override
+  void visitListLiteral(ListLiteral node) {
+    _writeln('ListLiteral');
+    _withIndent(() {
+      _writeln2('isConst: ', node.isConst);
+      _writeln2('staticType: ', node.staticType);
+      _writeTypeArgumentList('typeArguments', node.typeArguments);
+      _writeNodeList('elements', node.elements);
+    });
+  }
+
+  void _withIndent(void Function() f) {
+    var indent = _indent;
+    _indent = '$_indent  ';
+    f();
+    _indent = indent;
+  }
+
+  void _writeln(String line) {
+    _sink.write('$_indent');
+    _sink.writeln(line);
+  }
+
+  void _writeln2(String prefix, Object o) {
+    _sink.write('$_indent');
+    _sink.write(prefix);
+    _sink.writeln(o);
+  }
+
+  void _writeNodeList(String name, NodeList nodeList) {
+    if (nodeList.isNotEmpty) {
+      _writeln(name);
+      _withIndent(() {
+        nodeList.accept(this);
+      });
+    }
+  }
+
+  void _writeTypeArgumentList(String name, TypeArgumentList node) {
+    if (node != null) {
+      _writeln(name);
+      _withIndent(() {
+        node.arguments?.accept(this);
+      });
+    }
+  }
+}
diff --git a/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart b/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart
deleted file mode 100644
index 190954b..0000000
--- a/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart
+++ /dev/null
@@ -1,98 +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 'package:analyzer/src/dart/analysis/driver.dart';
-import 'package:test/test.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-import 'element_text.dart';
-import 'resynthesize_common.dart';
-import 'test_strategies.dart';
-
-main() {
-  if (AnalysisDriver.useSummary2) {
-    test('fake', () {});
-    return;
-  }
-  defineReflectiveSuite(() {
-    defineReflectiveTests(ApplyCheckElementTextReplacements);
-    defineReflectiveTests(ResynthesizeAstStrongTest);
-  });
-}
-
-@reflectiveTest
-class ApplyCheckElementTextReplacements {
-  test_applyReplacements() {
-    applyCheckElementTextReplacements();
-  }
-}
-
-@reflectiveTest
-class ResynthesizeAstStrongTest extends ResynthesizeTestStrategyTwoPhase
-    with ResynthesizeTestCases, GetElementTestCases, ResynthesizeTestHelpers {
-  @override
-  @failingTest
-  test_class_constructor_field_formal_functionTyped_withReturnType_generic() async {
-    await super
-        .test_class_constructor_field_formal_functionTyped_withReturnType_generic();
-  }
-
-  @failingTest // See dartbug.com/32290
-  test_const_constructor_inferred_args() =>
-      super.test_const_constructor_inferred_args();
-
-  @failingTest // See dartbug.com/33441
-  test_const_list_inferredType() => super.test_const_list_inferredType();
-
-  @failingTest // See dartbug.com/33441
-  test_const_map_inferredType() => super.test_const_map_inferredType();
-
-  @FailingTest(
-      reason: "NoSuchMethodError: Class 'ExtensionElementForLink' has no "
-          "instance method 'getGetter' with matching arguments.")
-  test_const_reference_staticMethod_ofExtension() async {
-    await super.test_const_reference_staticMethod_ofExtension();
-  }
-
-  @failingTest // See dartbug.com/33441
-  test_const_set_inferredType() => super.test_const_set_inferredType();
-
-  @override
-  @failingTest
-  test_defaultValue_refersToExtension_method_inside() async {
-    await super.test_defaultValue_refersToExtension_method_inside();
-  }
-
-  @override
-  @failingTest
-  test_defaultValue_refersToGenericClass() async {
-    await super.test_defaultValue_refersToGenericClass();
-  }
-
-  @FailingTest(
-    reason: 'Inference for extension fields is not implemented in summary1.',
-  )
-  test_duplicateDeclaration_extension() async {
-    await super.test_duplicateDeclaration_extension();
-  }
-
-  @FailingTest(
-    reason: 'Inference for extension fields is not implemented in summary1.',
-  )
-  test_extension_field_inferredType_const() async {
-    await super.test_extension_field_inferredType_const();
-  }
-
-  @override
-  @failingTest
-  test_infer_generic_typedef_complex() async {
-    await super.test_infer_generic_typedef_complex();
-  }
-
-  @override
-  @failingTest
-  test_syntheticFunctionType_inGenericClass() async {
-    await super.test_syntheticFunctionType_inGenericClass();
-  }
-}
diff --git a/pkg/analyzer/test/src/summary/resynthesize_common.dart b/pkg/analyzer/test/src/summary/resynthesize_common.dart
index d3e4e8a..86a1ada 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_common.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_common.dart
@@ -11,17 +11,13 @@
 import 'package:analyzer/dart/element/nullability_suffix.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';
 import 'package:analyzer/src/test_utilities/mock_sdk.dart';
 import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
 import 'package:test/test.dart';
 
-import '../../util/element_type_matchers.dart';
 import 'element_text.dart';
 import 'test_strategies.dart';
 
@@ -81,126 +77,6 @@
     testSource = addSource(testFile, code);
     return testSource;
   }
-
-  /**
-   * Verify that the [resynthesizer] didn't do any unnecessary work when
-   * resynthesizing the library with the [expectedLibraryUri].
-   */
-  void checkMinimalResynthesisWork(TestSummaryResynthesizer resynthesizer,
-      Uri expectedLibraryUri, List<Uri> expectedUnitUriList) {
-    // Check that no other summaries needed to be resynthesized to resynthesize
-    // the library element.
-    expect(resynthesizer.resynthesisCount, 3);
-    // Check that the only linked summary consulted was that for [uri].
-    expect(resynthesizer.linkedSummariesRequested, hasLength(1));
-    expect(resynthesizer.linkedSummariesRequested.first,
-        expectedLibraryUri.toString());
-    // Check that the only unlinked summaries consulted were those for the
-    // library in question.
-    var expectedUnitUriStrSet =
-        expectedUnitUriList.map((uri) => uri.toString()).toSet();
-    for (String requestedUri in resynthesizer.unlinkedSummariesRequested) {
-      expect(expectedUnitUriStrSet, contains(requestedUri));
-    }
-  }
-}
-
-/// Mixin containing test cases exercising summary resynthesis.  Intended to be
-/// applied to a class implementing [ResynthesizeTestStrategy], along with the
-/// mixin [ResynthesizeTestHelpers].
-mixin GetElementTestCases implements ResynthesizeTestHelpers {
-  test_getElement_class() async {
-    var resynthesized = _validateGetElement(
-      'class C { m() {} }',
-      ['C'],
-    );
-    expect(resynthesized, isClassElement);
-  }
-
-  test_getElement_constructor_named() async {
-    var resynthesized = _validateGetElement(
-      'class C { C.named(); }',
-      ['C', 'named'],
-    );
-    expect(resynthesized, isConstructorElement);
-  }
-
-  test_getElement_constructor_unnamed() async {
-    var resynthesized = _validateGetElement(
-      'class C { C(); }',
-      ['C', ''],
-    );
-    expect(resynthesized, isConstructorElement);
-  }
-
-  test_getElement_field() async {
-    var resynthesized = _validateGetElement(
-      'class C { var f; }',
-      ['C', 'f'],
-    );
-    expect(resynthesized, isFieldElement);
-  }
-
-  test_getElement_getter() async {
-    var resynthesized = _validateGetElement(
-      'class C { get f => null; }',
-      ['C', 'f?'],
-    );
-    expect(resynthesized, isPropertyAccessorElement);
-  }
-
-  test_getElement_method() async {
-    var resynthesized = _validateGetElement(
-      'class C { m() {} }',
-      ['C', 'm'],
-    );
-    expect(resynthesized, isMethodElement);
-  }
-
-  test_getElement_operator() async {
-    var resynthesized = _validateGetElement(
-      'class C { operator+(x) => null; }',
-      ['C', '+'],
-    );
-    expect(resynthesized, isMethodElement);
-  }
-
-  test_getElement_setter() async {
-    var resynthesized = _validateGetElement(
-      'class C { void set f(value) {} }',
-      ['C', 'f='],
-    );
-    expect(resynthesized, isPropertyAccessorElement);
-  }
-
-  test_getElement_unit() async {
-    var resynthesized = _validateGetElement('class C {}', []);
-    expect(resynthesized, isCompilationUnitElement);
-  }
-
-  /**
-   * Encode the library [text] into a summary and then use
-   * [TestSummaryResynthesizer.getElement] to retrieve just the element with
-   * the specified [names] from the resynthesized summary.
-   */
-  Element _validateGetElement(String text, List<String> names) {
-    Source source = addTestSource(text);
-    SummaryResynthesizer resynthesizer = encodeLibrary(source);
-
-    var locationComponents = [
-      source.uri.toString(),
-      source.uri.toString(),
-    ]..addAll(names);
-    var location = ElementLocationImpl.con3(locationComponents);
-
-    Element result = resynthesizer.getElement(location);
-    checkMinimalResynthesisWork(resynthesizer, source.uri, [source.uri]);
-    // Check that no other summaries needed to be resynthesized to resynthesize
-    // the library element.
-    expect(resynthesizer.resynthesisCount, 3);
-    expect(result.location, location);
-    return result;
-  }
 }
 
 /// Mixin containing test cases exercising summary resynthesis.  Intended to be
@@ -6540,6 +6416,35 @@
 ''');
   }
 
+  test_finalField_hasConstConstructor() async {
+    var library = await checkLibrary(r'''
+class C1  {
+  final List<int> f1 = const [];
+  const C1();
+}
+class C2  {
+  final List<int> f2 = const [];
+  C2();
+}
+''');
+    checkElementText(
+        library,
+        r'''
+class C1 {
+  final List<int> f1 =
+    ListLiteral
+      isConst: true
+      staticType: List<int>
+  const C1();
+}
+class C2 {
+  final List<int> f2;
+  C2();
+}
+''',
+        withFullyResolvedAst: true);
+  }
+
   test_function_async() async {
     var library = await checkLibrary(r'''
 import 'dart:async';
@@ -8029,6 +7934,22 @@
 ''');
   }
 
+  test_instantiateToBounds_issue38498() async {
+    var library = await checkLibrary('''
+class A<R extends B> {
+  final values = <B>[];
+}
+class B<T extends num> {}
+''');
+    checkElementText(library, r'''
+class A<R extends B<num>> {
+  final List<B<num>> values;
+}
+class B<T extends num> {
+}
+''');
+  }
+
   test_instantiateToBounds_simple() async {
     var library = await checkLibrary('''
 class C<T extends num> {}
@@ -11509,60 +11430,9 @@
 mixin ResynthesizeTestHelpers implements ResynthesizeTestStrategy {
   Future<LibraryElementImpl> checkLibrary(String text,
       {bool allowErrors: false, bool dumpSummaries: false}) async {
-    Source source = addTestSource(text);
-    SummaryResynthesizer resynthesizer = encodeLibrary(source);
-    return resynthesizer.getLibraryElement(source.uri.toString());
-  }
-}
-
-class TestSummaryResynthesizer extends SummaryResynthesizer {
-  final Map<String, UnlinkedUnit> unlinkedSummaries;
-  final Map<String, LinkedLibrary> linkedSummaries;
-  final bool allowMissingFiles;
-
-  /**
-   * The set of uris for which unlinked summaries have been requested using
-   * [getUnlinkedSummary].
-   */
-  final Set<String> unlinkedSummariesRequested = new Set<String>();
-
-  /**
-   * The set of uris for which linked summaries have been requested using
-   * [getLinkedSummary].
-   */
-  final Set<String> linkedSummariesRequested = new Set<String>();
-
-  TestSummaryResynthesizer(AnalysisContextImpl context, this.unlinkedSummaries,
-      this.linkedSummaries, this.allowMissingFiles)
-      : super(context, null, context.sourceFactory, true) {
-    // Clear after resynthesizing TypeProvider in super().
-    unlinkedSummariesRequested.clear();
-    linkedSummariesRequested.clear();
-    context.typeProvider = typeProvider;
-  }
-
-  @override
-  LinkedLibrary getLinkedSummary(String uri) {
-    linkedSummariesRequested.add(uri);
-    LinkedLibrary serializedLibrary = linkedSummaries[uri];
-    if (serializedLibrary == null && !allowMissingFiles) {
-      fail('Unexpectedly tried to get linked summary for $uri');
-    }
-    return serializedLibrary;
-  }
-
-  @override
-  UnlinkedUnit getUnlinkedSummary(String uri) {
-    unlinkedSummariesRequested.add(uri);
-    UnlinkedUnit serializedUnit = unlinkedSummaries[uri];
-    if (serializedUnit == null && !allowMissingFiles) {
-      fail('Unexpectedly tried to get unlinked summary for $uri');
-    }
-    return serializedUnit;
-  }
-
-  @override
-  bool hasLibrarySummary(String uri) {
-    return true;
+    throw 42;
+//    Source source = addTestSource(text);
+//    SummaryResynthesizer resynthesizer = encodeLibrary(source);
+//    return resynthesizer.getLibraryElement(source.uri.toString());
   }
 }
diff --git a/pkg/analyzer/test/src/summary/summarize_ast_strong_test.dart b/pkg/analyzer/test/src/summary/summarize_ast_strong_test.dart
deleted file mode 100644
index c6d4b8d..0000000
--- a/pkg/analyzer/test/src/summary/summarize_ast_strong_test.dart
+++ /dev/null
@@ -1,84 +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 'package:analyzer/src/dart/analysis/driver.dart';
-import 'package:test/test.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-import 'summary_common.dart';
-import 'test_strategies.dart';
-
-main() {
-  if (AnalysisDriver.useSummary2) {
-    test('fake', () {});
-    return;
-  }
-  defineReflectiveSuite(() {
-    defineReflectiveTests(LinkedSummarizeAstStrongTest);
-  });
-}
-
-@reflectiveTest
-class LinkedSummarizeAstStrongTest extends SummaryBlackBoxTestStrategyTwoPhase
-    with SummaryTestCases {
-  @override
-  @failingTest
-  test_closure_executable_with_imported_return_type() {
-    super.test_closure_executable_with_imported_return_type();
-  }
-
-  @override
-  @failingTest
-  test_closure_executable_with_return_type_from_closure() {
-    super.test_closure_executable_with_return_type_from_closure();
-  }
-
-  @override
-  @failingTest
-  test_closure_executable_with_unimported_return_type() {
-    super.test_closure_executable_with_unimported_return_type();
-  }
-
-  @override
-  @failingTest
-  test_initializer_executable_with_bottom_return_type() {
-    super.test_initializer_executable_with_bottom_return_type();
-  }
-
-  @override
-  @failingTest
-  test_initializer_executable_with_imported_return_type() {
-    super.test_initializer_executable_with_imported_return_type();
-  }
-
-  @override
-  @failingTest
-  test_initializer_executable_with_return_type_from_closure() {
-    super.test_initializer_executable_with_return_type_from_closure();
-  }
-
-  @override
-  @failingTest
-  test_initializer_executable_with_return_type_from_closure_field() {
-    super.test_initializer_executable_with_return_type_from_closure_field();
-  }
-
-  @override
-  @failingTest
-  test_initializer_executable_with_unimported_return_type() {
-    super.test_initializer_executable_with_unimported_return_type();
-  }
-
-  @override
-  @failingTest
-  test_syntheticFunctionType_genericClosure() {
-    super.test_syntheticFunctionType_genericClosure();
-  }
-
-  @override
-  @failingTest
-  test_syntheticFunctionType_inGenericClass() {
-    super.test_syntheticFunctionType_inGenericClass();
-  }
-}
diff --git a/pkg/analyzer/test/src/summary/summary_common.dart b/pkg/analyzer/test/src/summary/summary_common.dart
deleted file mode 100644
index 10f6ccd..0000000
--- a/pkg/analyzer/test/src/summary/summary_common.dart
+++ /dev/null
@@ -1,11856 +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 'package:analyzer/dart/analysis/features.dart';
-import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/error/listener.dart';
-import 'package:analyzer/src/dart/scanner/reader.dart';
-import 'package:analyzer/src/dart/scanner/scanner.dart';
-import 'package:analyzer/src/generated/parser.dart';
-import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/generated/source_io.dart';
-import 'package:analyzer/src/string_source.dart';
-import 'package:analyzer/src/summary/base.dart';
-import 'package:analyzer/src/summary/idl.dart';
-import 'package:analyzer/src/summary/public_namespace_computer.dart'
-    as public_namespace;
-import 'package:analyzer/src/summary/summarize_const_expr.dart';
-import 'package:test/test.dart';
-
-import 'test_strategies.dart';
-
-/// Convert a summary object (or a portion of one) into a canonical form that
-/// can be easily compared using [expect].  If [orderByName] is true, and the
-/// object is a [List], it is sorted by the `name` field of its elements.
-Object canonicalize(Object obj, {bool orderByName: false}) {
-  if (obj is SummaryClass) {
-    Map<String, Object> result = <String, Object>{};
-    obj.toMap().forEach((String key, Object value) {
-      bool orderByName = false;
-      if (obj is UnlinkedPublicNamespace && key == 'names' ||
-          obj is UnlinkedPublicName && key == 'members') {
-        orderByName = true;
-      }
-      result[key] = canonicalize(value, orderByName: orderByName);
-    });
-    return result;
-  } else if (obj is List) {
-    List<Object> result = <Object>[];
-    for (Object item in obj) {
-      result.add(canonicalize(item));
-    }
-    if (orderByName) {
-      result.sort((Object a, Object b) {
-        if (a is Map && b is Map) {
-          return Comparable.compare(a['name'], b['name']);
-        } else {
-          return 0;
-        }
-      });
-    }
-    return result;
-  } else if (obj is String || obj is num || obj is bool) {
-    return obj;
-  } else {
-    return obj.toString();
-  }
-}
-
-UnlinkedPublicNamespace computePublicNamespaceFromText(
-    String text, Source source, FeatureSet featureSet) {
-  CharacterReader reader = new CharSequenceReader(text);
-  Scanner scanner =
-      new Scanner(source, reader, AnalysisErrorListener.NULL_LISTENER)
-        ..configureFeatures(featureSet);
-  Parser parser = new Parser(source, AnalysisErrorListener.NULL_LISTENER,
-      featureSet: featureSet);
-  CompilationUnit unit = parser.parseCompilationUnit(scanner.tokenize());
-  UnlinkedPublicNamespace namespace = new UnlinkedPublicNamespace.fromBuffer(
-      public_namespace.computePublicNamespace(unit).toBuffer());
-  return namespace;
-}
-
-/// Type of a function that validates an [EntityRef].
-typedef void _EntityRefValidator(EntityRef entityRef);
-
-/// Test cases that exercise summary generation in a black-box fashion.
-///
-/// These test cases may be mixed into any class derived from
-/// [SummaryBlackBoxTestStrategy], allowing summary generation to be unit-tested
-/// in a variety of ways.
-mixin SummaryTestCases implements SummaryBlackBoxTestStrategy {
-  /// Get access to the linked defining compilation unit.
-  LinkedUnit get definingUnit => linked.units[0];
-
-  FeatureSet get disableNnbd => FeatureSet.forTesting(sdkVersion: '2.2.2');
-
-  FeatureSet get enableNnbd =>
-      FeatureSet.forTesting(additionalFeatures: [Feature.non_nullable]);
-
-  /// TODO(scheglov) rename "Const" to "Expr" everywhere
-  void assertUnlinkedConst(UnlinkedExpr constExpr, String sourceRepresentation,
-      {bool isValidConst: true,
-      List<UnlinkedExprOperation> operators: const <UnlinkedExprOperation>[],
-      List<UnlinkedExprAssignOperator> assignmentOperators:
-          const <UnlinkedExprAssignOperator>[],
-      List<int> ints: const <int>[],
-      List<double> doubles: const <double>[],
-      List<String> strings: const <String>[],
-      List<_EntityRefValidator> referenceValidators:
-          const <_EntityRefValidator>[],
-      bool forTypeInferenceOnly: false}) {
-    if (forTypeInferenceOnly && !containsNonConstExprs) {
-      expect(constExpr, isNull);
-      return;
-    }
-    expect(constExpr, isNotNull);
-    expect(constExpr.sourceRepresentation,
-        _normalizeTokenString(sourceRepresentation));
-    expect(constExpr.isValidConst, isValidConst);
-    expect(constExpr.operations, operators);
-    expect(constExpr.ints, ints);
-    expect(constExpr.doubles, doubles);
-    expect(constExpr.strings, strings);
-    expect(constExpr.assignmentOperators, assignmentOperators);
-    expect(constExpr.references, hasLength(referenceValidators.length));
-    for (int i = 0; i < referenceValidators.length; i++) {
-      referenceValidators[i](constExpr.references[i]);
-    }
-  }
-
-  /// Check that [annotations] contains a single entry which is a reference to
-  /// a top level variable called `a` in the current library.
-  void checkAnnotationA(List<UnlinkedExpr> annotations) {
-    expect(annotations, hasLength(1));
-    assertUnlinkedConst(annotations[0], 'a', operators: [
-      UnlinkedExprOperation.pushReference
-    ], referenceValidators: [
-      (EntityRef r) => checkTypeRef(r, null, 'a',
-          expectedKind: ReferenceKind.topLevelPropertyAccessor)
-    ]);
-  }
-
-  void checkConstCycle(String className,
-      {String name: '', bool hasCycle: true}) {
-    UnlinkedClass cls = findClass(className);
-    int constCycleSlot =
-        findExecutable(name, executables: cls.executables).constCycleSlot;
-    expect(constCycleSlot, isNot(0));
-    if (!skipFullyLinkedData) {
-      expect(
-          definingUnit.constCycles,
-          hasCycle
-              ? contains(constCycleSlot)
-              : isNot(contains(constCycleSlot)));
-    }
-  }
-
-  /// Verify that the [dependency]th element of the dependency table represents
-  /// a file reachable via the given [absoluteUri].
-  void checkDependency(int dependency, String absoluteUri) {
-    expect(dependency, new TypeMatcher<int>());
-    expect(linked.dependencies[dependency].uri, absoluteUri);
-  }
-
-  /// Verify that the given [dependency] lists the given
-  /// [relativeUris] as its parts.
-  void checkDependencyParts(
-      LinkedDependency dependency, List<String> relativeUris) {
-    expect(dependency.parts, relativeUris);
-  }
-
-  /// Check that the given [documentationComment] matches the first
-  /// Javadoc-style comment found in [text].
-  ///
-  /// Note that the algorithm for finding the Javadoc-style comment in [text] is
-  /// a simple-minded text search; it is easily confused by corner cases such as
-  /// strings containing comments, nested comments, etc.
-  void checkDocumentationComment(
-      UnlinkedDocumentationComment documentationComment, String text) {
-    expect(documentationComment, isNotNull);
-    int commentStart = text.indexOf('/*');
-    expect(commentStart, isNot(-1));
-    int commentEnd = text.indexOf('*/');
-    expect(commentEnd, isNot(-1));
-    commentEnd += 2;
-    String expectedCommentText =
-        text.substring(commentStart, commentEnd).replaceAll('\r\n', '\n');
-    expect(documentationComment.text, expectedCommentText);
-  }
-
-  /// Verify that the given [typeRef] represents the type `dynamic`.
-  void checkDynamicTypeRef(EntityRef typeRef) {
-    checkTypeRef(typeRef, null, 'dynamic');
-  }
-
-  /// Verify that the given [exportName] represents a reference to an entity
-  /// declared in a file reachable via [absoluteUri], having name [expectedName].
-  /// [expectedKind] is the kind of object referenced. [expectedTargetUnit] is
-  /// the index of the compilation unit in which the target of the [exportName]
-  /// is expected to appear; if not specified it is assumed to be the defining
-  /// compilation unit.
-  void checkExportName(LinkedExportName exportName, String absoluteUri,
-      String expectedName, ReferenceKind expectedKind,
-      {int expectedTargetUnit: 0}) {
-    expect(exportName, new TypeMatcher<LinkedExportName>());
-    // Exported names must come from other libraries.
-    expect(exportName.dependency, isNot(0));
-    checkDependency(exportName.dependency, absoluteUri);
-    expect(exportName.name, expectedName);
-    expect(exportName.kind, expectedKind);
-    expect(exportName.unit, expectedTargetUnit);
-  }
-
-  /// Verify that the dependency table contains an entry for a file reachable
-  /// via the given [relativeUri].  If [fullyLinked] is
-  /// `true`, then the dependency should be a fully-linked dependency; otherwise
-  /// it should be a prelinked dependency.
-  ///
-  /// The index of the [LinkedDependency] is returned.
-  int checkHasDependency(String relativeUri, {bool fullyLinked: false}) {
-    List<String> found = <String>[];
-    for (int i = 0; i < linked.dependencies.length; i++) {
-      LinkedDependency dep = linked.dependencies[i];
-      if (dep.uri == relativeUri) {
-        if (fullyLinked) {
-          expect(i, greaterThanOrEqualTo(linked.numPrelinkedDependencies));
-        } else {
-          expect(i, lessThan(linked.numPrelinkedDependencies));
-        }
-        return i;
-      }
-      found.add(dep.uri);
-    }
-    fail('Did not find dependency $relativeUri.  Found: $found');
-  }
-
-  /// Test an inferred type.  If [onlyInStrongMode] is `true` (the default) and
-  /// strong mode is disabled, verify that the given [slotId] exists and has no
-  /// associated type.  Otherwise, behave as in [checkLinkedTypeSlot].
-  void checkInferredTypeSlot(
-      int slotId, String absoluteUri, String expectedName,
-      {int numTypeArguments: 0,
-      ReferenceKind expectedKind: ReferenceKind.classOrEnum,
-      int expectedTargetUnit: 0,
-      LinkedUnit linkedSourceUnit,
-      UnlinkedUnit unlinkedSourceUnit,
-      int numTypeParameters: 0,
-      bool onlyInStrongMode: true}) {
-    checkLinkedTypeSlot(slotId, absoluteUri, expectedName,
-        numTypeArguments: numTypeArguments,
-        expectedKind: expectedKind,
-        expectedTargetUnit: expectedTargetUnit,
-        linkedSourceUnit: linkedSourceUnit,
-        unlinkedSourceUnit: unlinkedSourceUnit,
-        numTypeParameters: numTypeParameters);
-  }
-
-  /// Verify that the dependency table *does not* contain any entries for a file
-  /// reachable via the given [relativeUri].
-  void checkLacksDependency(String relativeUri) {
-    for (LinkedDependency dep in linked.dependencies) {
-      if (dep.uri == relativeUri) {
-        fail('Unexpected dependency found: $relativeUri');
-      }
-    }
-  }
-
-  /// Verify that the given [typeRef] represents the type `dynamic`.
-  void checkLinkedDynamicTypeRef(EntityRef typeRef) {
-    checkLinkedTypeRef(typeRef, null, 'dynamic');
-  }
-
-  /// Verify that the given [typeRef] represents a reference to a type declared
-  /// in a file reachable via [absoluteUri], having name [expectedName].  Verify
-  /// that the number of type arguments is equal to [numTypeArguments].
-  /// [expectedKind] is the kind of object referenced.  [linkedSourceUnit] and
-  /// [unlinkedSourceUnit] refer to the compilation unit within which the
-  /// [typeRef] appears; if not specified they are assumed to refer to the
-  /// defining compilation unit. [expectedTargetUnit] is the index of the
-  /// compilation unit in which the target of the [typeRef] is expected to
-  /// appear; if not specified it is assumed to be the defining compilation unit.
-  /// [numTypeParameters] is the number of type parameters of the thing being
-  /// referred to.
-  void checkLinkedTypeRef(
-      EntityRef typeRef, String absoluteUri, String expectedName,
-      {int numTypeArguments: 0,
-      ReferenceKind expectedKind: ReferenceKind.classOrEnum,
-      int expectedTargetUnit: 0,
-      LinkedUnit linkedSourceUnit,
-      UnlinkedUnit unlinkedSourceUnit,
-      int numTypeParameters: 0}) {
-    linkedSourceUnit ??= definingUnit;
-    expect(typeRef, isNotNull,
-        reason: 'No entry in linkedSourceUnit.types matching slotId');
-    expect(typeRef.paramReference, 0);
-    int index = typeRef.reference;
-    expect(typeRef.typeArguments, hasLength(numTypeArguments));
-    checkReferenceIndex(index, absoluteUri, expectedName,
-        expectedKind: expectedKind,
-        expectedTargetUnit: expectedTargetUnit,
-        linkedSourceUnit: linkedSourceUnit,
-        unlinkedSourceUnit: unlinkedSourceUnit,
-        numTypeParameters: numTypeParameters);
-  }
-
-  /// Verify that the given [slotId] represents a reference to a type declared
-  /// in a file reachable via [absoluteUri], having name [expectedName].  Verify
-  /// that the number of type arguments is equal to [numTypeArguments].
-  /// [expectedKind] is the kind of object referenced.  [linkedSourceUnit] and
-  /// [unlinkedSourceUnit] refer to the compilation unit within which the
-  /// [typeRef] appears; if not specified they are assumed to refer to the
-  /// defining compilation unit. [expectedTargetUnit] is the index of the
-  /// compilation unit in which the target of the [typeRef] is expected to
-  /// appear; if not specified it is assumed to be the defining compilation unit.
-  /// [numTypeParameters] is the number of type parameters of the thing being
-  /// referred to.
-  void checkLinkedTypeSlot(int slotId, String absoluteUri, String expectedName,
-      {int numTypeArguments: 0,
-      ReferenceKind expectedKind: ReferenceKind.classOrEnum,
-      int expectedTargetUnit: 0,
-      LinkedUnit linkedSourceUnit,
-      UnlinkedUnit unlinkedSourceUnit,
-      int numTypeParameters: 0}) {
-    // Slot ids should be nonzero, since zero means "no associated slot".
-    expect(slotId, isNot(0));
-    if (skipFullyLinkedData) {
-      return;
-    }
-    linkedSourceUnit ??= definingUnit;
-    checkLinkedTypeRef(
-        getTypeRefForSlot(slotId, linkedSourceUnit: linkedSourceUnit),
-        absoluteUri,
-        expectedName,
-        numTypeArguments: numTypeArguments,
-        expectedKind: expectedKind,
-        expectedTargetUnit: expectedTargetUnit,
-        linkedSourceUnit: linkedSourceUnit,
-        unlinkedSourceUnit: unlinkedSourceUnit,
-        numTypeParameters: numTypeParameters);
-  }
-
-  /// Verify that the given [typeRef] represents a reference to a type parameter
-  /// having the given [deBruijnIndex].
-  void checkParamTypeRef(EntityRef typeRef, int deBruijnIndex) {
-    expect(typeRef, new TypeMatcher<EntityRef>());
-    expect(typeRef.reference, 0);
-    expect(typeRef.typeArguments, isEmpty);
-    expect(typeRef.paramReference, deBruijnIndex);
-  }
-
-  /// Verify that [prefixReference] is a valid reference to a prefix having the
-  /// given [name].
-  void checkPrefix(int prefixReference, String name) {
-    expect(prefixReference, isNot(0));
-    expect(unlinkedUnits[0].references[prefixReference].prefixReference, 0);
-    expect(unlinkedUnits[0].references[prefixReference].name, name);
-    expect(definingUnit.references[prefixReference].dependency, 0);
-    expect(definingUnit.references[prefixReference].kind, ReferenceKind.prefix);
-    expect(definingUnit.references[prefixReference].unit, 0);
-  }
-
-  /// Check the data structures that are reachable from an index in the
-  /// references table.  If the reference in question is an explicit
-  /// reference, return the [UnlinkedReference] that is used to make the
-  /// explicit reference.  If the type reference in question is an implicit
-  /// reference, return `null`.
-  UnlinkedReference checkReferenceIndex(
-      int referenceIndex, String absoluteUri, String expectedName,
-      {ReferenceKind expectedKind: ReferenceKind.classOrEnum,
-      int expectedTargetUnit: 0,
-      LinkedUnit linkedSourceUnit,
-      UnlinkedUnit unlinkedSourceUnit,
-      int numTypeParameters: 0,
-      bool unresolvedHasName: false}) {
-    linkedSourceUnit ??= definingUnit;
-    unlinkedSourceUnit ??= unlinkedUnits[0];
-    LinkedReference referenceResolution =
-        linkedSourceUnit.references[referenceIndex];
-    String name;
-    UnlinkedReference reference;
-    if (referenceIndex < unlinkedSourceUnit.references.length) {
-      // This is an explicit reference, so its name and prefix should be in
-      // [UnlinkedUnit.references].
-      expect(referenceResolution.name, isEmpty);
-      reference = unlinkedSourceUnit.references[referenceIndex];
-      name = reference.name;
-      if (reference.prefixReference != 0) {
-        // Prefixes should appear in the references table before any reference
-        // that uses them.
-        expect(reference.prefixReference, lessThan(referenceIndex));
-      }
-    } else {
-      // This is an implicit reference, so its name should be in
-      // [LinkedUnit.references].
-      name = referenceResolution.name;
-    }
-    // Index 0 is reserved.
-    expect(referenceIndex, isNot(0));
-    if (absoluteUri == null) {
-      expect(referenceResolution.dependency, 0);
-    } else {
-      checkDependency(referenceResolution.dependency, absoluteUri);
-    }
-    if (expectedName == null) {
-      expect(name, isEmpty);
-    } else {
-      expect(name, expectedName);
-    }
-    expect(referenceResolution.kind, expectedKind);
-    expect(referenceResolution.unit, expectedTargetUnit);
-    expect(referenceResolution.numTypeParameters, numTypeParameters);
-    return reference;
-  }
-
-  /// Verify that the given [typeRef] represents a reference to a type declared
-  /// in a file reachable via [absoluteUri], having name [expectedName].
-  /// If [expectedPrefix] is supplied, verify that the type is reached via the
-  /// given prefix.  Verify that the number of type arguments is equal to
-  /// [numTypeArguments].  [expectedKind] is the kind of object referenced.
-  /// [linkedSourceUnit] and [unlinkedSourceUnit] refer to the compilation unit
-  /// within which the [typeRef] appears; if not specified they are assumed to
-  /// refer to the defining compilation unit. [expectedTargetUnit] is the index
-  /// of the compilation unit in which the target of the [typeRef] is expected
-  /// to appear; if not specified it is assumed to be the defining compilation
-  /// unit.  [numTypeParameters] is the number of type parameters of the thing
-  /// being referred to.
-  void checkTypeRef(EntityRef typeRef, String absoluteUri, String expectedName,
-      {String expectedPrefix,
-      List<_PrefixExpectation> prefixExpectations,
-      int numTypeArguments: 0,
-      ReferenceKind expectedKind: ReferenceKind.classOrEnum,
-      EntityRefKind entityKind: null,
-      int expectedTargetUnit: 0,
-      LinkedUnit linkedSourceUnit,
-      UnlinkedUnit unlinkedSourceUnit,
-      int numTypeParameters: 0,
-      bool unresolvedHasName: false,
-      EntityRefNullabilitySuffix nullabilitySuffix:
-          EntityRefNullabilitySuffix.starOrIrrelevant}) {
-    linkedSourceUnit ??= definingUnit;
-    expect(typeRef, new TypeMatcher<EntityRef>());
-    expect(typeRef.paramReference, 0);
-    int index = typeRef.reference;
-    expect(typeRef.typeArguments, hasLength(numTypeArguments));
-    expect(typeRef.nullabilitySuffix, nullabilitySuffix);
-
-    if (entityKind == EntityRefKind.genericFunctionType) {
-      // [GenericFunctionType]s don't have references to check.
-      return;
-    }
-
-    UnlinkedReference reference = checkReferenceIndex(
-        index, absoluteUri, expectedName,
-        expectedKind: expectedKind,
-        expectedTargetUnit: expectedTargetUnit,
-        linkedSourceUnit: linkedSourceUnit,
-        unlinkedSourceUnit: unlinkedSourceUnit,
-        numTypeParameters: numTypeParameters,
-        unresolvedHasName: unresolvedHasName);
-    expect(reference, isNotNull,
-        reason: 'Unlinked type refs must refer to an explicit reference');
-    if (expectedPrefix != null) {
-      checkPrefix(reference.prefixReference, expectedPrefix);
-    } else if (prefixExpectations != null) {
-      for (_PrefixExpectation expectation in prefixExpectations) {
-        expect(reference.prefixReference, isNot(0));
-        reference = checkReferenceIndex(reference.prefixReference,
-            expectation.absoluteUri, expectation.name,
-            expectedKind: expectation.kind,
-            expectedTargetUnit: expectedTargetUnit,
-            linkedSourceUnit: linkedSourceUnit,
-            unlinkedSourceUnit: unlinkedSourceUnit,
-            numTypeParameters: expectation.numTypeParameters);
-      }
-      expect(reference.prefixReference, 0);
-    } else {
-      expect(reference.prefixReference, 0);
-    }
-  }
-
-  /// Verify that the given [typeRef] represents a reference to an unresolved
-  /// type.
-  void checkUnresolvedTypeRef(
-      EntityRef typeRef, String expectedPrefix, String expectedName,
-      {LinkedUnit linkedSourceUnit, UnlinkedUnit unlinkedSourceUnit}) {
-    // When serializing from the element model, unresolved type refs lose their
-    // name.
-    checkTypeRef(typeRef, null, expectedName,
-        expectedPrefix: expectedPrefix,
-        expectedKind: ReferenceKind.unresolved,
-        linkedSourceUnit: linkedSourceUnit,
-        unlinkedSourceUnit: unlinkedSourceUnit);
-  }
-
-  /// Verify that the given [typeRef] represents the type `void`.
-  void checkVoidTypeRef(EntityRef typeRef) {
-    checkTypeRef(typeRef, null, 'void');
-  }
-
-  fail_invalid_prefix_dynamic() {
-//    if (checkAstDerivedData) {
-//      // TODO(paulberry): get this to work properly.
-//      return;
-//    }
-    var t = serializeTypeText('dynamic.T', allowErrors: true);
-    checkUnresolvedTypeRef(t, 'dynamic', 'T');
-  }
-
-  fail_invalid_prefix_type_parameter() {
-//    if (checkAstDerivedData) {
-//      // TODO(paulberry): get this to work properly.
-//      return;
-//    }
-    checkUnresolvedTypeRef(
-        serializeClassText('class C<T> { T.U x; }', allowErrors: true)
-            .fields[0]
-            .type,
-        'T',
-        'U');
-  }
-
-  fail_invalid_prefix_void() {
-//    if (checkAstDerivedData) {
-//      // TODO(paulberry): get this to work properly.
-//      return;
-//    }
-    checkUnresolvedTypeRef(
-        serializeTypeText('void.T', allowErrors: true), 'void', 'T');
-  }
-
-  /// Find the class with the given [className] in the summary, and return its
-  /// [UnlinkedClass] data structure.  If [unit] is not given, the class is
-  /// looked for in the defining compilation unit.
-  UnlinkedClass findClass(String className,
-      {bool failIfAbsent: false, UnlinkedUnit unit}) {
-    unit ??= unlinkedUnits[0];
-    UnlinkedClass result;
-    for (UnlinkedClass cls in unit.classes) {
-      if (cls.name == className) {
-        if (result != null) {
-          fail('Duplicate class $className');
-        }
-        result = cls;
-      }
-    }
-    if (result == null && failIfAbsent) {
-      fail('Class $className not found in serialized output');
-    }
-    return result;
-  }
-
-  /// Find the enum with the given [enumName] in the summary, and return its
-  /// [UnlinkedEnum] data structure.  If [unit] is not given, the enum is looked
-  /// for in the defining compilation unit.
-  UnlinkedEnum findEnum(String enumName,
-      {bool failIfAbsent: false, UnlinkedUnit unit}) {
-    unit ??= unlinkedUnits[0];
-    UnlinkedEnum result;
-    for (UnlinkedEnum e in unit.enums) {
-      if (e.name == enumName) {
-        if (result != null) {
-          fail('Duplicate enum $enumName');
-        }
-        result = e;
-      }
-    }
-    if (result == null && failIfAbsent) {
-      fail('Enum $enumName not found in serialized output');
-    }
-    return result;
-  }
-
-  /// Find the executable with the given [executableName] in the summary, and
-  /// return its [UnlinkedExecutable] data structure.  If [executables] is not
-  /// given, then the executable is searched for in the defining compilation
-  /// unit.
-  UnlinkedExecutable findExecutable(String executableName,
-      {List<UnlinkedExecutable> executables, bool failIfAbsent: false}) {
-    executables ??= unlinkedUnits[0].executables;
-    UnlinkedExecutable result;
-    for (UnlinkedExecutable executable in executables) {
-      if (executable.name == executableName) {
-        if (result != null) {
-          fail('Duplicate executable $executableName');
-        }
-        result = executable;
-      }
-    }
-    if (result == null && failIfAbsent) {
-      fail('Executable $executableName not found in serialized output');
-    }
-    return result;
-  }
-
-  /// Find the mixin with the given [name] in the summary, and return its
-  /// [UnlinkedClass] data structure.
-  UnlinkedClass findMixin(String name) {
-    UnlinkedClass result;
-    for (UnlinkedClass mixin in unlinkedUnits[0].mixins) {
-      if (mixin.name == name) {
-        if (result != null) {
-          fail('Duplicate mixin $name');
-        }
-        result = mixin;
-      }
-    }
-    if (result == null) {
-      fail('Mixin $name not found in serialized output.');
-    }
-    return result;
-  }
-
-  /// Find the parameter with the given [name] in [parameters].
-  UnlinkedParam findParameter(List<UnlinkedParam> parameters, String name) {
-    UnlinkedParam result;
-    for (UnlinkedParam parameter in parameters) {
-      if (parameter.name == name) {
-        if (result != null) {
-          fail('Duplicate parameter $name');
-        }
-        result = parameter;
-      }
-    }
-    if (result == null) {
-      fail('Parameter $name not found');
-    }
-    return result;
-  }
-
-  /// Find the typedef with the given [typedefName] in the summary, and return
-  /// its [UnlinkedTypedef] data structure.  If [unit] is not given, the typedef
-  /// is looked for in the defining compilation unit.
-  UnlinkedTypedef findTypedef(String typedefName,
-      {bool failIfAbsent: false, UnlinkedUnit unit}) {
-    unit ??= unlinkedUnits[0];
-    UnlinkedTypedef result;
-    for (UnlinkedTypedef type in unit.typedefs) {
-      if (type.name == typedefName) {
-        if (result != null) {
-          fail('Duplicate typedef $typedefName');
-        }
-        result = type;
-      }
-    }
-    if (result == null && failIfAbsent) {
-      fail('Typedef $typedefName not found in serialized output');
-    }
-    return result;
-  }
-
-  /// Find the top level variable with the given [variableName] in the summary,
-  /// and return its [UnlinkedVariable] data structure.  If [variables] is not
-  /// specified, the variable is looked for in the defining compilation unit.
-  UnlinkedVariable findVariable(String variableName,
-      {List<UnlinkedVariable> variables, bool failIfAbsent: false}) {
-    variables ??= unlinkedUnits[0].variables;
-    UnlinkedVariable result;
-    for (UnlinkedVariable variable in variables) {
-      if (variable.name == variableName) {
-        if (result != null) {
-          fail('Duplicate variable $variableName');
-        }
-        result = variable;
-      }
-    }
-    if (result == null && failIfAbsent) {
-      fail('Variable $variableName not found in serialized output');
-    }
-    return result;
-  }
-
-  /// Find the entry in [linkedSourceUnit.types] matching [slotId].
-  EntityRef getTypeRefForSlot(int slotId, {LinkedUnit linkedSourceUnit}) {
-    linkedSourceUnit ??= definingUnit;
-    for (EntityRef typeRef in linkedSourceUnit.types) {
-      if (typeRef.slot == slotId) {
-        return typeRef;
-      }
-    }
-    return null;
-  }
-
-  /// Serialize the given library [text] and return the summary of the class
-  /// with the given [className].
-  UnlinkedClass serializeClassText(String text,
-      {String className: 'C', bool allowErrors: false}) {
-    serializeLibraryText(text, allowErrors: allowErrors);
-    return findClass(className, failIfAbsent: true);
-  }
-
-  /// Serialize the given library [text] and return the summary of the enum with
-  /// the given [enumName].
-  UnlinkedEnum serializeEnumText(String text, [String enumName = 'E']) {
-    serializeLibraryText(text);
-    return findEnum(enumName, failIfAbsent: true);
-  }
-
-  /// Serialize the given library [text] and return the summary of the
-  /// executable with the given [executableName].
-  UnlinkedExecutable serializeExecutableText(String text,
-      {String executableName: 'f', bool allowErrors: false}) {
-    serializeLibraryText(text, allowErrors: allowErrors);
-    return findExecutable(executableName, failIfAbsent: true);
-  }
-
-  /// Serialize the given method [text] and return the summary of the executable
-  /// with the given [executableName].
-  UnlinkedExecutable serializeMethodText(String text,
-      [String executableName = 'f']) {
-    serializeLibraryText('class C { $text }');
-    return findExecutable(executableName,
-        executables: findClass('C', failIfAbsent: true).executables,
-        failIfAbsent: true);
-  }
-
-  /// Serialize the given library [text] and return the summary of the mixin
-  /// with the given [name].
-  UnlinkedClass serializeMixinText(String text,
-      {String name: 'M', bool allowErrors: false}) {
-    serializeLibraryText(text, allowErrors: allowErrors);
-    return findMixin(name);
-  }
-
-  /// Serialize the given library [text] and return the summary of the typedef
-  /// with the given [typedefName].
-  UnlinkedTypedef serializeTypedefText(String text,
-      [String typedefName = 'F']) {
-    serializeLibraryText(text);
-    return findTypedef(typedefName, failIfAbsent: true);
-  }
-
-  /// Serialize a type declaration using the given [text] as a type name, and
-  /// return a summary of the corresponding [EntityRef].  If the type
-  /// declaration needs to refer to types that are not available in core, those
-  /// types may be declared in [otherDeclarations].
-  EntityRef serializeTypeText(String text,
-      {String otherDeclarations: '', bool allowErrors: false}) {
-    return serializeVariableText('$otherDeclarations\n$text v;',
-            allowErrors: allowErrors)
-        .type;
-  }
-
-  /// Serialize the given library [text] and return the summary of the variable
-  /// with the given [variableName].
-  UnlinkedVariable serializeVariableText(String text,
-      {String variableName: 'v', bool allowErrors: false, imports: ''}) {
-    if (imports.isNotEmpty && !imports.endsWith('\n')) {
-      imports += '\n';
-    }
-    serializeLibraryText('$imports$text', allowErrors: allowErrors);
-    return findVariable(variableName, failIfAbsent: true);
-  }
-
-  test_apiSignature() {
-    List<int> signature1;
-    List<int> signature2;
-    List<int> signature3;
-    {
-      serializeLibraryText('class A {}');
-      signature1 = unlinkedUnits[0].apiSignature;
-    }
-    {
-      serializeLibraryText('class A { }');
-      signature2 = unlinkedUnits[0].apiSignature;
-    }
-    {
-      serializeLibraryText('class B {}');
-      signature3 = unlinkedUnits[0].apiSignature;
-    }
-    expect(signature2, signature1);
-    expect(signature3, isNot(signature1));
-  }
-
-  test_apiSignature_excludeBody_constructor() {
-    List<int> signature1;
-    List<int> signature2;
-    List<int> signature3;
-    {
-      serializeLibraryText(r'''
-class A {
-  A() {
-  }
-}
-''');
-      signature1 = unlinkedUnits[0].apiSignature;
-    }
-    {
-      serializeLibraryText(r'''
-class A {
-  A() {
-    int v1;
-    f() {
-      double v2;
-    }
-  }
-}
-''');
-      signature2 = unlinkedUnits[0].apiSignature;
-    }
-    {
-      serializeLibraryText(r'''
-class A {
-  A(int p) {
-  }
-}
-''');
-    }
-    expect(signature2, signature1);
-    expect(signature3, isNot(signature1));
-  }
-
-  test_apiSignature_excludeBody_method() {
-    List<int> signature1;
-    List<int> signature2;
-    List<int> signature3;
-    {
-      serializeLibraryText(r'''
-class A {
-  m() {
-  }
-}
-''');
-      signature1 = unlinkedUnits[0].apiSignature;
-    }
-    {
-      serializeLibraryText(r'''
-class A {
-  m() {
-    int v1;
-    f() {
-      double v2;
-    }
-  }
-}
-''');
-      signature2 = unlinkedUnits[0].apiSignature;
-    }
-    {
-      serializeLibraryText(r'''
-class A {
-  m(p) {
-  }
-}
-''');
-    }
-    expect(signature2, signature1);
-    expect(signature3, isNot(signature1));
-  }
-
-  test_apiSignature_excludeBody_topLevelFunction() {
-    List<int> signature1;
-    List<int> signature2;
-    List<int> signature3;
-    {
-      serializeLibraryText('main() {}');
-      signature1 = unlinkedUnits[0].apiSignature;
-    }
-    {
-      serializeLibraryText(r'''
-main() {
-  int v1 = 1;
-  f() {
-    int v2 = 2;
-  }
-}
-''');
-      signature2 = unlinkedUnits[0].apiSignature;
-    }
-    {
-      serializeLibraryText('main(p) {}');
-      signature3 = unlinkedUnits[0].apiSignature;
-    }
-    expect(signature2, signature1);
-    expect(signature3, isNot(signature1));
-  }
-
-  test_bottom_reference_shared() {
-    if (skipFullyLinkedData) {
-      return;
-    }
-    // The synthetic executables for both `x` and `y` have type `() => `Bottom`.
-    // Verify that they both use the same reference to `Bottom`.
-    serializeLibraryText('var x = throw null; var y = throw null;');
-    EntityRef xInitializerReturnType =
-        getTypeRefForSlot(findVariable('x').initializer.inferredReturnTypeSlot);
-    EntityRef yInitializerReturnType =
-        getTypeRefForSlot(findVariable('y').initializer.inferredReturnTypeSlot);
-    checkLinkedTypeRef(xInitializerReturnType, null, '*bottom*');
-    checkLinkedTypeRef(yInitializerReturnType, null, '*bottom*');
-    expect(xInitializerReturnType.reference, yInitializerReturnType.reference);
-  }
-
-  test_cascaded_export_hide_hide() {
-    addNamedSource('/lib1.dart', 'export "lib2.dart" hide C hide B, C;');
-    addNamedSource('/lib2.dart', 'class A {} class B {} class C {}');
-    serializeLibraryText('''
-import 'lib1.dart';
-A a;
-B b;
-C c;
-    ''', allowErrors: true);
-    checkTypeRef(findVariable('a').type, absUri('/lib2.dart'), 'A');
-    checkUnresolvedTypeRef(findVariable('b').type, null, 'B');
-    checkUnresolvedTypeRef(findVariable('c').type, null, 'C');
-  }
-
-  test_cascaded_export_hide_show() {
-    addNamedSource('/lib1.dart', 'export "lib2.dart" hide C show A, C;');
-    addNamedSource('/lib2.dart', 'class A {} class B {} class C {}');
-    serializeLibraryText('''
-import 'lib1.dart';
-A a;
-B b;
-C c;
-    ''', allowErrors: true);
-    checkTypeRef(findVariable('a').type, absUri('/lib2.dart'), 'A');
-    checkUnresolvedTypeRef(findVariable('b').type, null, 'B');
-    checkUnresolvedTypeRef(findVariable('c').type, null, 'C');
-  }
-
-  test_cascaded_export_show_hide() {
-    addNamedSource('/lib1.dart', 'export "lib2.dart" show A, B hide B, C;');
-    addNamedSource('/lib2.dart', 'class A {} class B {} class C {}');
-    serializeLibraryText('''
-import 'lib1.dart';
-A a;
-B b;
-C c;
-    ''', allowErrors: true);
-    checkTypeRef(findVariable('a').type, absUri('/lib2.dart'), 'A');
-    checkUnresolvedTypeRef(findVariable('b').type, null, 'B');
-    checkUnresolvedTypeRef(findVariable('c').type, null, 'C');
-  }
-
-  test_cascaded_export_show_show() {
-    addNamedSource('/lib1.dart', 'export "lib2.dart" show A, B show A, C;');
-    addNamedSource('/lib2.dart', 'class A {} class B {} class C {}');
-    serializeLibraryText('''
-import 'lib1.dart';
-A a;
-B b;
-C c;
-    ''', allowErrors: true);
-    checkTypeRef(findVariable('a').type, absUri('/lib2.dart'), 'A');
-    checkUnresolvedTypeRef(findVariable('b').type, null, 'B');
-    checkUnresolvedTypeRef(findVariable('c').type, null, 'C');
-  }
-
-  test_cascaded_import_hide_hide() {
-    addNamedSource('/lib.dart', 'class A {} class B {} class C {}');
-    serializeLibraryText('''
-import 'lib.dart' hide C hide B, C;
-A a;
-B b;
-C c;
-    ''', allowErrors: true);
-    checkTypeRef(findVariable('a').type, absUri('/lib.dart'), 'A');
-    checkUnresolvedTypeRef(findVariable('b').type, null, 'B');
-    checkUnresolvedTypeRef(findVariable('c').type, null, 'C');
-  }
-
-  test_cascaded_import_hide_show() {
-    addNamedSource('/lib.dart', 'class A {} class B {} class C {}');
-    serializeLibraryText('''
-import 'lib.dart' hide C show A, C;
-A a;
-B b;
-C c;
-    ''', allowErrors: true);
-    checkTypeRef(findVariable('a').type, absUri('/lib.dart'), 'A');
-    checkUnresolvedTypeRef(findVariable('b').type, null, 'B');
-    checkUnresolvedTypeRef(findVariable('c').type, null, 'C');
-  }
-
-  test_cascaded_import_show_hide() {
-    addNamedSource('/lib.dart', 'class A {} class B {} class C {}');
-    serializeLibraryText('''
-import 'lib.dart' show A, B hide B, C;
-A a;
-B b;
-C c;
-    ''', allowErrors: true);
-    checkTypeRef(findVariable('a').type, absUri('/lib.dart'), 'A');
-    checkUnresolvedTypeRef(findVariable('b').type, null, 'B');
-    checkUnresolvedTypeRef(findVariable('c').type, null, 'C');
-  }
-
-  test_cascaded_import_show_show() {
-    addNamedSource('/lib.dart', 'class A {} class B {} class C {}');
-    serializeLibraryText('''
-import 'lib.dart' show A, B show A, C;
-A a;
-B b;
-C c;
-    ''', allowErrors: true);
-    checkTypeRef(findVariable('a').type, absUri('/lib.dart'), 'A');
-    checkUnresolvedTypeRef(findVariable('b').type, null, 'B');
-    checkUnresolvedTypeRef(findVariable('c').type, null, 'C');
-  }
-
-  test_class_abstract() {
-    UnlinkedClass cls = serializeClassText('abstract class C {}');
-    expect(cls.isAbstract, true);
-  }
-
-  test_class_alias_abstract() {
-    UnlinkedClass cls = serializeClassText(
-        'abstract class C = D with E; class D {} class E {}');
-    expect(cls.isAbstract, true);
-  }
-
-  test_class_alias_concrete() {
-    UnlinkedClass cls =
-        serializeClassText('class C = _D with _E; class _D {} class _E {}');
-    expect(cls.isAbstract, false);
-    expect(unlinkedUnits[0].publicNamespace.names, hasLength(1));
-    expect(unlinkedUnits[0].publicNamespace.names[0].kind,
-        ReferenceKind.classOrEnum);
-    expect(unlinkedUnits[0].publicNamespace.names[0].name, 'C');
-    expect(unlinkedUnits[0].publicNamespace.names[0].numTypeParameters, 0);
-  }
-
-  test_class_alias_documented() {
-    String text = '''
-// Extra comment so doc comment offset != 0
-/**
- * Docs
- */
-class C = D with E;
-
-class D {}
-class E {}''';
-    UnlinkedClass cls = serializeClassText(text);
-    expect(cls.documentationComment, isNotNull);
-    checkDocumentationComment(cls.documentationComment, text);
-  }
-
-  test_class_alias_flag() {
-    UnlinkedClass cls =
-        serializeClassText('class C = D with E; class D {} class E {}');
-    expect(cls.isMixinApplication, true);
-  }
-
-  test_class_alias_generic() {
-    serializeClassText('class C<A, B> = _D with _E; class _D {} class _E {}');
-    expect(unlinkedUnits[0].publicNamespace.names[0].numTypeParameters, 2);
-  }
-
-  test_class_alias_mixin_order() {
-    UnlinkedClass cls = serializeClassText('''
-class C = D with E, F;
-class D {}
-class E {}
-class F {}
-''');
-    expect(cls.mixins, hasLength(2));
-    checkTypeRef(cls.mixins[0], null, 'E');
-    checkTypeRef(cls.mixins[1], null, 'F');
-  }
-
-  test_class_alias_no_implicit_constructors() {
-    UnlinkedClass cls = serializeClassText('''
-class C = D with E;
-class D {
-  D.foo();
-  D.bar();
-}
-class E {}
-''');
-    expect(cls.executables, isEmpty);
-  }
-
-  test_class_alias_notSimplyBoundedSlot() {
-    var cls = serializeClassText(
-        'class C<T extends C> = D with E; class D {} class E {}');
-    expect(cls.notSimplyBoundedSlot, isNot(0));
-    if (!skipFullyLinkedData) {
-      expect(
-          linked.units[0].notSimplyBounded, contains(cls.notSimplyBoundedSlot));
-    }
-  }
-
-  test_class_alias_notSimplyBoundedSlot_simple_because_non_generic() {
-    // If no type parameters are specified, then the class is simply bounded, so
-    // there is no reason to assign it a slot.
-    var cls = serializeClassText('class C = D with E; class D {} class E {}');
-    expect(cls.notSimplyBoundedSlot, 0);
-  }
-
-  test_class_alias_notSimplyBoundedSlot_simple_by_syntax() {
-    // If no bounds are specified, then the class is simply bounded by sintax
-    // alone, so there is no reason to assign it a slot.
-    var cls =
-        serializeClassText('class C<T> = D with E; class D {} class E {}');
-    expect(cls.notSimplyBoundedSlot, 0);
-  }
-
-  test_class_alias_private() {
-    serializeClassText('class _C = _D with _E; class _D {} class _E {}',
-        className: '_C');
-    expect(unlinkedUnits[0].publicNamespace.names, isEmpty);
-  }
-
-  test_class_alias_reference_generic() {
-    EntityRef typeRef = serializeTypeText('C',
-        otherDeclarations: 'class C<D, E> = F with G; class F {} class G {}');
-    checkTypeRef(typeRef, null, 'C', numTypeParameters: 2);
-  }
-
-  test_class_alias_reference_generic_imported() {
-    addNamedSource(
-        '/lib.dart', 'class C<D, E> = F with G; class F {} class G {}');
-    EntityRef typeRef =
-        serializeTypeText('C', otherDeclarations: 'import "lib.dart";');
-    checkTypeRef(typeRef, absUri('/lib.dart'), 'C', numTypeParameters: 2);
-  }
-
-  test_class_alias_supertype() {
-    UnlinkedClass cls =
-        serializeClassText('class C = D with E; class D {} class E {}');
-    checkTypeRef(cls.supertype, null, 'D');
-    expect(cls.hasNoSupertype, isFalse);
-  }
-
-  test_class_codeRange() {
-    UnlinkedClass cls = serializeClassText(' class C {}');
-    _assertCodeRange(cls.codeRange, 1, 10);
-  }
-
-  test_class_concrete() {
-    UnlinkedClass cls = serializeClassText('class C {}');
-    expect(cls.isAbstract, false);
-    expect(unlinkedUnits[0].publicNamespace.names, hasLength(1));
-    expect(unlinkedUnits[0].publicNamespace.names[0].kind,
-        ReferenceKind.classOrEnum);
-    expect(unlinkedUnits[0].publicNamespace.names[0].name, 'C');
-    expect(unlinkedUnits[0].publicNamespace.names[0].numTypeParameters, 0);
-  }
-
-  test_class_constMembers() {
-    UnlinkedClass cls = serializeClassText('''
-class C {
-  int fieldInstance = 0;
-  final int fieldInstanceFinal = 0;
-  static int fieldStatic = 0;
-  static final int fieldStaticFinal = 0;
-  static const int fieldStaticConst = 0;
-  static const int _fieldStaticConstPrivate = 0;
-  static void methodStaticPublic() {}
-  static void _methodStaticPrivate() {}
-  void methodInstancePublic() {}
-  C operator+(C c) => null;
-}
-''');
-    expect(cls.isAbstract, false);
-    expect(unlinkedUnits[0].publicNamespace.names, hasLength(1));
-    UnlinkedPublicName className = unlinkedUnits[0].publicNamespace.names[0];
-    expect(className.kind, ReferenceKind.classOrEnum);
-    expect(className.name, 'C');
-    expect(className.numTypeParameters, 0);
-    // executables
-    Map<String, UnlinkedPublicName> executablesMap =
-        <String, UnlinkedPublicName>{};
-    className.members.forEach((e) => executablesMap[e.name] = e);
-    expect(executablesMap, hasLength(4));
-    Map<String, ReferenceKind> expectedExecutableKinds =
-        <String, ReferenceKind>{
-      'fieldStaticConst': ReferenceKind.propertyAccessor,
-      'fieldStaticFinal': ReferenceKind.propertyAccessor,
-      'fieldStatic': ReferenceKind.propertyAccessor,
-      'methodStaticPublic': ReferenceKind.method,
-    };
-    expectedExecutableKinds.forEach((String name, ReferenceKind expectedKind) {
-      UnlinkedPublicName executable = executablesMap[name];
-      expect(executable.kind, expectedKind);
-      expect(executable.members, isEmpty);
-    });
-  }
-
-  test_class_constMembers_constructors() {
-    UnlinkedClass cls = serializeClassText('''
-class C {
-  const C();
-  const C.constructorNamedPublicConst();
-  C.constructorNamedPublic();
-  C._constructorNamedPrivate();
-}
-''');
-    expect(cls.isAbstract, false);
-    expect(unlinkedUnits[0].publicNamespace.names, hasLength(1));
-    UnlinkedPublicName className = unlinkedUnits[0].publicNamespace.names[0];
-    expect(className.kind, ReferenceKind.classOrEnum);
-    expect(className.name, 'C');
-    expect(className.numTypeParameters, 0);
-    // executables
-    Map<String, UnlinkedPublicName> executablesMap =
-        <String, UnlinkedPublicName>{};
-    className.members.forEach((e) => executablesMap[e.name] = e);
-    expect(executablesMap, hasLength(2));
-    {
-      UnlinkedPublicName executable =
-          executablesMap['constructorNamedPublicConst'];
-      expect(executable.kind, ReferenceKind.constructor);
-      expect(executable.members, isEmpty);
-    }
-    {
-      UnlinkedPublicName executable = executablesMap['constructorNamedPublic'];
-      expect(executable.kind, ReferenceKind.constructor);
-      expect(executable.members, isEmpty);
-    }
-  }
-
-  test_class_documented() {
-    String text = '''
-// Extra comment so doc comment offset != 0
-/**
- * Docs
- */
-class C {}''';
-    UnlinkedClass cls = serializeClassText(text);
-    expect(cls.documentationComment, isNotNull);
-    checkDocumentationComment(cls.documentationComment, text);
-  }
-
-  test_class_documented_tripleSlash() {
-    String text = '''
-/// aaa
-/// bbbb
-/// cc
-class C {}''';
-    UnlinkedClass cls = serializeClassText(text);
-    UnlinkedDocumentationComment comment = cls.documentationComment;
-    expect(comment, isNotNull);
-    expect(comment.text, '/// aaa\n/// bbbb\n/// cc');
-  }
-
-  test_class_documented_with_references() {
-    String text = '''
-// Extra comment so doc comment offset != 0
-/**
- * Docs referring to [D] and [E]
- */
-class C {}
-
-class D {}
-class E {}''';
-    UnlinkedClass cls = serializeClassText(text);
-    expect(cls.documentationComment, isNotNull);
-    checkDocumentationComment(cls.documentationComment, text);
-  }
-
-  test_class_documented_with_with_windows_line_endings() {
-    String text = '/**\r\n * Docs\r\n */\r\nclass C {}';
-    UnlinkedClass cls = serializeClassText(text);
-    expect(cls.documentationComment, isNotNull);
-    checkDocumentationComment(cls.documentationComment, text);
-  }
-
-  test_class_interface() {
-    UnlinkedClass cls = serializeClassText('''
-class C implements D {}
-class D {}
-''');
-    expect(cls.interfaces, hasLength(1));
-    checkTypeRef(cls.interfaces[0], null, 'D');
-  }
-
-  test_class_interface_order() {
-    UnlinkedClass cls = serializeClassText('''
-class C implements D, E {}
-class D {}
-class E {}
-''');
-    expect(cls.interfaces, hasLength(2));
-    checkTypeRef(cls.interfaces[0], null, 'D');
-    checkTypeRef(cls.interfaces[1], null, 'E');
-  }
-
-  test_class_mixin() {
-    UnlinkedClass cls = serializeClassText('''
-class C extends Object with D {}
-class D {}
-''');
-    expect(cls.mixins, hasLength(1));
-    checkTypeRef(cls.mixins[0], null, 'D');
-  }
-
-  test_class_mixin_order() {
-    UnlinkedClass cls = serializeClassText('''
-class C extends Object with D, E {}
-class D {}
-class E {}
-''');
-    expect(cls.mixins, hasLength(2));
-    checkTypeRef(cls.mixins[0], null, 'D');
-    checkTypeRef(cls.mixins[1], null, 'E');
-  }
-
-  test_class_name() {
-    var classText = 'class C {}';
-    UnlinkedClass cls = serializeClassText(classText);
-    expect(cls.name, 'C');
-    expect(cls.nameOffset, classText.indexOf('C'));
-  }
-
-  test_class_no_flags() {
-    UnlinkedClass cls = serializeClassText('class C {}');
-    expect(cls.isAbstract, false);
-    expect(cls.isMixinApplication, false);
-  }
-
-  test_class_no_interface() {
-    UnlinkedClass cls = serializeClassText('class C {}');
-    expect(cls.interfaces, isEmpty);
-  }
-
-  test_class_no_mixins() {
-    UnlinkedClass cls = serializeClassText('class C {}');
-    expect(cls.mixins, isEmpty);
-  }
-
-  test_class_no_superclass() {
-    UnlinkedClass cls = serializeClassText('part of dart.core; class Object {}',
-        className: 'Object');
-    expect(cls.supertype, isNull);
-    expect(cls.hasNoSupertype, isTrue);
-  }
-
-  test_class_no_type_param() {
-    UnlinkedClass cls = serializeClassText('class C {}');
-    expect(cls.typeParameters, isEmpty);
-  }
-
-  test_class_non_alias_flag() {
-    UnlinkedClass cls = serializeClassText('class C {}');
-    expect(cls.isMixinApplication, false);
-  }
-
-  test_class_notSimplyBounded_circularity_via_typedef() {
-    // C's type parameter T is not simply bounded because its bound, F, expands
-    // to `dynamic F(C)`, which refers to C.
-    UnlinkedClass cls =
-        serializeClassText('class C<T extends F> {} typedef F(C value);');
-    expect(cls.notSimplyBoundedSlot, isNot(0));
-    if (!skipFullyLinkedData) {
-      expect(
-          linked.units[0].notSimplyBounded, contains(cls.notSimplyBoundedSlot));
-    }
-  }
-
-  test_class_notSimplyBounded_circularity_with_type_params() {
-    // C's type parameter T is simply bounded because even though it refers to
-    // C, it specifies a bound.
-    UnlinkedClass cls = serializeClassText('class C<T extends C<dynamic>> {}');
-    expect(cls.notSimplyBoundedSlot, isNot(0));
-    if (!skipFullyLinkedData) {
-      expect(linked.units[0].notSimplyBounded,
-          isNot(contains(cls.notSimplyBoundedSlot)));
-    }
-  }
-
-  test_class_notSimplyBounded_dependency_with_type_params() {
-    // C's type parameter T is simply bounded because even though it refers to
-    // non-simply-bounded type D, it specifies a bound.
-    UnlinkedClass cls = serializeClassText(
-        'class C<T extends D<dynamic>> {} class D<T extends D<T>> {}');
-    expect(cls.notSimplyBoundedSlot, isNot(0));
-    if (!skipFullyLinkedData) {
-      expect(linked.units[0].notSimplyBounded,
-          isNot(contains(cls.notSimplyBoundedSlot)));
-    }
-  }
-
-  test_class_notSimplyBounded_function_typed_bound_complex_via_parameter_type() {
-    UnlinkedClass cls =
-        serializeClassText('class C<T extends void Function(T)> {}');
-    expect(cls.notSimplyBoundedSlot, isNot(0));
-    if (!skipFullyLinkedData) {
-      expect(
-          linked.units[0].notSimplyBounded, contains(cls.notSimplyBoundedSlot));
-    }
-  }
-
-  test_class_notSimplyBounded_function_typed_bound_complex_via_return_type() {
-    UnlinkedClass cls =
-        serializeClassText('class C<T extends T Function()> {}');
-    expect(cls.notSimplyBoundedSlot, isNot(0));
-    if (!skipFullyLinkedData) {
-      expect(
-          linked.units[0].notSimplyBounded, contains(cls.notSimplyBoundedSlot));
-    }
-  }
-
-  test_class_notSimplyBounded_function_typed_bound_simple() {
-    UnlinkedClass cls =
-        serializeClassText('class C<T extends void Function()> {}');
-    expect(cls.notSimplyBoundedSlot, isNot(0));
-    if (!skipFullyLinkedData) {
-      expect(linked.units[0].notSimplyBounded,
-          isNot(contains(cls.notSimplyBoundedSlot)));
-    }
-  }
-
-  test_class_notSimplyBounded_refers_to_circular_typedef() {
-    // C's type parameter T has a bound of F, which is a circular typedef.  This
-    // is illegal in Dart, but we need to make sure it doesn't lead to a crash
-    // or infinite loop.
-    UnlinkedClass cls = serializeClassText(
-        'class C<T extends F> {} typedef F(G value); typedef G(F value);');
-    expect(cls.notSimplyBoundedSlot, isNot(0));
-  }
-
-  test_class_notSimplyBoundedSlot() {
-    var cls = serializeClassText('class C<T extends C> {}');
-    expect(cls.notSimplyBoundedSlot, isNot(0));
-    if (!skipFullyLinkedData) {
-      expect(
-          linked.units[0].notSimplyBounded, contains(cls.notSimplyBoundedSlot));
-    }
-  }
-
-  test_class_notSimplyBoundedSlot_complex_by_cycle() {
-    var cls =
-        serializeClassText('class C<T extends D> {} class D<T extends C> {}');
-    if (!skipFullyLinkedData) {
-      expect(
-          linked.units[0].notSimplyBounded, contains(cls.notSimplyBoundedSlot));
-    }
-  }
-
-  test_class_notSimplyBoundedSlot_complex_by_reference_to_cycle() {
-    var cls =
-        serializeClassText('class C<T extends D> {} class D<T extends D> {}');
-    if (!skipFullyLinkedData) {
-      expect(
-          linked.units[0].notSimplyBounded, contains(cls.notSimplyBoundedSlot));
-    }
-  }
-
-  test_class_notSimplyBoundedSlot_complex_by_use_of_parameter() {
-    var cls = serializeClassText('class C<T extends D<T>> {} class D<T> {}');
-    if (!skipFullyLinkedData) {
-      expect(
-          linked.units[0].notSimplyBounded, contains(cls.notSimplyBoundedSlot));
-    }
-  }
-
-  test_class_notSimplyBoundedSlot_simple_because_non_generic() {
-    // If no type parameters are specified, then the class is simply bounded, so
-    // there is no reason to assign it a slot.
-    var cls = serializeClassText('class C {}');
-    expect(cls.notSimplyBoundedSlot, 0);
-  }
-
-  test_class_notSimplyBoundedSlot_simple_by_lack_of_cycles() {
-    var cls = serializeClassText('class C<T extends D> {} class D<T> {}');
-    if (!skipFullyLinkedData) {
-      expect(linked.units[0].notSimplyBounded,
-          isNot(contains(cls.notSimplyBoundedSlot)));
-    }
-  }
-
-  test_class_notSimplyBoundedSlot_simple_by_syntax() {
-    // If no bounds are specified, then the class is simply bounded by syntax
-    // alone, so there is no reason to assign it a slot.
-    var cls = serializeClassText('class C<T> {}');
-    expect(cls.notSimplyBoundedSlot, 0);
-  }
-
-  test_class_private() {
-    serializeClassText('class _C {}', className: '_C');
-    expect(unlinkedUnits[0].publicNamespace.names, isEmpty);
-  }
-
-  test_class_reference_generic() {
-    EntityRef typeRef =
-        serializeTypeText('C', otherDeclarations: 'class C<D, E> {}');
-    checkTypeRef(typeRef, null, 'C', numTypeParameters: 2);
-  }
-
-  test_class_reference_generic_imported() {
-    addNamedSource('/lib.dart', 'class C<D, E> {}');
-    EntityRef typeRef =
-        serializeTypeText('C', otherDeclarations: 'import "lib.dart";');
-    checkTypeRef(typeRef, absUri('/lib.dart'), 'C', numTypeParameters: 2);
-  }
-
-  test_class_superclass() {
-    UnlinkedClass cls = serializeClassText('class C {}');
-    expect(cls.supertype, isNull);
-    expect(cls.hasNoSupertype, isFalse);
-  }
-
-  test_class_superclass_explicit() {
-    UnlinkedClass cls = serializeClassText('class C extends D {} class D {}');
-    expect(cls.supertype, isNotNull);
-    checkTypeRef(cls.supertype, null, 'D');
-    expect(cls.hasNoSupertype, isFalse);
-  }
-
-  test_class_type_param_bound() {
-    UnlinkedClass cls = serializeClassText('class C<T extends List> {}');
-    expect(cls.typeParameters, hasLength(1));
-    {
-      UnlinkedTypeParam typeParameter = cls.typeParameters[0];
-      expect(typeParameter.name, 'T');
-      expect(typeParameter.bound, isNotNull);
-      checkTypeRef(typeParameter.bound, 'dart:core', 'List',
-          numTypeParameters: 1);
-    }
-  }
-
-  test_class_type_param_f_bound() {
-    UnlinkedClass cls = serializeClassText('class C<T, U extends List<T>> {}');
-    EntityRef typeArgument = cls.typeParameters[1].bound.typeArguments[0];
-    checkParamTypeRef(typeArgument, 2);
-  }
-
-  test_class_type_param_f_bound_self_ref() {
-    UnlinkedClass cls = serializeClassText('class C<T, U extends List<U>> {}');
-    EntityRef typeArgument = cls.typeParameters[1].bound.typeArguments[0];
-    checkParamTypeRef(typeArgument, 1);
-  }
-
-  test_class_type_param_no_bound() {
-    String text = 'class C<T> {}';
-    UnlinkedClass cls = serializeClassText(text);
-    expect(cls.typeParameters, hasLength(1));
-    expect(cls.typeParameters[0].name, 'T');
-    expect(cls.typeParameters[0].nameOffset, text.indexOf('T'));
-    expect(cls.typeParameters[0].bound, isNull);
-    expect(unlinkedUnits[0].publicNamespace.names[0].numTypeParameters, 1);
-  }
-
-  test_closure_executable_with_bottom_return_type() {
-    UnlinkedVariable variable = serializeVariableText('var v = (() => null);');
-    UnlinkedExecutable closure;
-    {
-      UnlinkedExecutable executable = variable.initializer;
-      expect(executable.localFunctions, hasLength(1));
-      expect(executable.localFunctions[0].returnType, isNull);
-      closure = executable.localFunctions[0];
-    }
-    // Strong mode infers a type for the closure of `() => Null`.
-    checkInferredTypeSlot(closure.inferredReturnTypeSlot, 'dart:core', 'Null');
-  }
-
-  test_closure_executable_with_imported_return_type() {
-    addNamedSource('/a.dart', 'class C { D d; } class D {}');
-    // The closure has type `() => D`; `D` is defined in a library that is
-    // imported.
-    UnlinkedExecutable executable = serializeVariableText(r'''
-import "a.dart";
-var v = (() {
-  print((() => new C().d)());
-});
-''').initializer.localFunctions[0];
-    expect(executable.localFunctions, hasLength(1));
-    expect(executable.localFunctions[0].returnType, isNull);
-    checkInferredTypeSlot(executable.localFunctions[0].inferredReturnTypeSlot,
-        absUri('/a.dart'), 'D',
-        onlyInStrongMode: false);
-    checkHasDependency(absUri('/a.dart'), fullyLinked: false);
-  }
-
-  test_closure_executable_with_return_type_from_closure() {
-    if (skipFullyLinkedData) {
-      return;
-    }
-    // The closure has type `() => () => int`, where the `() => int` part refers
-    // to the nested closure.
-    UnlinkedExecutable executable = serializeExecutableText('''
-f() {
-  print(() {}); // force the closure below to have index 1
-  print(() => () => 0);
-}
-''');
-    expect(executable.localFunctions, hasLength(2));
-    EntityRef closureType =
-        getTypeRefForSlot(executable.localFunctions[1].inferredReturnTypeSlot);
-    checkLinkedTypeRef(closureType, null, '',
-        expectedKind: ReferenceKind.function);
-    int outerClosureIndex =
-        definingUnit.references[closureType.reference].containingReference;
-    checkReferenceIndex(outerClosureIndex, null, '',
-        expectedKind: ReferenceKind.function);
-    int topLevelFunctionIndex =
-        definingUnit.references[outerClosureIndex].containingReference;
-    checkReferenceIndex(topLevelFunctionIndex, null, 'f',
-        expectedKind: ReferenceKind.topLevelFunction);
-    expect(
-        definingUnit.references[topLevelFunctionIndex].containingReference, 0);
-  }
-
-  test_closure_executable_with_unimported_return_type() {
-    addNamedSource('/a.dart', 'import "b.dart"; class C { D d; }');
-    addNamedSource('/b.dart', 'class D {}');
-    // The closure has type `() => D`; `D` is defined in a library that is not
-    // imported.
-    UnlinkedExecutable executable = serializeVariableText(r'''
-import "a.dart";
-var v = (() {
-  print((() => new C().d)());
-});
-''').initializer.localFunctions[0];
-    expect(executable.localFunctions, hasLength(1));
-    expect(executable.localFunctions[0].returnType, isNull);
-    checkInferredTypeSlot(executable.localFunctions[0].inferredReturnTypeSlot,
-        absUri('/b.dart'), 'D',
-        onlyInStrongMode: false);
-    if (!skipFullyLinkedData) {
-      checkHasDependency('b.dart', fullyLinked: true);
-    }
-  }
-
-  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: [
-      UnlinkedExprOperation.pushInt,
-      UnlinkedExprOperation.pushInt,
-      UnlinkedExprOperation.add
-    ], ints: [
-      1,
-      2
-    ]);
-  }
-
-  test_constExpr_binary_and() {
-    UnlinkedVariable variable =
-        serializeVariableText('const v = true && false;');
-    assertUnlinkedConst(variable.initializer.bodyExpr, 'true && false',
-        operators: [
-          UnlinkedExprOperation.pushTrue,
-          UnlinkedExprOperation.pushFalse,
-          UnlinkedExprOperation.and
-        ]);
-  }
-
-  test_constExpr_binary_bitAnd() {
-    UnlinkedVariable variable = serializeVariableText('const v = 1 & 2;');
-    assertUnlinkedConst(variable.initializer.bodyExpr, '1 & 2', operators: [
-      UnlinkedExprOperation.pushInt,
-      UnlinkedExprOperation.pushInt,
-      UnlinkedExprOperation.bitAnd
-    ], ints: [
-      1,
-      2
-    ]);
-  }
-
-  test_constExpr_binary_bitOr() {
-    UnlinkedVariable variable = serializeVariableText('const v = 1 | 2;');
-    assertUnlinkedConst(variable.initializer.bodyExpr, '1 | 2', operators: [
-      UnlinkedExprOperation.pushInt,
-      UnlinkedExprOperation.pushInt,
-      UnlinkedExprOperation.bitOr
-    ], ints: [
-      1,
-      2
-    ]);
-  }
-
-  test_constExpr_binary_bitShiftLeft() {
-    UnlinkedVariable variable = serializeVariableText('const v = 1 << 2;');
-    assertUnlinkedConst(variable.initializer.bodyExpr, '1 << 2', operators: [
-      UnlinkedExprOperation.pushInt,
-      UnlinkedExprOperation.pushInt,
-      UnlinkedExprOperation.bitShiftLeft
-    ], ints: [
-      1,
-      2
-    ]);
-  }
-
-  test_constExpr_binary_bitShiftRight() {
-    UnlinkedVariable variable = serializeVariableText('const v = 1 >> 2;');
-    assertUnlinkedConst(variable.initializer.bodyExpr, '1 >> 2', operators: [
-      UnlinkedExprOperation.pushInt,
-      UnlinkedExprOperation.pushInt,
-      UnlinkedExprOperation.bitShiftRight
-    ], ints: [
-      1,
-      2
-    ]);
-  }
-
-  test_constExpr_binary_bitShiftRightLogical() {
-    featureSet = FeatureSet.forTesting(
-        sdkVersion: '2.2.2',
-        additionalFeatures: [
-          Feature.constant_update_2018,
-          Feature.triple_shift
-        ]);
-    UnlinkedVariable variable = serializeVariableText('const v = 1 >>> 2;');
-    assertUnlinkedConst(variable.initializer.bodyExpr, '1 >>> 2', operators: [
-      UnlinkedExprOperation.pushInt,
-      UnlinkedExprOperation.pushInt,
-      UnlinkedExprOperation.bitShiftRightLogical
-    ], ints: [
-      1,
-      2
-    ]);
-  }
-
-  test_constExpr_binary_bitXor() {
-    UnlinkedVariable variable = serializeVariableText('const v = 1 ^ 2;');
-    assertUnlinkedConst(variable.initializer.bodyExpr, '1 ^ 2', operators: [
-      UnlinkedExprOperation.pushInt,
-      UnlinkedExprOperation.pushInt,
-      UnlinkedExprOperation.bitXor
-    ], ints: [
-      1,
-      2
-    ]);
-  }
-
-  test_constExpr_binary_divide() {
-    UnlinkedVariable variable = serializeVariableText('const v = 1 / 2;');
-    assertUnlinkedConst(variable.initializer.bodyExpr, '1 / 2', operators: [
-      UnlinkedExprOperation.pushInt,
-      UnlinkedExprOperation.pushInt,
-      UnlinkedExprOperation.divide
-    ], ints: [
-      1,
-      2
-    ]);
-  }
-
-  test_constExpr_binary_equal() {
-    UnlinkedVariable variable = serializeVariableText('const v = 1 == 2;');
-    assertUnlinkedConst(variable.initializer.bodyExpr, '1 == 2', operators: [
-      UnlinkedExprOperation.pushInt,
-      UnlinkedExprOperation.pushInt,
-      UnlinkedExprOperation.equal
-    ], ints: [
-      1,
-      2
-    ]);
-  }
-
-  test_constExpr_binary_equal_not() {
-    UnlinkedVariable variable = serializeVariableText('const v = 1 != 2;');
-    assertUnlinkedConst(variable.initializer.bodyExpr, '1 != 2', operators: [
-      UnlinkedExprOperation.pushInt,
-      UnlinkedExprOperation.pushInt,
-      UnlinkedExprOperation.notEqual
-    ], ints: [
-      1,
-      2
-    ]);
-  }
-
-  test_constExpr_binary_floorDivide() {
-    UnlinkedVariable variable = serializeVariableText('const v = 1 ~/ 2;');
-    assertUnlinkedConst(variable.initializer.bodyExpr, '1 ~/ 2', operators: [
-      UnlinkedExprOperation.pushInt,
-      UnlinkedExprOperation.pushInt,
-      UnlinkedExprOperation.floorDivide
-    ], ints: [
-      1,
-      2
-    ]);
-  }
-
-  test_constExpr_binary_greater() {
-    UnlinkedVariable variable = serializeVariableText('const v = 1 > 2;');
-    assertUnlinkedConst(variable.initializer.bodyExpr, '1 > 2', operators: [
-      UnlinkedExprOperation.pushInt,
-      UnlinkedExprOperation.pushInt,
-      UnlinkedExprOperation.greater
-    ], ints: [
-      1,
-      2
-    ]);
-  }
-
-  test_constExpr_binary_greaterEqual() {
-    UnlinkedVariable variable = serializeVariableText('const v = 1 >= 2;');
-    assertUnlinkedConst(variable.initializer.bodyExpr, '1 >= 2', operators: [
-      UnlinkedExprOperation.pushInt,
-      UnlinkedExprOperation.pushInt,
-      UnlinkedExprOperation.greaterEqual
-    ], ints: [
-      1,
-      2
-    ]);
-  }
-
-  test_constExpr_binary_less() {
-    UnlinkedVariable variable = serializeVariableText('const v = 1 < 2;');
-    assertUnlinkedConst(variable.initializer.bodyExpr, '1 < 2', operators: [
-      UnlinkedExprOperation.pushInt,
-      UnlinkedExprOperation.pushInt,
-      UnlinkedExprOperation.less
-    ], ints: [
-      1,
-      2
-    ]);
-  }
-
-  test_constExpr_binary_lessEqual() {
-    UnlinkedVariable variable = serializeVariableText('const v = 1 <= 2;');
-    assertUnlinkedConst(variable.initializer.bodyExpr, '1 <= 2', operators: [
-      UnlinkedExprOperation.pushInt,
-      UnlinkedExprOperation.pushInt,
-      UnlinkedExprOperation.lessEqual
-    ], ints: [
-      1,
-      2
-    ]);
-  }
-
-  test_constExpr_binary_modulo() {
-    UnlinkedVariable variable = serializeVariableText('const v = 1 % 2;');
-    assertUnlinkedConst(variable.initializer.bodyExpr, '1 % 2', operators: [
-      UnlinkedExprOperation.pushInt,
-      UnlinkedExprOperation.pushInt,
-      UnlinkedExprOperation.modulo
-    ], ints: [
-      1,
-      2
-    ]);
-  }
-
-  test_constExpr_binary_multiply() {
-    UnlinkedVariable variable = serializeVariableText('const v = 1 * 2;');
-    assertUnlinkedConst(variable.initializer.bodyExpr, '1 * 2', operators: [
-      UnlinkedExprOperation.pushInt,
-      UnlinkedExprOperation.pushInt,
-      UnlinkedExprOperation.multiply
-    ], ints: [
-      1,
-      2
-    ]);
-  }
-
-  test_constExpr_binary_or() {
-    UnlinkedVariable variable =
-        serializeVariableText('const v = false || true;');
-    assertUnlinkedConst(variable.initializer.bodyExpr, 'false || true',
-        operators: [
-          UnlinkedExprOperation.pushFalse,
-          UnlinkedExprOperation.pushTrue,
-          UnlinkedExprOperation.or
-        ]);
-  }
-
-  test_constExpr_binary_qq() {
-    UnlinkedVariable variable = serializeVariableText('const v = 1 ?? 2;');
-    assertUnlinkedConst(variable.initializer.bodyExpr, '1 ?? 2', operators: [
-      UnlinkedExprOperation.pushInt,
-      UnlinkedExprOperation.pushInt,
-      UnlinkedExprOperation.ifNull
-    ], ints: [
-      1,
-      2
-    ]);
-  }
-
-  test_constExpr_binary_subtract() {
-    UnlinkedVariable variable = serializeVariableText('const v = 1 - 2;');
-    assertUnlinkedConst(variable.initializer.bodyExpr, '1 - 2', operators: [
-      UnlinkedExprOperation.pushInt,
-      UnlinkedExprOperation.pushInt,
-      UnlinkedExprOperation.subtract
-    ], ints: [
-      1,
-      2
-    ]);
-  }
-
-  test_constExpr_classMember_shadows_typeParam() {
-    // Although it is an error for a class member to have the same name as a
-    // type parameter, the spec makes it clear that the class member scope is
-    // nested inside the type parameter scope.  So go ahead and verify that
-    // the class member shadows the type parameter.
-    String text = '''
-class C<T> {
-  static const T = null;
-  final x;
-  const C() : x = T;
-}
-''';
-    UnlinkedClass cls = serializeClassText(text, allowErrors: true);
-    assertUnlinkedConst(
-        cls.executables[0].constantInitializers[0].expression, 'T',
-        operators: [
-          UnlinkedExprOperation.pushReference
-        ],
-        referenceValidators: [
-          (EntityRef r) => checkTypeRef(r, null, 'T',
-                  expectedKind: ReferenceKind.propertyAccessor,
-                  prefixExpectations: [
-                    new _PrefixExpectation(ReferenceKind.classOrEnum, 'C',
-                        numTypeParameters: 1)
-                  ])
-        ]);
-  }
-
-  test_constExpr_conditional() {
-    UnlinkedVariable variable =
-        serializeVariableText('const v = true ? 1 : 2;', allowErrors: true);
-    assertUnlinkedConst(variable.initializer.bodyExpr, 'true ? 1 : 2',
-        operators: [
-          UnlinkedExprOperation.pushTrue,
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.conditional
-        ],
-        ints: [
-          1,
-          2
-        ]);
-  }
-
-  test_constExpr_constructorParam_shadows_classMember() {
-    UnlinkedClass cls = serializeClassText('''
-class C {
-  static const a = null;
-  final b;
-  const C(a) : b = a;
-}
-''');
-    assertUnlinkedConst(
-        cls.executables[0].constantInitializers[0].expression, 'a',
-        operators: [UnlinkedExprOperation.pushParameter], strings: ['a']);
-  }
-
-  test_constExpr_constructorParam_shadows_typeParam() {
-    UnlinkedClass cls = serializeClassText('''
-class C<T> {
-  final x;
-  const C(T) : x = T;
-}
-''');
-    assertUnlinkedConst(
-        cls.executables[0].constantInitializers[0].expression, 'T',
-        operators: [UnlinkedExprOperation.pushParameter], strings: ['T']);
-  }
-
-  test_constExpr_function_type_arg_nullability_suffix_none() {
-    featureSet = enableNnbd;
-    var variable =
-        serializeVariableText('const v = const <void Function()>[];');
-    assertUnlinkedConst(
-        variable.initializer.bodyExpr, 'const <void Function()>[]', operators: [
-      UnlinkedExprOperation.makeTypedList
-    ], ints: [
-      0
-    ], referenceValidators: [
-      (EntityRef r) =>
-          expect(r.nullabilitySuffix, EntityRefNullabilitySuffix.none)
-    ]);
-  }
-
-  test_constExpr_function_type_arg_nullability_suffix_question() {
-    featureSet = enableNnbd;
-    var variable =
-        serializeVariableText('const v = const <void Function()?>[];');
-    assertUnlinkedConst(
-        variable.initializer.bodyExpr, 'const <void Function()?>[]',
-        operators: [
-          UnlinkedExprOperation.makeTypedList
-        ],
-        ints: [
-          0
-        ],
-        referenceValidators: [
-          (EntityRef r) =>
-              expect(r.nullabilitySuffix, EntityRefNullabilitySuffix.question)
-        ]);
-  }
-
-  test_constExpr_function_type_arg_nullability_suffix_star() {
-    featureSet = disableNnbd;
-    var variable =
-        serializeVariableText('const v = const <void Function()>[];');
-    assertUnlinkedConst(
-        variable.initializer.bodyExpr, 'const <void Function()>[]',
-        operators: [
-          UnlinkedExprOperation.makeTypedList
-        ],
-        ints: [
-          0
-        ],
-        referenceValidators: [
-          (EntityRef r) => expect(
-              r.nullabilitySuffix, EntityRefNullabilitySuffix.starOrIrrelevant)
-        ]);
-  }
-
-  test_constExpr_functionExpression() {
-    UnlinkedVariable variable = serializeVariableText('''
-import 'dart:async';
-var v = (f) async => await f;
-''');
-    assertUnlinkedConst(
-        variable.initializer.localFunctions[0].bodyExpr, 'await f',
-        isValidConst: false,
-        operators: [
-          UnlinkedExprOperation.pushParameter,
-          UnlinkedExprOperation.await
-        ],
-        strings: ['f'],
-        ints: [],
-        forTypeInferenceOnly: true);
-  }
-
-  test_constExpr_functionExpression_asArgument() {
-    // Even though function expressions are not allowed in constant
-    // declarations, they might occur due to erroneous code, so make sure they
-    // function correctly.
-    UnlinkedVariable variable = serializeVariableText('''
-const v = foo(5, () => 42);
-foo(a, b) {}
-''');
-    assertUnlinkedConst(variable.initializer.bodyExpr, 'foo(5, () => 42)',
-        isValidConst: false,
-        operators: [
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.pushLocalFunctionReference,
-          UnlinkedExprOperation.invokeMethodRef
-        ],
-        ints: [
-          5,
-          0,
-          0,
-          0,
-          2,
-          0
-        ],
-        referenceValidators: [
-          (EntityRef r) => checkTypeRef(r, null, 'foo',
-              expectedKind: ReferenceKind.topLevelFunction)
-        ]);
-  }
-
-  test_constExpr_functionExpression_asArgument_multiple() {
-    // Even though function expressions are not allowed in constant
-    // declarations, they might occur due to erroneous code, so make sure they
-    // function correctly.
-    UnlinkedVariable variable = serializeVariableText('''
-const v = foo(5, () => 42, () => 43);
-foo(a, b, c) {}
-''');
-    assertUnlinkedConst(
-        variable.initializer.bodyExpr, 'foo(5, () => 42, () => 43)',
-        isValidConst: false,
-        operators: [
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.pushLocalFunctionReference,
-          UnlinkedExprOperation.pushLocalFunctionReference,
-          UnlinkedExprOperation.invokeMethodRef
-        ],
-        ints: [
-          5,
-          0,
-          0,
-          0,
-          1,
-          0,
-          3,
-          0
-        ],
-        referenceValidators: [
-          (EntityRef r) => checkTypeRef(r, null, 'foo',
-              expectedKind: ReferenceKind.topLevelFunction)
-        ]);
-  }
-
-  test_constExpr_functionExpression_inConstructorInitializers() {
-    // Even though function expressions are not allowed in constant
-    // declarations, they might occur due to erroneous code, so make sure they
-    // function correctly.
-    UnlinkedExecutable executable = serializeClassText('''
-class C {
-  final x, y;
-  const C() : x = (() => 42), y = (() => 43);
-}
-''').executables[0];
-    expect(executable.localFunctions, hasLength(2));
-    assertUnlinkedConst(
-        executable.constantInitializers[0].expression, '(() => 42)',
-        isValidConst: false,
-        operators: [UnlinkedExprOperation.pushLocalFunctionReference],
-        ints: [0, 0]);
-    assertUnlinkedConst(
-        executable.constantInitializers[1].expression, '(() => 43)',
-        isValidConst: false,
-        operators: [UnlinkedExprOperation.pushLocalFunctionReference],
-        ints: [0, 1]);
-  }
-
-  test_constExpr_invokeConstructor_generic_named() {
-    UnlinkedVariable variable = serializeVariableText('''
-class C<K, V> {
-  const C.named();
-}
-const v = const C<int, String>.named();
-''');
-    assertUnlinkedConst(
-        variable.initializer.bodyExpr, 'const C<int, String>.named()',
-        operators: [
-          UnlinkedExprOperation.invokeConstructor,
-        ],
-        ints: [
-          0,
-          0
-        ],
-        referenceValidators: [
-          (EntityRef r) {
-            checkTypeRef(r, null, 'named',
-                expectedKind: ReferenceKind.constructor,
-                prefixExpectations: [
-                  new _PrefixExpectation(ReferenceKind.classOrEnum, 'C',
-                      numTypeParameters: 2)
-                ],
-                numTypeArguments: 2);
-            checkTypeRef(r.typeArguments[0], 'dart:core', 'int');
-            checkTypeRef(r.typeArguments[1], 'dart:core', 'String');
-          }
-        ]);
-  }
-
-  test_constExpr_invokeConstructor_generic_named_imported() {
-    addNamedSource('/a.dart', '''
-class C<K, V> {
-  const C.named();
-}
-''');
-    UnlinkedVariable variable = serializeVariableText('''
-import 'a.dart';
-const v = const C<int, String>.named();
-''');
-    assertUnlinkedConst(
-        variable.initializer.bodyExpr, 'const C<int, String>.named()',
-        operators: [
-          UnlinkedExprOperation.invokeConstructor,
-        ],
-        ints: [
-          0,
-          0
-        ],
-        referenceValidators: [
-          (EntityRef r) {
-            checkTypeRef(r, null, 'named',
-                expectedKind: ReferenceKind.constructor,
-                prefixExpectations: [
-                  new _PrefixExpectation(ReferenceKind.classOrEnum, 'C',
-                      absoluteUri: absUri('/a.dart'), numTypeParameters: 2)
-                ],
-                numTypeArguments: 2);
-            checkTypeRef(r.typeArguments[0], 'dart:core', 'int');
-            checkTypeRef(r.typeArguments[1], 'dart:core', 'String');
-          }
-        ]);
-  }
-
-  test_constExpr_invokeConstructor_generic_named_imported_withPrefix() {
-    addNamedSource('/a.dart', '''
-class C<K, V> {
-  const C.named();
-}
-''');
-    UnlinkedVariable variable = serializeVariableText('''
-import 'a.dart' as p;
-const v = const p.C<int, String>.named();
-''');
-    assertUnlinkedConst(
-        variable.initializer.bodyExpr, 'const p.C<int, String>.named()',
-        operators: [
-          UnlinkedExprOperation.invokeConstructor,
-        ],
-        ints: [
-          0,
-          0
-        ],
-        referenceValidators: [
-          (EntityRef r) {
-            checkTypeRef(r, null, 'named',
-                expectedKind: ReferenceKind.constructor,
-                prefixExpectations: [
-                  new _PrefixExpectation(ReferenceKind.classOrEnum, 'C',
-                      absoluteUri: absUri('/a.dart'), numTypeParameters: 2),
-                  new _PrefixExpectation(ReferenceKind.prefix, 'p')
-                ],
-                numTypeArguments: 2);
-            checkTypeRef(r.typeArguments[0], 'dart:core', 'int');
-            checkTypeRef(r.typeArguments[1], 'dart:core', 'String');
-          }
-        ]);
-  }
-
-  test_constExpr_invokeConstructor_generic_unnamed() {
-    UnlinkedVariable variable = serializeVariableText('''
-class C<K, V> {
-  const C();
-}
-const v = const C<int, String>();
-''');
-    assertUnlinkedConst(variable.initializer.bodyExpr, 'const C<int, String>()',
-        operators: [
-          UnlinkedExprOperation.invokeConstructor,
-        ],
-        ints: [
-          0,
-          0
-        ],
-        referenceValidators: [
-          (EntityRef r) {
-            checkTypeRef(r, null, 'C',
-                expectedKind: ReferenceKind.classOrEnum,
-                numTypeParameters: 2,
-                numTypeArguments: 2);
-            checkTypeRef(r.typeArguments[0], 'dart:core', 'int');
-            checkTypeRef(r.typeArguments[1], 'dart:core', 'String');
-          }
-        ]);
-  }
-
-  test_constExpr_invokeConstructor_generic_unnamed_imported() {
-    addNamedSource('/a.dart', '''
-class C<K, V> {
-  const C();
-}
-''');
-    UnlinkedVariable variable = serializeVariableText('''
-import 'a.dart';
-const v = const C<int, String>();
-''');
-    assertUnlinkedConst(variable.initializer.bodyExpr, 'const C<int, String>()',
-        operators: [
-          UnlinkedExprOperation.invokeConstructor,
-        ],
-        ints: [
-          0,
-          0
-        ],
-        referenceValidators: [
-          (EntityRef r) {
-            checkTypeRef(r, absUri('/a.dart'), 'C',
-                expectedKind: ReferenceKind.classOrEnum,
-                numTypeParameters: 2,
-                numTypeArguments: 2);
-            checkTypeRef(r.typeArguments[0], 'dart:core', 'int');
-            checkTypeRef(r.typeArguments[1], 'dart:core', 'String');
-          }
-        ]);
-  }
-
-  test_constExpr_invokeConstructor_generic_unnamed_imported_withPrefix() {
-    addNamedSource('/a.dart', '''
-class C<K, V> {
-  const C();
-}
-''');
-    UnlinkedVariable variable = serializeVariableText('''
-import 'a.dart' as p;
-const v = const p.C<int, String>();
-''');
-    assertUnlinkedConst(
-        variable.initializer.bodyExpr, 'const p.C<int, String>()',
-        operators: [
-          UnlinkedExprOperation.invokeConstructor,
-        ],
-        ints: [
-          0,
-          0
-        ],
-        referenceValidators: [
-          (EntityRef r) {
-            checkTypeRef(r, absUri('/a.dart'), 'C',
-                expectedKind: ReferenceKind.classOrEnum,
-                numTypeParameters: 2,
-                numTypeArguments: 2,
-                prefixExpectations: [
-                  new _PrefixExpectation(ReferenceKind.prefix, 'p')
-                ]);
-            checkTypeRef(r.typeArguments[0], 'dart:core', 'int');
-            checkTypeRef(r.typeArguments[1], 'dart:core', 'String');
-          }
-        ]);
-  }
-
-  test_constExpr_invokeConstructor_named() {
-    UnlinkedVariable variable = serializeVariableText('''
-class C {
-  const C.named();
-}
-const v = const C.named();
-''');
-    assertUnlinkedConst(variable.initializer.bodyExpr, 'const C.named()',
-        operators: [
-          UnlinkedExprOperation.invokeConstructor,
-        ],
-        ints: [
-          0,
-          0
-        ],
-        referenceValidators: [
-          (EntityRef r) => checkTypeRef(r, null, 'named',
-                  expectedKind: ReferenceKind.constructor,
-                  prefixExpectations: [
-                    new _PrefixExpectation(ReferenceKind.classOrEnum, 'C')
-                  ])
-        ]);
-  }
-
-  test_constExpr_invokeConstructor_named_imported() {
-    addNamedSource('/a.dart', '''
-class C {
-  const C.named();
-}
-''');
-    UnlinkedVariable variable = serializeVariableText('''
-import 'a.dart';
-const v = const C.named();
-''');
-    assertUnlinkedConst(variable.initializer.bodyExpr, 'const C.named()',
-        operators: [
-          UnlinkedExprOperation.invokeConstructor,
-        ],
-        ints: [
-          0,
-          0
-        ],
-        referenceValidators: [
-          (EntityRef r) => checkTypeRef(r, null, 'named',
-                  expectedKind: ReferenceKind.constructor,
-                  prefixExpectations: [
-                    new _PrefixExpectation(ReferenceKind.classOrEnum, 'C',
-                        absoluteUri: absUri('/a.dart'))
-                  ])
-        ]);
-  }
-
-  test_constExpr_invokeConstructor_named_imported_withPrefix() {
-    addNamedSource('/a.dart', '''
-class C {
-  const C.named();
-}
-''');
-    UnlinkedVariable variable = serializeVariableText('''
-import 'a.dart' as p;
-const v = const p.C.named();
-''');
-    assertUnlinkedConst(variable.initializer.bodyExpr, 'const p.C.named()',
-        operators: [
-          UnlinkedExprOperation.invokeConstructor,
-        ],
-        ints: [
-          0,
-          0
-        ],
-        referenceValidators: [
-          (EntityRef r) => checkTypeRef(r, null, 'named',
-                  expectedKind: ReferenceKind.constructor,
-                  prefixExpectations: [
-                    new _PrefixExpectation(ReferenceKind.classOrEnum, 'C',
-                        absoluteUri: absUri('/a.dart')),
-                    new _PrefixExpectation(ReferenceKind.prefix, 'p')
-                  ])
-        ]);
-  }
-
-  test_constExpr_invokeConstructor_unnamed() {
-    UnlinkedVariable variable = serializeVariableText('''
-class C {
-  const C(a, b, c, d, {e, f, g});
-}
-const v = const C(11, 22, 3.3, '444', e: 55, g: '777', f: 66);
-''');
-    // Stack: 11 22 3.3 '444' 55 '777' 66 ^head
-    // Ints: ^pointer 3 4
-    // Doubles: ^pointer
-    // Strings: ^pointer 'e' 'g' 'f' ''
-    assertUnlinkedConst(variable.initializer.bodyExpr,
-        "const C(11, 22, 3.3, '444', e: 55, g: '777', f: 66)",
-        operators: [
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.pushDouble,
-          UnlinkedExprOperation.pushString,
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.pushString,
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.invokeConstructor,
-        ],
-        ints: [
-          11,
-          22,
-          55,
-          66,
-          3,
-          4,
-        ],
-        doubles: [
-          3.3
-        ],
-        strings: [
-          '444',
-          '777',
-          'e',
-          'g',
-          'f'
-        ],
-        referenceValidators: [
-          (EntityRef r) => checkTypeRef(r, null, 'C',
-              expectedKind: ReferenceKind.classOrEnum)
-        ]);
-  }
-
-  test_constExpr_invokeConstructor_unnamed_imported() {
-    addNamedSource('/a.dart', '''
-class C {
-  const C();
-}
-''');
-    UnlinkedVariable variable = serializeVariableText('''
-import 'a.dart';
-const v = const C();
-''');
-    assertUnlinkedConst(variable.initializer.bodyExpr, 'const C()', operators: [
-      UnlinkedExprOperation.invokeConstructor,
-    ], ints: [
-      0,
-      0
-    ], referenceValidators: [
-      (EntityRef r) => checkTypeRef(r, absUri('/a.dart'), 'C',
-          expectedKind: ReferenceKind.classOrEnum)
-    ]);
-  }
-
-  test_constExpr_invokeConstructor_unnamed_imported_withPrefix() {
-    addNamedSource('/a.dart', '''
-class C {
-  const C();
-}
-''');
-    UnlinkedVariable variable = serializeVariableText('''
-import 'a.dart' as p;
-const v = const p.C();
-''');
-    assertUnlinkedConst(variable.initializer.bodyExpr, 'const p.C()',
-        operators: [
-          UnlinkedExprOperation.invokeConstructor,
-        ],
-        ints: [
-          0,
-          0
-        ],
-        referenceValidators: [
-          (EntityRef r) => checkTypeRef(r, absUri('/a.dart'), 'C',
-                  expectedKind: ReferenceKind.classOrEnum,
-                  prefixExpectations: [
-                    new _PrefixExpectation(ReferenceKind.prefix, 'p')
-                  ])
-        ]);
-  }
-
-  test_constExpr_invokeConstructor_unresolved_named() {
-    UnlinkedVariable variable = serializeVariableText('''
-class C {}
-const v = const C.foo();
-''', allowErrors: true);
-    assertUnlinkedConst(variable.initializer.bodyExpr, 'const C.foo()',
-        operators: [
-          UnlinkedExprOperation.invokeConstructor,
-        ],
-        ints: [
-          0,
-          0
-        ],
-        referenceValidators: [
-          (EntityRef r) => checkTypeRef(r, null, 'foo',
-                  expectedKind: ReferenceKind.unresolved,
-                  prefixExpectations: [
-                    new _PrefixExpectation(ReferenceKind.classOrEnum, 'C')
-                  ])
-        ]);
-  }
-
-  test_constExpr_invokeConstructor_unresolved_named2() {
-    UnlinkedVariable variable = serializeVariableText('''
-const v = const C.foo();
-''', allowErrors: true);
-    assertUnlinkedConst(variable.initializer.bodyExpr, 'const C.foo()',
-        operators: [
-          UnlinkedExprOperation.invokeConstructor,
-        ],
-        ints: [
-          0,
-          0
-        ],
-        referenceValidators: [
-          (EntityRef r) => checkTypeRef(r, null, 'foo',
-                  expectedKind: ReferenceKind.unresolved,
-                  prefixExpectations: [
-                    new _PrefixExpectation(ReferenceKind.unresolved, 'C')
-                  ])
-        ]);
-  }
-
-  test_constExpr_invokeConstructor_unresolved_named_prefixed() {
-    addNamedSource('/a.dart', '''
-class C {
-}
-''');
-    UnlinkedVariable variable = serializeVariableText('''
-import 'a.dart' as p;
-const v = const p.C.foo();
-''', allowErrors: true);
-    assertUnlinkedConst(variable.initializer.bodyExpr, 'const p.C.foo()',
-        operators: [
-          UnlinkedExprOperation.invokeConstructor,
-        ],
-        ints: [
-          0,
-          0
-        ],
-        referenceValidators: [
-          (EntityRef r) => checkTypeRef(r, null, 'foo',
-                  expectedKind: ReferenceKind.unresolved,
-                  prefixExpectations: [
-                    new _PrefixExpectation(ReferenceKind.classOrEnum, 'C',
-                        absoluteUri: absUri('/a.dart')),
-                    new _PrefixExpectation(ReferenceKind.prefix, 'p')
-                  ])
-        ]);
-  }
-
-  test_constExpr_invokeConstructor_unresolved_named_prefixed2() {
-    addNamedSource('/a.dart', '');
-    UnlinkedVariable variable = serializeVariableText('''
-import 'a.dart' as p;
-const v = const p.C.foo();
-''', allowErrors: true);
-    assertUnlinkedConst(variable.initializer.bodyExpr, 'const p.C.foo()',
-        operators: [
-          UnlinkedExprOperation.invokeConstructor,
-        ],
-        ints: [
-          0,
-          0
-        ],
-        referenceValidators: [
-          (EntityRef r) => checkTypeRef(r, null, 'foo',
-                  expectedKind: ReferenceKind.unresolved,
-                  prefixExpectations: [
-                    new _PrefixExpectation(ReferenceKind.unresolved, 'C'),
-                    new _PrefixExpectation(ReferenceKind.prefix, 'p')
-                  ])
-        ]);
-  }
-
-  test_constExpr_invokeConstructor_unresolved_unnamed() {
-    UnlinkedVariable variable = serializeVariableText('''
-const v = const Foo();
-''', allowErrors: true);
-    assertUnlinkedConst(variable.initializer.bodyExpr, 'const Foo()',
-        operators: [
-          UnlinkedExprOperation.invokeConstructor,
-        ],
-        ints: [
-          0,
-          0
-        ],
-        referenceValidators: [
-          (EntityRef r) => checkTypeRef(r, null, 'Foo',
-              expectedKind: ReferenceKind.unresolved)
-        ]);
-  }
-
-  test_constExpr_invokeMethodRef_identical() {
-    UnlinkedVariable variable =
-        serializeVariableText('const v = identical(42, null);');
-    assertUnlinkedConst(variable.initializer.bodyExpr, 'identical(42, null)',
-        operators: [
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.pushNull,
-          UnlinkedExprOperation.invokeMethodRef
-        ],
-        ints: [
-          42,
-          0,
-          2,
-          0
-        ],
-        referenceValidators: [
-          (EntityRef r) {
-            checkTypeRef(r, 'dart:core', 'identical',
-                expectedKind: ReferenceKind.topLevelFunction);
-          }
-        ]);
-  }
-
-  test_constExpr_length_classConstField() {
-    UnlinkedVariable variable = serializeVariableText('''
-class C {
-  static const int length = 0;
-}
-const int v = C.length;
-''');
-    assertUnlinkedConst(variable.initializer.bodyExpr, 'C.length', operators: [
-      UnlinkedExprOperation.pushReference
-    ], referenceValidators: [
-      (EntityRef r) => checkTypeRef(r, null, 'length',
-              expectedKind: ReferenceKind.propertyAccessor,
-              prefixExpectations: [
-                new _PrefixExpectation(ReferenceKind.classOrEnum, 'C')
-              ])
-    ]);
-  }
-
-  test_constExpr_length_classConstField_imported_withPrefix() {
-    addNamedSource('/a.dart', '''
-class C {
-  static const int length = 0;
-}
-''');
-    UnlinkedVariable variable = serializeVariableText('''
-import 'a.dart' as p;
-const int v = p.C.length;
-''');
-    assertUnlinkedConst(variable.initializer.bodyExpr, 'p.C.length',
-        operators: [
-          UnlinkedExprOperation.pushReference
-        ],
-        referenceValidators: [
-          (EntityRef r) => checkTypeRef(r, null, 'length',
-                  expectedKind: ReferenceKind.propertyAccessor,
-                  prefixExpectations: [
-                    new _PrefixExpectation(ReferenceKind.classOrEnum, 'C',
-                        absoluteUri: absUri('/a.dart')),
-                    new _PrefixExpectation(ReferenceKind.prefix, 'p')
-                  ])
-        ]);
-  }
-
-  test_constExpr_length_identifierTarget() {
-    UnlinkedVariable variable = serializeVariableText('''
-const String a = 'aaa';
-const int v = a.length;
-''');
-    assertUnlinkedConst(variable.initializer.bodyExpr, 'a.length', operators: [
-      UnlinkedExprOperation.pushReference
-    ], referenceValidators: [
-      (EntityRef r) => checkTypeRef(r, null, 'length',
-              expectedKind: ReferenceKind.unresolved,
-              unresolvedHasName: true,
-              prefixExpectations: [
-                new _PrefixExpectation(
-                    ReferenceKind.topLevelPropertyAccessor, 'a')
-              ])
-    ]);
-  }
-
-  test_constExpr_length_identifierTarget_classConstField() {
-    UnlinkedVariable variable = serializeVariableText('''
-class C {
-  static const String F = '';
-}
-const int v = C.F.length;
-''');
-    assertUnlinkedConst(variable.initializer.bodyExpr, 'C.F.length',
-        operators: [
-          UnlinkedExprOperation.pushReference
-        ],
-        referenceValidators: [
-          (EntityRef r) => checkTypeRef(r, null, 'length',
-                  expectedKind: ReferenceKind.unresolved,
-                  unresolvedHasName: true,
-                  prefixExpectations: [
-                    new _PrefixExpectation(ReferenceKind.propertyAccessor, 'F'),
-                    new _PrefixExpectation(ReferenceKind.classOrEnum, 'C'),
-                  ])
-        ]);
-  }
-
-  test_constExpr_length_identifierTarget_imported() {
-    addNamedSource('/a.dart', '''
-const String a = 'aaa';
-''');
-    UnlinkedVariable variable = serializeVariableText('''
-import 'a.dart';
-const int v = a.length;
-''');
-    assertUnlinkedConst(variable.initializer.bodyExpr, 'a.length', operators: [
-      UnlinkedExprOperation.pushReference
-    ], referenceValidators: [
-      (EntityRef r) => checkTypeRef(r, null, 'length',
-              expectedKind: ReferenceKind.unresolved,
-              unresolvedHasName: true,
-              prefixExpectations: [
-                new _PrefixExpectation(
-                    ReferenceKind.topLevelPropertyAccessor, 'a',
-                    absoluteUri: absUri('/a.dart'))
-              ])
-    ]);
-  }
-
-  test_constExpr_length_identifierTarget_imported_withPrefix() {
-    addNamedSource('/a.dart', '''
-const String a = 'aaa';
-''');
-    UnlinkedVariable variable = serializeVariableText('''
-import 'a.dart' as p;
-const int v = p.a.length;
-''');
-    assertUnlinkedConst(variable.initializer.bodyExpr, 'p.a.length',
-        operators: [
-          UnlinkedExprOperation.pushReference
-        ],
-        referenceValidators: [
-          (EntityRef r) => checkTypeRef(r, null, 'length',
-                  expectedKind: ReferenceKind.unresolved,
-                  unresolvedHasName: true,
-                  prefixExpectations: [
-                    new _PrefixExpectation(
-                        ReferenceKind.topLevelPropertyAccessor, 'a',
-                        absoluteUri: absUri('/a.dart')),
-                    new _PrefixExpectation(ReferenceKind.prefix, 'p')
-                  ])
-        ]);
-  }
-
-  test_constExpr_length_parenthesizedBinaryTarget() {
-    UnlinkedVariable variable =
-        serializeVariableText('const v = ("abc" + "edf").length;');
-    assertUnlinkedConst(variable.initializer.bodyExpr, '("abc" + "edf").length',
-        operators: [
-          UnlinkedExprOperation.pushString,
-          UnlinkedExprOperation.pushString,
-          UnlinkedExprOperation.add,
-          UnlinkedExprOperation.extractProperty
-        ],
-        strings: [
-          'abc',
-          'edf',
-          'length'
-        ]);
-  }
-
-  test_constExpr_length_parenthesizedStringTarget() {
-    UnlinkedVariable variable =
-        serializeVariableText('const v = ("abc").length;');
-    assertUnlinkedConst(variable.initializer.bodyExpr, '("abc").length',
-        operators: [
-          UnlinkedExprOperation.pushString,
-          UnlinkedExprOperation.extractProperty
-        ],
-        strings: [
-          'abc',
-          'length'
-        ]);
-  }
-
-  test_constExpr_length_stringLiteralTarget() {
-    UnlinkedVariable variable =
-        serializeVariableText('const v = "abc".length;');
-    assertUnlinkedConst(variable.initializer.bodyExpr, '"abc".length',
-        operators: [
-          UnlinkedExprOperation.pushString,
-          UnlinkedExprOperation.extractProperty
-        ],
-        strings: [
-          'abc',
-          'length'
-        ]);
-  }
-
-  test_constExpr_list_if() {
-    UnlinkedVariable variable =
-        serializeVariableText('const v = [if (true) 1];');
-    assertUnlinkedConst(variable.initializer.bodyExpr, '[if (true) 1]',
-        operators: [
-          UnlinkedExprOperation.pushTrue,
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.ifElement,
-          UnlinkedExprOperation.makeUntypedList
-        ],
-        ints: [
-          1,
-          1
-        ]);
-  }
-
-  test_constExpr_list_if_else() {
-    UnlinkedVariable variable =
-        serializeVariableText('const v = [if (true) 1 else 2];');
-    assertUnlinkedConst(variable.initializer.bodyExpr, '[if (true) 1 else 2]',
-        operators: [
-          UnlinkedExprOperation.pushTrue,
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.ifElseElement,
-          UnlinkedExprOperation.makeUntypedList
-        ],
-        ints: [
-          1,
-          2,
-          1
-        ]);
-  }
-
-  test_constExpr_list_spread() {
-    UnlinkedVariable variable = serializeVariableText('const v = [...[]];');
-    assertUnlinkedConst(variable.initializer.bodyExpr, '[...[]]', operators: [
-      UnlinkedExprOperation.makeUntypedList,
-      UnlinkedExprOperation.spreadElement,
-      UnlinkedExprOperation.makeUntypedList
-    ], ints: [
-      0,
-      1
-    ]);
-  }
-
-  test_constExpr_list_spread_null_aware() {
-    UnlinkedVariable variable = serializeVariableText('const v = [...?[]];');
-    assertUnlinkedConst(variable.initializer.bodyExpr, '[...?[]]', operators: [
-      UnlinkedExprOperation.makeUntypedList,
-      UnlinkedExprOperation.nullAwareSpreadElement,
-      UnlinkedExprOperation.makeUntypedList
-    ], ints: [
-      0,
-      1
-    ]);
-  }
-
-  test_constExpr_makeSymbol() {
-    UnlinkedVariable variable = serializeVariableText('const v = #a.bb.ccc;');
-    assertUnlinkedConst(variable.initializer.bodyExpr, '#a.bb.ccc',
-        operators: [UnlinkedExprOperation.makeSymbol], strings: ['a.bb.ccc']);
-  }
-
-  test_constExpr_makeTypedList() {
-    UnlinkedVariable variable =
-        serializeVariableText('const v = const <int>[11, 22, 33];');
-    assertUnlinkedConst(
-        variable.initializer.bodyExpr, 'const <int>[11, 22, 33]',
-        operators: [
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.makeTypedList
-        ],
-        ints: [
-          11,
-          22,
-          33,
-          3
-        ],
-        referenceValidators: [
-          (EntityRef r) => checkTypeRef(r, 'dart:core', 'int',
-              expectedKind: ReferenceKind.classOrEnum)
-        ]);
-  }
-
-  test_constExpr_makeTypedList_dynamic() {
-    UnlinkedVariable variable =
-        serializeVariableText('const v = const <dynamic>[11, 22, 33];');
-    assertUnlinkedConst(
-        variable.initializer.bodyExpr, 'const <dynamic>[11, 22, 33]',
-        operators: [
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.makeTypedList
-        ],
-        ints: [
-          11,
-          22,
-          33,
-          3
-        ],
-        referenceValidators: [
-          (EntityRef r) => checkDynamicTypeRef(r)
-        ]);
-  }
-
-  test_constExpr_makeTypedList_functionType() {
-    UnlinkedVariable variable =
-        serializeVariableText('final v = <void Function(int)>[];');
-    assertUnlinkedConst(variable.initializer.bodyExpr, '<void Function(int)>[]',
-        operators: [UnlinkedExprOperation.makeTypedList],
-        ints: [
-          0 // Size of the list
-        ],
-        referenceValidators: [
-          (EntityRef reference) {
-            expect(reference, new TypeMatcher<EntityRef>());
-            expect(reference.entityKind, EntityRefKind.genericFunctionType);
-            expect(reference.syntheticParams, hasLength(1));
-            {
-              final param = reference.syntheticParams[0];
-              expect(param.name, ''); // no name for generic type parameters
-              checkTypeRef(param.type, 'dart:core', 'int',
-                  expectedKind: ReferenceKind.classOrEnum);
-            }
-            expect(reference.paramReference, 0);
-            expect(reference.typeParameters, hasLength(0));
-            // TODO(mfairhurst) check this references void
-            expect(reference.syntheticReturnType, isNotNull);
-          }
-        ],
-        forTypeInferenceOnly: true);
-  }
-
-  test_constExpr_makeTypedList_functionType_withTypeParameters() {
-    UnlinkedVariable variable = serializeVariableText(
-        'final v = <void Function<T>(Function<Q>(T, Q))>[];');
-    assertUnlinkedConst(variable.initializer.bodyExpr,
-        '<void Function<T>(Function<Q>(T, Q))>[]',
-        operators: [UnlinkedExprOperation.makeTypedList],
-        ints: [
-          0 // Size of the list
-        ],
-        referenceValidators: [
-          (EntityRef reference) {
-            expect(reference, new TypeMatcher<EntityRef>());
-            expect(reference.entityKind, EntityRefKind.genericFunctionType);
-            expect(reference.syntheticParams, hasLength(1));
-            {
-              final param = reference.syntheticParams[0];
-              expect(param.type, new TypeMatcher<EntityRef>());
-              expect(param.type.entityKind, EntityRefKind.genericFunctionType);
-              expect(param.type.syntheticParams, hasLength(2));
-              {
-                final subparam = param.type.syntheticParams[0];
-                expect(
-                    subparam.name, ''); // no name for generic type parameters
-                expect(subparam.type, new TypeMatcher<EntityRef>());
-                expect(subparam.type.paramReference, 2);
-              }
-              {
-                final subparam = param.type.syntheticParams[1];
-                expect(
-                    subparam.name, ''); // no name for generic type parameters
-                expect(subparam.type, new TypeMatcher<EntityRef>());
-                expect(subparam.type.paramReference, 1);
-              }
-            }
-            expect(reference.paramReference, 0);
-            expect(reference.typeParameters, hasLength(1));
-            // TODO(mfairhurst) check this references void
-            expect(reference.syntheticReturnType, isNotNull);
-          }
-        ],
-        forTypeInferenceOnly: true);
-  }
-
-  test_constExpr_makeTypedMap() {
-    UnlinkedVariable variable = serializeVariableText(
-        'const v = const <int, String>{11: "aaa", 22: "bbb", 33: "ccc"};');
-    assertUnlinkedConst(variable.initializer.bodyExpr,
-        'const <int, String>{11: "aaa", 22: "bbb", 33: "ccc"}',
-        operators: [
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.pushString,
-          UnlinkedExprOperation.makeMapLiteralEntry,
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.pushString,
-          UnlinkedExprOperation.makeMapLiteralEntry,
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.pushString,
-          UnlinkedExprOperation.makeMapLiteralEntry,
-          UnlinkedExprOperation.makeTypedMap2
-        ],
-        ints: [
-          11,
-          22,
-          33,
-          3
-        ],
-        strings: [
-          'aaa',
-          'bbb',
-          'ccc'
-        ],
-        referenceValidators: [
-          (EntityRef r) => checkTypeRef(r, 'dart:core', 'int',
-              expectedKind: ReferenceKind.classOrEnum),
-          (EntityRef r) => checkTypeRef(r, 'dart:core', 'String',
-              expectedKind: ReferenceKind.classOrEnum)
-        ]);
-  }
-
-  test_constExpr_makeTypedMap_dynamic() {
-    UnlinkedVariable variable = serializeVariableText(
-        'const v = const <dynamic, dynamic>{11: "aaa", 22: "bbb", 33: "ccc"};');
-    assertUnlinkedConst(variable.initializer.bodyExpr,
-        'const <dynamic, dynamic>{11: "aaa", 22: "bbb", 33: "ccc"}',
-        operators: [
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.pushString,
-          UnlinkedExprOperation.makeMapLiteralEntry,
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.pushString,
-          UnlinkedExprOperation.makeMapLiteralEntry,
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.pushString,
-          UnlinkedExprOperation.makeMapLiteralEntry,
-          UnlinkedExprOperation.makeTypedMap2
-        ],
-        ints: [
-          11,
-          22,
-          33,
-          3
-        ],
-        strings: [
-          'aaa',
-          'bbb',
-          'ccc'
-        ],
-        referenceValidators: [
-          (EntityRef r) => checkDynamicTypeRef(r),
-          (EntityRef r) => checkDynamicTypeRef(r)
-        ]);
-  }
-
-  test_constExpr_makeTypedSet() {
-    UnlinkedVariable variable =
-        serializeVariableText('const v = const <int>{11, 22, 33};');
-    assertUnlinkedConst(
-      variable.initializer.bodyExpr,
-      'const <int>{11, 22, 33}',
-      operators: [
-        UnlinkedExprOperation.pushInt,
-        UnlinkedExprOperation.pushInt,
-        UnlinkedExprOperation.pushInt,
-        UnlinkedExprOperation.makeTypedSet
-      ],
-      ints: [11, 22, 33, 3],
-      referenceValidators: [
-        (EntityRef r) => checkTypeRef(r, 'dart:core', 'int',
-            expectedKind: ReferenceKind.classOrEnum)
-      ],
-    );
-  }
-
-  test_constExpr_makeTypedSet_dynamic() {
-    UnlinkedVariable variable =
-        serializeVariableText('const v = const <dynamic>{11, 22, 33};');
-    assertUnlinkedConst(
-      variable.initializer.bodyExpr,
-      'const <dynamic>{11, 22, 33}',
-      operators: [
-        UnlinkedExprOperation.pushInt,
-        UnlinkedExprOperation.pushInt,
-        UnlinkedExprOperation.pushInt,
-        UnlinkedExprOperation.makeTypedSet
-      ],
-      ints: [11, 22, 33, 3],
-      referenceValidators: [(EntityRef r) => checkDynamicTypeRef(r)],
-    );
-  }
-
-  test_constExpr_makeTypedSet_functionType() {
-    UnlinkedVariable variable =
-        serializeVariableText('final v = <void Function(int)>{};');
-    assertUnlinkedConst(variable.initializer.bodyExpr, '<void Function(int)>{}',
-        operators: [UnlinkedExprOperation.makeTypedSet],
-        ints: [
-          0 // Size of the list
-        ],
-        referenceValidators: [
-          (EntityRef reference) {
-            expect(reference, new TypeMatcher<EntityRef>());
-            expect(reference.entityKind, EntityRefKind.genericFunctionType);
-            expect(reference.syntheticParams, hasLength(1));
-            {
-              final param = reference.syntheticParams[0];
-              expect(param.name, ''); // no name for generic type parameters
-              checkTypeRef(param.type, 'dart:core', 'int',
-                  expectedKind: ReferenceKind.classOrEnum);
-            }
-            expect(reference.paramReference, 0);
-            expect(reference.typeParameters, hasLength(0));
-            // TODO(mfairhurst) check this references void
-            expect(reference.syntheticReturnType, isNotNull);
-          }
-        ],
-        forTypeInferenceOnly: true);
-  }
-
-  test_constExpr_makeTypedSet_functionType_withTypeParameters() {
-    UnlinkedVariable variable = serializeVariableText(
-        'final v = <void Function<T>(Function<Q>(T, Q))>{};');
-    assertUnlinkedConst(variable.initializer.bodyExpr,
-        '<void Function<T>(Function<Q>(T, Q))>{}',
-        operators: [UnlinkedExprOperation.makeTypedSet],
-        ints: [
-          0 // Size of the list
-        ],
-        referenceValidators: [
-          (EntityRef reference) {
-            expect(reference, new TypeMatcher<EntityRef>());
-            expect(reference.entityKind, EntityRefKind.genericFunctionType);
-            expect(reference.syntheticParams, hasLength(1));
-            {
-              final param = reference.syntheticParams[0];
-              expect(param.type, new TypeMatcher<EntityRef>());
-              expect(param.type.entityKind, EntityRefKind.genericFunctionType);
-              expect(param.type.syntheticParams, hasLength(2));
-              {
-                final subparam = param.type.syntheticParams[0];
-                expect(
-                    subparam.name, ''); // no name for generic type parameters
-                expect(subparam.type, new TypeMatcher<EntityRef>());
-                expect(subparam.type.paramReference, 2);
-              }
-              {
-                final subparam = param.type.syntheticParams[1];
-                expect(
-                    subparam.name, ''); // no name for generic type parameters
-                expect(subparam.type, new TypeMatcher<EntityRef>());
-                expect(subparam.type.paramReference, 1);
-              }
-            }
-            expect(reference.paramReference, 0);
-            expect(reference.typeParameters, hasLength(1));
-            // TODO(mfairhurst) check this references void
-            expect(reference.syntheticReturnType, isNotNull);
-          }
-        ],
-        forTypeInferenceOnly: true);
-  }
-
-  test_constExpr_makeUntypedList() {
-    UnlinkedVariable variable =
-        serializeVariableText('const v = const [11, 22, 33];');
-    assertUnlinkedConst(variable.initializer.bodyExpr, 'const [11, 22, 33]',
-        operators: [
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.makeUntypedList
-        ],
-        ints: [
-          11,
-          22,
-          33,
-          3
-        ]);
-  }
-
-  test_constExpr_makeUntypedMap() {
-    UnlinkedVariable variable = serializeVariableText(
-        'const v = const {11: "aaa", 22: "bbb", 33: "ccc"};');
-    assertUnlinkedConst(variable.initializer.bodyExpr,
-        'const {11: "aaa", 22: "bbb", 33: "ccc"}',
-        operators: [
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.pushString,
-          UnlinkedExprOperation.makeMapLiteralEntry,
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.pushString,
-          UnlinkedExprOperation.makeMapLiteralEntry,
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.pushString,
-          UnlinkedExprOperation.makeMapLiteralEntry,
-          UnlinkedExprOperation.makeUntypedSetOrMap
-        ],
-        ints: [
-          11,
-          22,
-          33,
-          3
-        ],
-        strings: [
-          'aaa',
-          'bbb',
-          'ccc'
-        ]);
-  }
-
-  test_constExpr_makeUntypedSet() {
-    UnlinkedVariable variable =
-        serializeVariableText('const v = const {11, 22, 33};');
-    assertUnlinkedConst(
-      variable.initializer.bodyExpr,
-      'const {11, 22, 33}',
-      operators: [
-        UnlinkedExprOperation.pushInt,
-        UnlinkedExprOperation.pushInt,
-        UnlinkedExprOperation.pushInt,
-        UnlinkedExprOperation.makeUntypedSetOrMap
-      ],
-      ints: [11, 22, 33, 3],
-    );
-  }
-
-  test_constExpr_map_if() {
-    UnlinkedVariable variable =
-        serializeVariableText('const v = <int, int>{if (true) 1 : 2};');
-    assertUnlinkedConst(
-        variable.initializer.bodyExpr, '<int, int>{if (true) 1 : 2}',
-        operators: [
-          UnlinkedExprOperation.pushTrue,
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.makeMapLiteralEntry,
-          UnlinkedExprOperation.ifElement,
-          UnlinkedExprOperation.makeTypedMap2
-        ],
-        ints: [
-          1,
-          2,
-          1
-        ],
-        referenceValidators: [
-          (EntityRef r) => checkTypeRef(r, 'dart:core', 'int',
-              expectedKind: ReferenceKind.classOrEnum),
-          (EntityRef r) => checkTypeRef(r, 'dart:core', 'int',
-              expectedKind: ReferenceKind.classOrEnum)
-        ]);
-  }
-
-  test_constExpr_map_if_else() {
-    UnlinkedVariable variable = serializeVariableText(
-        'const v = <int, int>{if (true) 1 : 2 else 3 : 4};');
-    assertUnlinkedConst(
-        variable.initializer.bodyExpr, '<int, int>{if (true) 1 : 2 else 3 : 4}',
-        operators: [
-          UnlinkedExprOperation.pushTrue,
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.makeMapLiteralEntry,
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.makeMapLiteralEntry,
-          UnlinkedExprOperation.ifElseElement,
-          UnlinkedExprOperation.makeTypedMap2
-        ],
-        ints: [
-          1,
-          2,
-          3,
-          4,
-          1
-        ],
-        referenceValidators: [
-          (EntityRef r) => checkTypeRef(r, 'dart:core', 'int',
-              expectedKind: ReferenceKind.classOrEnum),
-          (EntityRef r) => checkTypeRef(r, 'dart:core', 'int',
-              expectedKind: ReferenceKind.classOrEnum)
-        ]);
-  }
-
-  test_constExpr_map_spread() {
-    UnlinkedVariable variable =
-        serializeVariableText('const v = <int, String>{...<int, String>{}};');
-    assertUnlinkedConst(
-        variable.initializer.bodyExpr, '<int, String>{...<int, String>{}}',
-        operators: [
-          UnlinkedExprOperation.makeTypedMap2,
-          UnlinkedExprOperation.spreadElement,
-          UnlinkedExprOperation.makeTypedMap2
-        ],
-        ints: [
-          0,
-          1
-        ],
-        referenceValidators: [
-          (EntityRef r) => checkTypeRef(r, 'dart:core', 'int',
-              expectedKind: ReferenceKind.classOrEnum),
-          (EntityRef r) => checkTypeRef(r, 'dart:core', 'String',
-              expectedKind: ReferenceKind.classOrEnum),
-          (EntityRef r) => checkTypeRef(r, 'dart:core', 'int',
-              expectedKind: ReferenceKind.classOrEnum),
-          (EntityRef r) => checkTypeRef(r, 'dart:core', 'String',
-              expectedKind: ReferenceKind.classOrEnum)
-        ]);
-  }
-
-  test_constExpr_map_spread_null_aware() {
-    UnlinkedVariable variable =
-        serializeVariableText('const v = <int, String>{...?<int, String>{}};');
-    assertUnlinkedConst(
-        variable.initializer.bodyExpr, '<int, String>{...?<int, String>{}}',
-        operators: [
-          UnlinkedExprOperation.makeTypedMap2,
-          UnlinkedExprOperation.nullAwareSpreadElement,
-          UnlinkedExprOperation.makeTypedMap2
-        ],
-        ints: [
-          0,
-          1
-        ],
-        referenceValidators: [
-          (EntityRef r) => checkTypeRef(r, 'dart:core', 'int',
-              expectedKind: ReferenceKind.classOrEnum),
-          (EntityRef r) => checkTypeRef(r, 'dart:core', 'String',
-              expectedKind: ReferenceKind.classOrEnum),
-          (EntityRef r) => checkTypeRef(r, 'dart:core', 'int',
-              expectedKind: ReferenceKind.classOrEnum),
-          (EntityRef r) => checkTypeRef(r, 'dart:core', 'String',
-              expectedKind: ReferenceKind.classOrEnum)
-        ]);
-  }
-
-  test_constExpr_parenthesized() {
-    UnlinkedVariable variable = serializeVariableText('const v = (1 + 2) * 3;');
-    assertUnlinkedConst(variable.initializer.bodyExpr, '(1 + 2) * 3',
-        operators: [
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.add,
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.multiply,
-        ],
-        ints: [
-          1,
-          2,
-          3
-        ]);
-  }
-
-  test_constExpr_prefix_complement() {
-    UnlinkedVariable variable = serializeVariableText('const v = ~2;');
-    assertUnlinkedConst(variable.initializer.bodyExpr, '~2', operators: [
-      UnlinkedExprOperation.pushInt,
-      UnlinkedExprOperation.complement
-    ], ints: [
-      2
-    ]);
-  }
-
-  test_constExpr_prefix_negate() {
-    UnlinkedVariable variable = serializeVariableText('const v = -(2);');
-    assertUnlinkedConst(variable.initializer.bodyExpr, '-(2)', operators: [
-      UnlinkedExprOperation.pushInt,
-      UnlinkedExprOperation.negate
-    ], ints: [
-      2
-    ]);
-  }
-
-  test_constExpr_prefix_not() {
-    UnlinkedVariable variable = serializeVariableText('const v = !true;');
-    assertUnlinkedConst(variable.initializer.bodyExpr, '!true',
-        operators: [UnlinkedExprOperation.pushTrue, UnlinkedExprOperation.not]);
-  }
-
-  test_constExpr_pushDouble() {
-    UnlinkedVariable variable = serializeVariableText('const v = 123.4567;');
-    assertUnlinkedConst(variable.initializer.bodyExpr, '123.4567',
-        operators: [UnlinkedExprOperation.pushDouble], doubles: [123.4567]);
-  }
-
-  test_constExpr_pushFalse() {
-    UnlinkedVariable variable = serializeVariableText('const v = false;');
-    assertUnlinkedConst(variable.initializer.bodyExpr, 'false',
-        operators: [UnlinkedExprOperation.pushFalse]);
-  }
-
-  test_constExpr_pushInt() {
-    UnlinkedVariable variable = serializeVariableText('const v = 1;');
-    assertUnlinkedConst(variable.initializer.bodyExpr, '1',
-        operators: [UnlinkedExprOperation.pushInt], ints: [1]);
-  }
-
-  test_constExpr_pushInt_max() {
-    UnlinkedVariable variable = serializeVariableText('const v = 0xFFFFFFFF;');
-    assertUnlinkedConst(variable.initializer.bodyExpr, '0xFFFFFFFF',
-        operators: [
-          UnlinkedExprOperation.pushInt,
-        ],
-        ints: [
-          0xFFFFFFFF
-        ]);
-  }
-
-  test_constExpr_pushInt_negative() {
-    UnlinkedVariable variable = serializeVariableText('const v = -5;');
-    assertUnlinkedConst(variable.initializer.bodyExpr, '-5', operators: [
-      UnlinkedExprOperation.pushInt,
-      UnlinkedExprOperation.negate
-    ], ints: [
-      5
-    ]);
-  }
-
-  test_constExpr_pushLongInt_maxNegative() {
-    UnlinkedVariable variable =
-        serializeVariableText('const v = 0xFFFFFFFFFFFFFFFF;');
-    assertUnlinkedConst(variable.initializer.bodyExpr, '0xFFFFFFFFFFFFFFFF',
-        operators: [
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.negate
-        ],
-        ints: [
-          1
-        ]);
-  }
-
-  test_constExpr_pushLongInt_maxPositive() {
-    UnlinkedVariable variable =
-        serializeVariableText('const v = 0x7FFFFFFFFFFFFFFF;');
-    assertUnlinkedConst(variable.initializer.bodyExpr, '0x7FFFFFFFFFFFFFFF',
-        operators: [UnlinkedExprOperation.pushLongInt],
-        ints: [2, 0x7FFFFFFF, 0xFFFFFFFF]);
-  }
-
-  test_constExpr_pushLongInt_min2() {
-    UnlinkedVariable variable = serializeVariableText('const v = 0x100000000;');
-    assertUnlinkedConst(variable.initializer.bodyExpr, '0x100000000',
-        operators: [
-          UnlinkedExprOperation.pushLongInt
-        ],
-        ints: [
-          2,
-          1,
-          0,
-        ]);
-  }
-
-  test_constExpr_pushLongInt_tooLong() {
-    UnlinkedVariable variable =
-        serializeVariableText('const v = 0x10000000000000000;');
-    assertUnlinkedConst(variable.initializer.bodyExpr, '0x10000000000000000',
-        operators: [UnlinkedExprOperation.pushInt], ints: [0]);
-  }
-
-  test_constExpr_pushNull() {
-    UnlinkedVariable variable = serializeVariableText('const v = null;');
-    assertUnlinkedConst(variable.initializer.bodyExpr, 'null',
-        operators: [UnlinkedExprOperation.pushNull]);
-  }
-
-  test_constExpr_pushReference_class() {
-    UnlinkedVariable variable = serializeVariableText('''
-class C {}
-const v = C;
-''');
-    assertUnlinkedConst(variable.initializer.bodyExpr, 'C', operators: [
-      UnlinkedExprOperation.pushReference
-    ], referenceValidators: [
-      (EntityRef r) =>
-          checkTypeRef(r, null, 'C', expectedKind: ReferenceKind.classOrEnum)
-    ]);
-  }
-
-  test_constExpr_pushReference_enum() {
-    UnlinkedVariable variable = serializeVariableText('''
-enum C {V1, V2, V3}
-const v = C;
-''');
-    assertUnlinkedConst(variable.initializer.bodyExpr, 'C', operators: [
-      UnlinkedExprOperation.pushReference
-    ], referenceValidators: [
-      (EntityRef r) =>
-          checkTypeRef(r, null, 'C', expectedKind: ReferenceKind.classOrEnum)
-    ]);
-  }
-
-  test_constExpr_pushReference_enumValue() {
-    UnlinkedVariable variable = serializeVariableText('''
-enum C {V1, V2, V3}
-const v = C.V1;
-''');
-    assertUnlinkedConst(variable.initializer.bodyExpr, 'C.V1', operators: [
-      UnlinkedExprOperation.pushReference
-    ], referenceValidators: [
-      (EntityRef r) => checkTypeRef(r, null, 'V1',
-              expectedKind: ReferenceKind.propertyAccessor,
-              prefixExpectations: [
-                new _PrefixExpectation(ReferenceKind.classOrEnum, 'C')
-              ])
-    ]);
-  }
-
-  test_constExpr_pushReference_enumValue_viaImport() {
-    addNamedSource('/a.dart', '''
-enum C {V1, V2, V3}
-''');
-    UnlinkedVariable variable = serializeVariableText('''
-import 'a.dart';
-const v = C.V1;
-''');
-    assertUnlinkedConst(variable.initializer.bodyExpr, 'C.V1', operators: [
-      UnlinkedExprOperation.pushReference
-    ], referenceValidators: [
-      (EntityRef r) => checkTypeRef(r, null, 'V1',
-              expectedKind: ReferenceKind.propertyAccessor,
-              prefixExpectations: [
-                new _PrefixExpectation(ReferenceKind.classOrEnum, 'C',
-                    absoluteUri: absUri('/a.dart'))
-              ])
-    ]);
-  }
-
-  test_constExpr_pushReference_enumValues() {
-    UnlinkedVariable variable = serializeVariableText('''
-enum C {V1, V2, V3}
-const v = C.values;
-''');
-    assertUnlinkedConst(variable.initializer.bodyExpr, 'C.values', operators: [
-      UnlinkedExprOperation.pushReference
-    ], referenceValidators: [
-      (EntityRef r) => checkTypeRef(r, null, 'values',
-              expectedKind: ReferenceKind.propertyAccessor,
-              prefixExpectations: [
-                new _PrefixExpectation(ReferenceKind.classOrEnum, 'C')
-              ])
-    ]);
-  }
-
-  test_constExpr_pushReference_enumValues_viaImport() {
-    addNamedSource('/a.dart', '''
-enum C {V1, V2, V3}
-''');
-    UnlinkedVariable variable = serializeVariableText('''
-import 'a.dart';
-const v = C.values;
-''');
-    assertUnlinkedConst(variable.initializer.bodyExpr, 'C.values', operators: [
-      UnlinkedExprOperation.pushReference
-    ], referenceValidators: [
-      (EntityRef r) => checkTypeRef(r, null, 'values',
-              expectedKind: ReferenceKind.propertyAccessor,
-              prefixExpectations: [
-                new _PrefixExpectation(ReferenceKind.classOrEnum, 'C',
-                    absoluteUri: absUri('/a.dart'))
-              ])
-    ]);
-  }
-
-  test_constExpr_pushReference_field() {
-    UnlinkedVariable variable = serializeVariableText('''
-class C {
-  static const int F = 1;
-}
-const v = C.F;
-''');
-    assertUnlinkedConst(variable.initializer.bodyExpr, 'C.F', operators: [
-      UnlinkedExprOperation.pushReference
-    ], referenceValidators: [
-      (EntityRef r) => checkTypeRef(r, null, 'F',
-              expectedKind: ReferenceKind.propertyAccessor,
-              prefixExpectations: [
-                new _PrefixExpectation(ReferenceKind.classOrEnum, 'C')
-              ])
-    ]);
-  }
-
-  test_constExpr_pushReference_field_imported() {
-    addNamedSource('/a.dart', '''
-class C {
-  static const int F = 1;
-}
-''');
-    UnlinkedVariable variable = serializeVariableText('''
-import 'a.dart';
-const v = C.F;
-''');
-    assertUnlinkedConst(variable.initializer.bodyExpr, 'C.F', operators: [
-      UnlinkedExprOperation.pushReference
-    ], referenceValidators: [
-      (EntityRef r) => checkTypeRef(r, null, 'F',
-              expectedKind: ReferenceKind.propertyAccessor,
-              prefixExpectations: [
-                new _PrefixExpectation(ReferenceKind.classOrEnum, 'C',
-                    absoluteUri: absUri('/a.dart'))
-              ])
-    ]);
-  }
-
-  test_constExpr_pushReference_field_imported_withPrefix() {
-    addNamedSource('/a.dart', '''
-class C {
-  static const int F = 1;
-}
-''');
-    UnlinkedVariable variable = serializeVariableText('''
-import 'a.dart' as p;
-const v = p.C.F;
-''');
-    assertUnlinkedConst(variable.initializer.bodyExpr, 'p.C.F', operators: [
-      UnlinkedExprOperation.pushReference
-    ], referenceValidators: [
-      (EntityRef r) => checkTypeRef(r, null, 'F',
-              expectedKind: ReferenceKind.propertyAccessor,
-              prefixExpectations: [
-                new _PrefixExpectation(ReferenceKind.classOrEnum, 'C',
-                    absoluteUri: absUri('/a.dart')),
-                new _PrefixExpectation(ReferenceKind.prefix, 'p'),
-              ])
-    ]);
-  }
-
-  test_constExpr_pushReference_field_simpleIdentifier() {
-    UnlinkedVariable variable = serializeClassText('''
-class C {
-  static const a = b;
-  static const b = null;
-}
-''').fields[0];
-    assertUnlinkedConst(variable.initializer.bodyExpr, 'b', operators: [
-      UnlinkedExprOperation.pushReference
-    ], referenceValidators: [
-      (EntityRef r) => checkTypeRef(r, null, 'b',
-              expectedKind: ReferenceKind.propertyAccessor,
-              prefixExpectations: [
-                new _PrefixExpectation(ReferenceKind.classOrEnum, 'C')
-              ])
-    ]);
-  }
-
-  test_constExpr_pushReference_staticGetter() {
-    UnlinkedVariable variable = serializeVariableText('''
-class C {
-  static int get x => null;
-}
-const v = C.x;
-''');
-    assertUnlinkedConst(variable.initializer.bodyExpr, 'C.x', operators: [
-      UnlinkedExprOperation.pushReference
-    ], referenceValidators: [
-      (EntityRef r) => checkTypeRef(r, null, 'x',
-              expectedKind: ReferenceKind.propertyAccessor,
-              prefixExpectations: [
-                new _PrefixExpectation(ReferenceKind.classOrEnum, 'C')
-              ])
-    ]);
-  }
-
-  test_constExpr_pushReference_staticGetter_imported() {
-    addNamedSource('/a.dart', '''
-class C {
-  static int get x => null;
-}
-''');
-    UnlinkedVariable variable = serializeVariableText('''
-import 'a.dart';
-const v = C.x;
-''');
-    assertUnlinkedConst(variable.initializer.bodyExpr, 'C.x', operators: [
-      UnlinkedExprOperation.pushReference
-    ], referenceValidators: [
-      (EntityRef r) => checkTypeRef(r, null, 'x',
-              expectedKind: ReferenceKind.propertyAccessor,
-              prefixExpectations: [
-                new _PrefixExpectation(ReferenceKind.classOrEnum, 'C',
-                    absoluteUri: absUri('/a.dart'))
-              ])
-    ]);
-  }
-
-  test_constExpr_pushReference_staticGetter_imported_withPrefix() {
-    addNamedSource('/a.dart', '''
-class C {
-  static int get x => null;
-}
-''');
-    UnlinkedVariable variable = serializeVariableText('''
-import 'a.dart' as p;
-const v = p.C.x;
-''');
-    assertUnlinkedConst(variable.initializer.bodyExpr, 'p.C.x', operators: [
-      UnlinkedExprOperation.pushReference
-    ], referenceValidators: [
-      (EntityRef r) => checkTypeRef(r, null, 'x',
-              expectedKind: ReferenceKind.propertyAccessor,
-              prefixExpectations: [
-                new _PrefixExpectation(ReferenceKind.classOrEnum, 'C',
-                    absoluteUri: absUri('/a.dart')),
-                new _PrefixExpectation(ReferenceKind.prefix, 'p')
-              ])
-    ]);
-  }
-
-  test_constExpr_pushReference_staticMethod() {
-    UnlinkedVariable variable = serializeVariableText('''
-class C {
-  static m() {}
-}
-const v = C.m;
-''');
-    assertUnlinkedConst(variable.initializer.bodyExpr, 'C.m', operators: [
-      UnlinkedExprOperation.pushReference
-    ], referenceValidators: [
-      (EntityRef r) => checkTypeRef(r, null, 'm',
-              expectedKind: ReferenceKind.method,
-              prefixExpectations: [
-                new _PrefixExpectation(ReferenceKind.classOrEnum, 'C')
-              ])
-    ]);
-  }
-
-  test_constExpr_pushReference_staticMethod_imported() {
-    addNamedSource('/a.dart', '''
-class C {
-  static m() {}
-}
-''');
-    UnlinkedVariable variable = serializeVariableText('''
-import 'a.dart';
-const v = C.m;
-''');
-    assertUnlinkedConst(variable.initializer.bodyExpr, 'C.m', operators: [
-      UnlinkedExprOperation.pushReference
-    ], referenceValidators: [
-      (EntityRef r) => checkTypeRef(r, null, 'm',
-              expectedKind: ReferenceKind.method,
-              prefixExpectations: [
-                new _PrefixExpectation(ReferenceKind.classOrEnum, 'C',
-                    absoluteUri: absUri('/a.dart'))
-              ])
-    ]);
-  }
-
-  test_constExpr_pushReference_staticMethod_imported_withPrefix() {
-    addNamedSource('/a.dart', '''
-class C {
-  static m() {}
-}
-''');
-    UnlinkedVariable variable = serializeVariableText('''
-import 'a.dart' as p;
-const v = p.C.m;
-''');
-    assertUnlinkedConst(variable.initializer.bodyExpr, 'p.C.m', operators: [
-      UnlinkedExprOperation.pushReference
-    ], referenceValidators: [
-      (EntityRef r) => checkTypeRef(r, null, 'm',
-              expectedKind: ReferenceKind.method,
-              prefixExpectations: [
-                new _PrefixExpectation(ReferenceKind.classOrEnum, 'C',
-                    absoluteUri: absUri('/a.dart')),
-                new _PrefixExpectation(ReferenceKind.prefix, 'p')
-              ])
-    ]);
-  }
-
-  test_constExpr_pushReference_staticMethod_simpleIdentifier() {
-    UnlinkedVariable variable = serializeClassText('''
-class C {
-  static const a = m;
-  static m() {}
-}
-''').fields[0];
-    assertUnlinkedConst(variable.initializer.bodyExpr, 'm', operators: [
-      UnlinkedExprOperation.pushReference
-    ], referenceValidators: [
-      (EntityRef r) => checkTypeRef(r, null, 'm',
-              expectedKind: ReferenceKind.method,
-              prefixExpectations: [
-                new _PrefixExpectation(ReferenceKind.classOrEnum, 'C')
-              ])
-    ]);
-  }
-
-  test_constExpr_pushReference_topLevelFunction() {
-    UnlinkedVariable variable = serializeVariableText('''
-f() {}
-const v = f;
-''');
-    assertUnlinkedConst(variable.initializer.bodyExpr, 'f', operators: [
-      UnlinkedExprOperation.pushReference
-    ], referenceValidators: [
-      (EntityRef r) => checkTypeRef(r, null, 'f',
-          expectedKind: ReferenceKind.topLevelFunction)
-    ]);
-  }
-
-  test_constExpr_pushReference_topLevelFunction_imported() {
-    addNamedSource('/a.dart', '''
-f() {}
-''');
-    UnlinkedVariable variable = serializeVariableText('''
-import 'a.dart';
-const v = f;
-''');
-    assertUnlinkedConst(variable.initializer.bodyExpr, 'f', operators: [
-      UnlinkedExprOperation.pushReference
-    ], referenceValidators: [
-      (EntityRef r) => checkTypeRef(r, absUri('/a.dart'), 'f',
-          expectedKind: ReferenceKind.topLevelFunction)
-    ]);
-  }
-
-  test_constExpr_pushReference_topLevelFunction_imported_withPrefix() {
-    addNamedSource('/a.dart', '''
-f() {}
-''');
-    UnlinkedVariable variable = serializeVariableText('''
-import 'a.dart' as p;
-const v = p.f;
-''');
-    assertUnlinkedConst(variable.initializer.bodyExpr, 'p.f', operators: [
-      UnlinkedExprOperation.pushReference
-    ], referenceValidators: [
-      (EntityRef r) => checkTypeRef(r, absUri('/a.dart'), 'f',
-              expectedKind: ReferenceKind.topLevelFunction,
-              prefixExpectations: [
-                new _PrefixExpectation(ReferenceKind.prefix, 'p')
-              ])
-    ]);
-  }
-
-  test_constExpr_pushReference_topLevelGetter() {
-    UnlinkedVariable variable = serializeVariableText('''
-int get x => null;
-const v = x;
-''');
-    assertUnlinkedConst(variable.initializer.bodyExpr, 'x', operators: [
-      UnlinkedExprOperation.pushReference
-    ], referenceValidators: [
-      (EntityRef r) => checkTypeRef(r, null, 'x',
-          expectedKind: ReferenceKind.topLevelPropertyAccessor)
-    ]);
-  }
-
-  test_constExpr_pushReference_topLevelGetter_imported() {
-    addNamedSource('/a.dart', 'int get x => null;');
-    UnlinkedVariable variable = serializeVariableText('''
-import 'a.dart';
-const v = x;
-''');
-    assertUnlinkedConst(variable.initializer.bodyExpr, 'x', operators: [
-      UnlinkedExprOperation.pushReference
-    ], referenceValidators: [
-      (EntityRef r) => checkTypeRef(r, absUri('/a.dart'), 'x',
-          expectedKind: ReferenceKind.topLevelPropertyAccessor)
-    ]);
-  }
-
-  test_constExpr_pushReference_topLevelGetter_imported_withPrefix() {
-    addNamedSource('/a.dart', 'int get x => null;');
-    UnlinkedVariable variable = serializeVariableText('''
-import 'a.dart' as p;
-const v = p.x;
-''');
-    assertUnlinkedConst(variable.initializer.bodyExpr, 'p.x', operators: [
-      UnlinkedExprOperation.pushReference
-    ], referenceValidators: [
-      (EntityRef r) => checkTypeRef(r, absUri('/a.dart'), 'x',
-          expectedKind: ReferenceKind.topLevelPropertyAccessor,
-          expectedPrefix: 'p')
-    ]);
-  }
-
-  test_constExpr_pushReference_topLevelVariable() {
-    UnlinkedVariable variable = serializeVariableText('''
-const int a = 1;
-const v = a;
-''');
-    assertUnlinkedConst(variable.initializer.bodyExpr, 'a', operators: [
-      UnlinkedExprOperation.pushReference
-    ], referenceValidators: [
-      (EntityRef r) => checkTypeRef(r, null, 'a',
-          expectedKind: ReferenceKind.topLevelPropertyAccessor)
-    ]);
-  }
-
-  test_constExpr_pushReference_topLevelVariable_imported() {
-    addNamedSource('/a.dart', 'const int a = 1;');
-    UnlinkedVariable variable = serializeVariableText('''
-import 'a.dart';
-const v = a;
-''');
-    assertUnlinkedConst(variable.initializer.bodyExpr, 'a', operators: [
-      UnlinkedExprOperation.pushReference
-    ], referenceValidators: [
-      (EntityRef r) => checkTypeRef(r, absUri('/a.dart'), 'a',
-          expectedKind: ReferenceKind.topLevelPropertyAccessor)
-    ]);
-  }
-
-  test_constExpr_pushReference_topLevelVariable_imported_withPrefix() {
-    addNamedSource('/a.dart', 'const int a = 1;');
-    UnlinkedVariable variable = serializeVariableText('''
-import 'a.dart' as p;
-const v = p.a;
-''');
-    assertUnlinkedConst(variable.initializer.bodyExpr, 'p.a', operators: [
-      UnlinkedExprOperation.pushReference
-    ], referenceValidators: [
-      (EntityRef r) {
-        return checkTypeRef(r, absUri('/a.dart'), 'a',
-            expectedKind: ReferenceKind.topLevelPropertyAccessor,
-            expectedPrefix: 'p');
-      }
-    ]);
-  }
-
-  test_constExpr_pushReference_typeParameter() {
-    String text = '''
-class C<T> {
-  static const a = T;
-}
-''';
-    UnlinkedVariable variable =
-        serializeClassText(text, allowErrors: true).fields[0];
-    assertUnlinkedConst(variable.initializer.bodyExpr, 'T', operators: [
-      UnlinkedExprOperation.pushReference
-    ], referenceValidators: [
-      (EntityRef r) {
-        return checkParamTypeRef(r, 1);
-      }
-    ]);
-  }
-
-  test_constExpr_pushReference_unresolved_prefix0() {
-    UnlinkedVariable variable = serializeVariableText('''
-const v = foo;
-''', allowErrors: true);
-    assertUnlinkedConst(variable.initializer.bodyExpr, 'foo', operators: [
-      UnlinkedExprOperation.pushReference
-    ], referenceValidators: [
-      (EntityRef r) =>
-          checkTypeRef(r, null, 'foo', expectedKind: ReferenceKind.unresolved)
-    ]);
-  }
-
-  test_constExpr_pushReference_unresolved_prefix1() {
-    UnlinkedVariable variable = serializeVariableText('''
-class C {}
-const v = C.foo;
-''', allowErrors: true);
-    assertUnlinkedConst(variable.initializer.bodyExpr, 'C.foo', operators: [
-      UnlinkedExprOperation.pushReference
-    ], referenceValidators: [
-      (EntityRef r) => checkTypeRef(r, null, 'foo',
-              expectedKind: ReferenceKind.unresolved,
-              prefixExpectations: [
-                new _PrefixExpectation(ReferenceKind.classOrEnum, 'C')
-              ])
-    ]);
-  }
-
-  test_constExpr_pushReference_unresolved_prefix2() {
-    addNamedSource('/a.dart', '''
-class C {}
-''');
-    UnlinkedVariable variable = serializeVariableText('''
-import 'a.dart' as p;
-const v = p.C.foo;
-''', allowErrors: true);
-    assertUnlinkedConst(variable.initializer.bodyExpr, 'p.C.foo', operators: [
-      UnlinkedExprOperation.pushReference
-    ], referenceValidators: [
-      (EntityRef r) => checkTypeRef(r, null, 'foo',
-              expectedKind: ReferenceKind.unresolved,
-              prefixExpectations: [
-                new _PrefixExpectation(ReferenceKind.classOrEnum, 'C',
-                    absoluteUri: absUri('/a.dart')),
-                new _PrefixExpectation(ReferenceKind.prefix, 'p'),
-              ])
-    ]);
-  }
-
-  test_constExpr_pushString_adjacent() {
-    UnlinkedVariable variable =
-        serializeVariableText('const v = "aaa" "b" "ccc";');
-    assertUnlinkedConst(variable.initializer.bodyExpr, '"aaa" "b" "ccc"',
-        operators: [UnlinkedExprOperation.pushString], strings: ['aaabccc']);
-  }
-
-  test_constExpr_pushString_adjacent_interpolation() {
-    UnlinkedVariable variable =
-        serializeVariableText(r'const v = "aaa" "bb ${42} bbb" "cccc";');
-    assertUnlinkedConst(
-        variable.initializer.bodyExpr, r'"aaa" "bb ${42} bbb" "cccc"',
-        operators: [
-          UnlinkedExprOperation.pushString,
-          UnlinkedExprOperation.pushString,
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.pushString,
-          UnlinkedExprOperation.concatenate,
-          UnlinkedExprOperation.pushString,
-          UnlinkedExprOperation.concatenate,
-        ],
-        ints: [
-          42,
-          3,
-          3,
-        ],
-        strings: [
-          'aaa',
-          'bb ',
-          ' bbb',
-          'cccc'
-        ]);
-  }
-
-  test_constExpr_pushString_interpolation() {
-    UnlinkedVariable variable =
-        serializeVariableText(r'const v = "aaa ${42} bbb";');
-    assertUnlinkedConst(variable.initializer.bodyExpr, r'"aaa ${42} bbb"',
-        operators: [
-          UnlinkedExprOperation.pushString,
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.pushString,
-          UnlinkedExprOperation.concatenate
-        ],
-        ints: [
-          42,
-          3
-        ],
-        strings: [
-          'aaa ',
-          ' bbb'
-        ]);
-  }
-
-  test_constExpr_pushString_simple() {
-    UnlinkedVariable variable = serializeVariableText('const v = "abc";');
-    assertUnlinkedConst(variable.initializer.bodyExpr, '"abc"',
-        operators: [UnlinkedExprOperation.pushString], strings: ['abc']);
-  }
-
-  test_constExpr_pushTrue() {
-    UnlinkedVariable variable = serializeVariableText('const v = true;');
-    assertUnlinkedConst(variable.initializer.bodyExpr, 'true',
-        operators: [UnlinkedExprOperation.pushTrue]);
-  }
-
-  test_constExpr_set_if() {
-    UnlinkedVariable variable =
-        serializeVariableText('const v = <int>{if (true) 1};');
-    assertUnlinkedConst(variable.initializer.bodyExpr, '<int>{if (true) 1}',
-        operators: [
-          UnlinkedExprOperation.pushTrue,
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.ifElement,
-          UnlinkedExprOperation.makeTypedSet
-        ],
-        ints: [
-          1,
-          1
-        ],
-        referenceValidators: [
-          (EntityRef r) => checkTypeRef(r, 'dart:core', 'int',
-              expectedKind: ReferenceKind.classOrEnum)
-        ]);
-  }
-
-  test_constExpr_set_if_else() {
-    UnlinkedVariable variable =
-        serializeVariableText('const v = <int>{if (true) 1 else 2};');
-    assertUnlinkedConst(
-        variable.initializer.bodyExpr, '<int>{if (true) 1 else 2}',
-        operators: [
-          UnlinkedExprOperation.pushTrue,
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.ifElseElement,
-          UnlinkedExprOperation.makeTypedSet
-        ],
-        ints: [
-          1,
-          2,
-          1
-        ],
-        referenceValidators: [
-          (EntityRef r) => checkTypeRef(r, 'dart:core', 'int',
-              expectedKind: ReferenceKind.classOrEnum)
-        ]);
-  }
-
-  test_constExpr_set_spread() {
-    UnlinkedVariable variable =
-        serializeVariableText('const v = <int>{...<int>{}};');
-    assertUnlinkedConst(variable.initializer.bodyExpr, '<int>{...<int>{}}',
-        operators: [
-          UnlinkedExprOperation.makeTypedSet,
-          UnlinkedExprOperation.spreadElement,
-          UnlinkedExprOperation.makeTypedSet
-        ],
-        ints: [
-          0,
-          1
-        ],
-        referenceValidators: [
-          (EntityRef r) => checkTypeRef(r, 'dart:core', 'int',
-              expectedKind: ReferenceKind.classOrEnum),
-          (EntityRef r) => checkTypeRef(r, 'dart:core', 'int',
-              expectedKind: ReferenceKind.classOrEnum)
-        ]);
-  }
-
-  test_constExpr_set_spread_null_aware() {
-    UnlinkedVariable variable =
-        serializeVariableText('const v = <int>{...?<int>{}};');
-    assertUnlinkedConst(variable.initializer.bodyExpr, '<int>{...?<int>{}}',
-        operators: [
-          UnlinkedExprOperation.makeTypedSet,
-          UnlinkedExprOperation.nullAwareSpreadElement,
-          UnlinkedExprOperation.makeTypedSet
-        ],
-        ints: [
-          0,
-          1
-        ],
-        referenceValidators: [
-          (EntityRef r) => checkTypeRef(r, 'dart:core', 'int',
-              expectedKind: ReferenceKind.classOrEnum),
-          (EntityRef r) => checkTypeRef(r, 'dart:core', 'int',
-              expectedKind: ReferenceKind.classOrEnum)
-        ]);
-  }
-
-  test_constExpr_type_arg_nullability_suffix_none() {
-    featureSet = enableNnbd;
-    var variable = serializeVariableText('const v = const <int>[];');
-    assertUnlinkedConst(variable.initializer.bodyExpr, 'const <int>[]',
-        operators: [
-          UnlinkedExprOperation.makeTypedList
-        ],
-        ints: [
-          0
-        ],
-        referenceValidators: [
-          (EntityRef r) => checkTypeRef(r, 'dart:core', 'int',
-              expectedKind: ReferenceKind.classOrEnum,
-              nullabilitySuffix: EntityRefNullabilitySuffix.none)
-        ]);
-  }
-
-  test_constExpr_type_arg_nullability_suffix_question() {
-    featureSet = enableNnbd;
-    var variable = serializeVariableText('const v = const <int?>[];');
-    assertUnlinkedConst(variable.initializer.bodyExpr, 'const <int?>[]',
-        operators: [
-          UnlinkedExprOperation.makeTypedList
-        ],
-        ints: [
-          0
-        ],
-        referenceValidators: [
-          (EntityRef r) => checkTypeRef(r, 'dart:core', 'int',
-              expectedKind: ReferenceKind.classOrEnum,
-              nullabilitySuffix: EntityRefNullabilitySuffix.question)
-        ]);
-  }
-
-  test_constExpr_type_arg_nullability_suffix_star() {
-    featureSet = disableNnbd;
-    var variable = serializeVariableText('const v = const <int>[];');
-    assertUnlinkedConst(variable.initializer.bodyExpr, 'const <int>[]',
-        operators: [
-          UnlinkedExprOperation.makeTypedList
-        ],
-        ints: [
-          0
-        ],
-        referenceValidators: [
-          (EntityRef r) => checkTypeRef(r, 'dart:core', 'int',
-              expectedKind: ReferenceKind.classOrEnum,
-              nullabilitySuffix: EntityRefNullabilitySuffix.starOrIrrelevant)
-        ]);
-  }
-
-  test_constExpr_type_nullability_suffix_none() {
-    featureSet = enableNnbd;
-    var variable = serializeVariableText('const v = int;');
-    assertUnlinkedConst(variable.initializer.bodyExpr, 'int', operators: [
-      UnlinkedExprOperation.pushReference
-    ], referenceValidators: [
-      (EntityRef r) => checkTypeRef(r, 'dart:core', 'int',
-          expectedKind: ReferenceKind.classOrEnum,
-          nullabilitySuffix: EntityRefNullabilitySuffix.none)
-    ]);
-  }
-
-  test_constExpr_type_nullability_suffix_question() {
-    // This is a placeholder for testing that `const v = int?;` is serialized
-    // correctly, if we decide that this syntax is allowed.
-    // TODO(paulberry): fill out this test if necessary.
-    // See https://github.com/dart-lang/language/issues/278
-
-    // var variable = serializeVariableText('const v = int?;', nnbd: true);
-    // assertUnlinkedConst(variable.initializer.bodyExpr, ...);
-  }
-
-  test_constExpr_type_nullability_suffix_star() {
-    featureSet = disableNnbd;
-    var variable = serializeVariableText('const v = int;');
-    assertUnlinkedConst(variable.initializer.bodyExpr, 'int', operators: [
-      UnlinkedExprOperation.pushReference
-    ], referenceValidators: [
-      (EntityRef r) => checkTypeRef(r, 'dart:core', 'int',
-          expectedKind: ReferenceKind.classOrEnum,
-          nullabilitySuffix: EntityRefNullabilitySuffix.starOrIrrelevant)
-    ]);
-  }
-
-  test_constExpr_type_prefixed_nullability_suffix_none() {
-    featureSet = enableNnbd;
-    var variable = serializeVariableText('const v = core.int;',
-        imports: 'import "dart:core" as core;');
-    assertUnlinkedConst(variable.initializer.bodyExpr, 'core.int', operators: [
-      UnlinkedExprOperation.pushReference
-    ], referenceValidators: [
-      (EntityRef r) => checkTypeRef(r, 'dart:core', 'int',
-          expectedKind: ReferenceKind.classOrEnum,
-          prefixExpectations: [
-            _PrefixExpectation(ReferenceKind.prefix, 'core')
-          ],
-          nullabilitySuffix: EntityRefNullabilitySuffix.none)
-    ]);
-  }
-
-  test_constExpr_type_prefixed_nullability_suffix_question() {
-    // This is a placeholder for testing that `const v = core.int?;` is
-    // serialized correctly, if we decide that this syntax is allowed.
-    // TODO(paulberry): fill out this test if necessary.
-    // See https://github.com/dart-lang/language/issues/278
-
-    // var variable = serializeVariableText('const v = core.int?;', imports: 'import "dart:core: as core;', nnbd: true);
-    // assertUnlinkedConst(variable.initializer.bodyExpr, ...);
-  }
-
-  test_constExpr_type_prefixed_nullability_suffix_star() {
-    featureSet = disableNnbd;
-    var variable = serializeVariableText('const v = core.int;',
-        imports: 'import "dart:core" as core;');
-    assertUnlinkedConst(variable.initializer.bodyExpr, 'core.int', operators: [
-      UnlinkedExprOperation.pushReference
-    ], referenceValidators: [
-      (EntityRef r) => checkTypeRef(r, 'dart:core', 'int',
-          expectedKind: ReferenceKind.classOrEnum,
-          prefixExpectations: [
-            _PrefixExpectation(ReferenceKind.prefix, 'core')
-          ],
-          nullabilitySuffix: EntityRefNullabilitySuffix.starOrIrrelevant)
-    ]);
-  }
-
-  test_constructor() {
-    String text = 'class C { C(); }';
-    UnlinkedExecutable executable =
-        findExecutable('', executables: serializeClassText(text).executables);
-    expect(executable.kind, UnlinkedExecutableKind.constructor);
-    expect(executable.returnType, isNull);
-    expect(executable.isAsynchronous, isFalse);
-    expect(executable.isExternal, isFalse);
-    expect(executable.isGenerator, isFalse);
-    expect(executable.nameOffset, text.indexOf('C();'));
-    expect(executable.periodOffset, 0);
-    expect(executable.nameEnd, 0);
-    expect(executable.isRedirectedConstructor, isFalse);
-    expect(executable.redirectedConstructor, isNull);
-    expect(executable.redirectedConstructorName, isEmpty);
-    expect(executable.visibleOffset, 0);
-    expect(executable.visibleLength, 0);
-  }
-
-  test_constructor_anonymous() {
-    UnlinkedExecutable executable = findExecutable('',
-        executables: serializeClassText('class C { C(); }').executables);
-    expect(executable.name, isEmpty);
-  }
-
-  test_constructor_const() {
-    UnlinkedExecutable executable = findExecutable('',
-        executables: serializeClassText('class C { const C(); }').executables);
-    expect(executable.isConst, isTrue);
-    expect(executable.isExternal, isFalse);
-  }
-
-  test_constructor_const_external() {
-    UnlinkedExecutable executable = findExecutable('',
-        executables:
-            serializeClassText('class C { external const C(); }').executables);
-    expect(executable.isConst, isTrue);
-    expect(executable.isExternal, isTrue);
-  }
-
-  test_constructor_documented() {
-    String text = '''
-class C {
-  /**
-   * Docs
-   */
-  C();
-}''';
-    UnlinkedExecutable executable = serializeClassText(text).executables[0];
-    expect(executable.documentationComment, isNotNull);
-    checkDocumentationComment(executable.documentationComment, text);
-  }
-
-  test_constructor_external() {
-    UnlinkedExecutable executable = findExecutable('',
-        executables:
-            serializeClassText('class C { external C(); }').executables);
-    expect(executable.isExternal, isTrue);
-  }
-
-  test_constructor_factory() {
-    UnlinkedExecutable executable = findExecutable('',
-        executables:
-            serializeClassText('class C { factory C() => null; }').executables);
-    expect(executable.isFactory, isTrue);
-  }
-
-  test_constructor_implicit() {
-    // Implicit constructors are not serialized.
-    UnlinkedExecutable executable = findExecutable(null,
-        executables: serializeClassText('class C { C(); }').executables,
-        failIfAbsent: false);
-    expect(executable, isNull);
-  }
-
-  test_constructor_initializers_assertInvocation() {
-    UnlinkedExecutable executable =
-        findExecutable('', executables: serializeClassText(r'''
-class C {
-  const C(int x) : assert(x >= 42);
-}
-''').executables);
-    expect(executable.constantInitializers, hasLength(1));
-    UnlinkedConstructorInitializer initializer =
-        executable.constantInitializers[0];
-    expect(
-        initializer.kind, UnlinkedConstructorInitializerKind.assertInvocation);
-    expect(initializer.name, '');
-    expect(initializer.expression, isNull);
-    expect(initializer.arguments, hasLength(1));
-    assertUnlinkedConst(initializer.arguments[0], 'x >= 42', operators: [
-      UnlinkedExprOperation.pushParameter,
-      UnlinkedExprOperation.pushInt,
-      UnlinkedExprOperation.greaterEqual
-    ], ints: [
-      42
-    ], strings: [
-      'x'
-    ]);
-  }
-
-  test_constructor_initializers_assertInvocation_message() {
-    UnlinkedExecutable executable =
-        findExecutable('', executables: serializeClassText(r'''
-class C {
-  const C(int x) : assert(x >= 42, 'foo');
-}
-''').executables);
-    expect(executable.constantInitializers, hasLength(1));
-    UnlinkedConstructorInitializer initializer =
-        executable.constantInitializers[0];
-    expect(
-        initializer.kind, UnlinkedConstructorInitializerKind.assertInvocation);
-    expect(initializer.name, '');
-    expect(initializer.expression, isNull);
-    expect(initializer.arguments, hasLength(2));
-    assertUnlinkedConst(initializer.arguments[0], 'x >= 42', operators: [
-      UnlinkedExprOperation.pushParameter,
-      UnlinkedExprOperation.pushInt,
-      UnlinkedExprOperation.greaterEqual
-    ], ints: [
-      42
-    ], strings: [
-      'x',
-    ]);
-    assertUnlinkedConst(initializer.arguments[1], "'foo'", operators: [
-      UnlinkedExprOperation.pushString,
-    ], strings: [
-      'foo'
-    ]);
-  }
-
-  test_constructor_initializers_field() {
-    UnlinkedExecutable executable =
-        findExecutable('', executables: serializeClassText(r'''
-class C {
-  final x;
-  const C() : x = 42;
-}
-''').executables);
-    expect(executable.constantInitializers, hasLength(1));
-    UnlinkedConstructorInitializer initializer =
-        executable.constantInitializers[0];
-    expect(initializer.kind, UnlinkedConstructorInitializerKind.field);
-    expect(initializer.name, 'x');
-    assertUnlinkedConst(initializer.expression, '42',
-        operators: [UnlinkedExprOperation.pushInt], ints: [42]);
-    expect(initializer.arguments, isEmpty);
-  }
-
-  test_constructor_initializers_field_withParameter() {
-    UnlinkedExecutable executable =
-        findExecutable('', executables: serializeClassText(r'''
-class C {
-  final x;
-  const C(int p) : x = p;
-}
-''').executables);
-    expect(executable.constantInitializers, hasLength(1));
-    UnlinkedConstructorInitializer initializer =
-        executable.constantInitializers[0];
-    expect(initializer.kind, UnlinkedConstructorInitializerKind.field);
-    expect(initializer.name, 'x');
-    assertUnlinkedConst(initializer.expression, 'p',
-        operators: [UnlinkedExprOperation.pushParameter], strings: ['p']);
-    expect(initializer.arguments, isEmpty);
-  }
-
-  test_constructor_initializers_notConst() {
-    UnlinkedExecutable executable =
-        findExecutable('', executables: serializeClassText(r'''
-class C {
-  final x;
-  C() : x = 42;
-}
-''').executables);
-    expect(executable.constantInitializers, isEmpty);
-  }
-
-  test_constructor_initializers_superInvocation_named() {
-    UnlinkedExecutable executable =
-        findExecutable('', executables: serializeClassText(r'''
-class A {
-  const A.aaa(int p);
-}
-class C extends A {
-  const C() : super.aaa(42);
-}
-''').executables);
-    expect(executable.constantInitializers, hasLength(1));
-    UnlinkedConstructorInitializer initializer =
-        executable.constantInitializers[0];
-    expect(
-        initializer.kind, UnlinkedConstructorInitializerKind.superInvocation);
-    expect(initializer.name, 'aaa');
-    expect(initializer.expression, isNull);
-    expect(initializer.arguments, hasLength(1));
-    assertUnlinkedConst(initializer.arguments[0], '42',
-        operators: [UnlinkedExprOperation.pushInt], ints: [42]);
-  }
-
-  test_constructor_initializers_superInvocation_namedExpression() {
-    UnlinkedExecutable executable =
-        findExecutable('', executables: serializeClassText(r'''
-class A {
-  const A(a, {int b, int c});
-}
-class C extends A {
-  const C() : super(1, b: 2, c: 3);
-}
-''').executables);
-    expect(executable.constantInitializers, hasLength(1));
-    UnlinkedConstructorInitializer initializer =
-        executable.constantInitializers[0];
-    expect(
-        initializer.kind, UnlinkedConstructorInitializerKind.superInvocation);
-    expect(initializer.name, '');
-    expect(initializer.expression, isNull);
-    expect(initializer.arguments, hasLength(3));
-    assertUnlinkedConst(initializer.arguments[0], '1',
-        operators: [UnlinkedExprOperation.pushInt], ints: [1]);
-    assertUnlinkedConst(initializer.arguments[1], '2',
-        operators: [UnlinkedExprOperation.pushInt], ints: [2]);
-    assertUnlinkedConst(initializer.arguments[2], '3',
-        operators: [UnlinkedExprOperation.pushInt], ints: [3]);
-    expect(initializer.argumentNames, ['b', 'c']);
-  }
-
-  test_constructor_initializers_superInvocation_unnamed() {
-    UnlinkedExecutable executable =
-        findExecutable('ccc', executables: serializeClassText(r'''
-class A {
-  const A(int p);
-}
-class C extends A {
-  const C.ccc() : super(42);
-}
-''').executables);
-    expect(executable.constantInitializers, hasLength(1));
-    UnlinkedConstructorInitializer initializer =
-        executable.constantInitializers[0];
-    expect(
-        initializer.kind, UnlinkedConstructorInitializerKind.superInvocation);
-    expect(initializer.name, '');
-    expect(initializer.expression, isNull);
-    expect(initializer.arguments, hasLength(1));
-    assertUnlinkedConst(initializer.arguments[0], '42',
-        operators: [UnlinkedExprOperation.pushInt], ints: [42]);
-  }
-
-  test_constructor_initializers_thisInvocation_named() {
-    UnlinkedExecutable executable =
-        findExecutable('', executables: serializeClassText(r'''
-class C {
-  const C() : this.named(1, 'bbb');
-  const C.named(int a, String b);
-}
-''').executables);
-    expect(executable.constantInitializers, hasLength(1));
-    UnlinkedConstructorInitializer initializer =
-        executable.constantInitializers[0];
-    expect(initializer.kind, UnlinkedConstructorInitializerKind.thisInvocation);
-    expect(initializer.name, 'named');
-    expect(initializer.expression, isNull);
-    expect(initializer.arguments, hasLength(2));
-    assertUnlinkedConst(initializer.arguments[0], '1',
-        operators: [UnlinkedExprOperation.pushInt], ints: [1]);
-    assertUnlinkedConst(initializer.arguments[1], "'bbb'",
-        operators: [UnlinkedExprOperation.pushString], strings: ['bbb']);
-  }
-
-  test_constructor_initializers_thisInvocation_namedExpression() {
-    UnlinkedExecutable executable =
-        findExecutable('', executables: serializeClassText(r'''
-class C {
-  const C() : this.named(1, b: 2, c: 3);
-  const C.named(a, {int b, int c});
-}
-''').executables);
-    expect(executable.constantInitializers, hasLength(1));
-    UnlinkedConstructorInitializer initializer =
-        executable.constantInitializers[0];
-    expect(initializer.kind, UnlinkedConstructorInitializerKind.thisInvocation);
-    expect(initializer.name, 'named');
-    expect(initializer.expression, isNull);
-    expect(initializer.arguments, hasLength(3));
-    assertUnlinkedConst(initializer.arguments[0], '1',
-        operators: [UnlinkedExprOperation.pushInt], ints: [1]);
-    assertUnlinkedConst(initializer.arguments[1], '2',
-        operators: [UnlinkedExprOperation.pushInt], ints: [2]);
-    assertUnlinkedConst(initializer.arguments[2], '3',
-        operators: [UnlinkedExprOperation.pushInt], ints: [3]);
-    expect(initializer.argumentNames, ['b', 'c']);
-  }
-
-  test_constructor_initializers_thisInvocation_unnamed() {
-    UnlinkedExecutable executable =
-        findExecutable('named', executables: serializeClassText(r'''
-class C {
-  const C.named() : this(1, 'bbb');
-  const C(int a, String b);
-}
-''').executables);
-    expect(executable.constantInitializers, hasLength(1));
-    UnlinkedConstructorInitializer initializer =
-        executable.constantInitializers[0];
-    expect(initializer.kind, UnlinkedConstructorInitializerKind.thisInvocation);
-    expect(initializer.name, '');
-    expect(initializer.expression, isNull);
-    expect(initializer.arguments, hasLength(2));
-    assertUnlinkedConst(initializer.arguments[0], '1',
-        operators: [UnlinkedExprOperation.pushInt], ints: [1]);
-    assertUnlinkedConst(initializer.arguments[1], "'bbb'",
-        operators: [UnlinkedExprOperation.pushString], strings: ['bbb']);
-  }
-
-  test_constructor_initializing_formal() {
-    UnlinkedExecutable executable = findExecutable('',
-        executables:
-            serializeClassText('class C { C(this.x); final x; }').executables);
-    UnlinkedParam parameter = executable.parameters[0];
-    expect(parameter.isInitializingFormal, isTrue);
-  }
-
-  test_constructor_initializing_formal_explicit_type() {
-    UnlinkedExecutable executable = findExecutable('',
-        executables: serializeClassText('class C { C(int this.x); final x; }')
-            .executables);
-    UnlinkedParam parameter = executable.parameters[0];
-    checkTypeRef(parameter.type, 'dart:core', 'int');
-  }
-
-  test_constructor_initializing_formal_function_typed() {
-    UnlinkedExecutable executable = findExecutable('',
-        executables: serializeClassText('class C { C(this.x()); final x; }')
-            .executables);
-    UnlinkedParam parameter = executable.parameters[0];
-    expect(parameter.isFunctionTyped, isTrue);
-  }
-
-  test_constructor_initializing_formal_function_typed_explicit_return_type() {
-    UnlinkedExecutable executable = findExecutable('',
-        executables:
-            serializeClassText('class C { C(int this.x()); Function x; }')
-                .executables);
-    UnlinkedParam parameter = executable.parameters[0];
-    checkTypeRef(parameter.type, 'dart:core', 'int');
-  }
-
-  test_constructor_initializing_formal_function_typed_implicit_return_type() {
-    UnlinkedExecutable executable = findExecutable('',
-        executables: serializeClassText('class C { C(this.x()); Function x; }')
-            .executables);
-    UnlinkedParam parameter = executable.parameters[0];
-    expect(parameter.isFunctionTyped, isTrue);
-    expect(parameter.type, isNull);
-  }
-
-  test_constructor_initializing_formal_function_typed_no_parameters() {
-    UnlinkedExecutable executable = findExecutable('',
-        executables: serializeClassText('class C { C(this.x()); final x; }')
-            .executables);
-    UnlinkedParam parameter = executable.parameters[0];
-    expect(parameter.parameters, isEmpty);
-  }
-
-  test_constructor_initializing_formal_function_typed_parameter() {
-    UnlinkedExecutable executable = findExecutable('',
-        executables: serializeClassText('class C { C(this.x(a)); final x; }')
-            .executables);
-    UnlinkedParam parameter = executable.parameters[0];
-    expect(parameter.parameters, hasLength(1));
-  }
-
-  test_constructor_initializing_formal_function_typed_parameter_order() {
-    UnlinkedExecutable executable = findExecutable('',
-        executables: serializeClassText('class C { C(this.x(a, b)); final x; }')
-            .executables);
-    UnlinkedParam parameter = executable.parameters[0];
-    expect(parameter.parameters, hasLength(2));
-    expect(parameter.parameters[0].name, 'a');
-    expect(parameter.parameters[1].name, 'b');
-  }
-
-  test_constructor_initializing_formal_function_typed_withDefault() {
-    UnlinkedExecutable executable =
-        findExecutable('', executables: serializeClassText(r'''
-class C {
-  C([this.x() = foo]);
-  final x;
-}
-int foo() => 0;
-''').executables);
-    UnlinkedParam param = executable.parameters[0];
-    expect(param.isFunctionTyped, isTrue);
-    expect(param.kind, UnlinkedParamKind.optionalPositional);
-    expect(param.defaultValueCode, 'foo');
-    assertUnlinkedConst(param.initializer.bodyExpr, 'foo', operators: [
-      UnlinkedExprOperation.pushReference
-    ], referenceValidators: [
-      (EntityRef r) => checkTypeRef(r, null, 'foo',
-          expectedKind: ReferenceKind.topLevelFunction)
-    ]);
-  }
-
-  test_constructor_initializing_formal_implicit_type() {
-    // Note: the implicit type of an initializing formal is the type of the
-    // field.
-    UnlinkedExecutable executable = findExecutable('',
-        executables:
-            serializeClassText('class C { C(this.x); int x; }').executables);
-    UnlinkedParam parameter = executable.parameters[0];
-    expect(parameter.type, isNull);
-  }
-
-  test_constructor_initializing_formal_name() {
-    UnlinkedExecutable executable = findExecutable('',
-        executables:
-            serializeClassText('class C { C(this.x); final x; }').executables);
-    UnlinkedParam parameter = executable.parameters[0];
-    expect(parameter.name, 'x');
-  }
-
-  test_constructor_initializing_formal_named() {
-    UnlinkedExecutable executable = findExecutable('',
-        executables: serializeClassText('class C { C({this.x}); final x; }')
-            .executables);
-    UnlinkedParam parameter = executable.parameters[0];
-    expect(parameter.kind, UnlinkedParamKind.optionalNamed);
-    expect(parameter.initializer, isNull);
-    expect(parameter.defaultValueCode, isEmpty);
-  }
-
-  test_constructor_initializing_formal_named_withDefault() {
-    UnlinkedExecutable executable = findExecutable('',
-        executables: serializeClassText('class C { C({this.x: 42}); final x; }')
-            .executables);
-    UnlinkedParam parameter = executable.parameters[0];
-    expect(parameter.kind, UnlinkedParamKind.optionalNamed);
-    expect(parameter.initializer, isNotNull);
-    expect(parameter.defaultValueCode, '42');
-    _assertCodeRange(parameter.codeRange, 13, 10);
-    assertUnlinkedConst(parameter.initializer.bodyExpr, '42',
-        operators: [UnlinkedExprOperation.pushInt], ints: [42]);
-  }
-
-  test_constructor_initializing_formal_non_function_typed() {
-    UnlinkedExecutable executable = findExecutable('',
-        executables:
-            serializeClassText('class C { C(this.x); final x; }').executables);
-    UnlinkedParam parameter = executable.parameters[0];
-    expect(parameter.isFunctionTyped, isFalse);
-  }
-
-  test_constructor_initializing_formal_positional() {
-    UnlinkedExecutable executable = findExecutable('',
-        executables: serializeClassText('class C { C([this.x]); final x; }')
-            .executables);
-    UnlinkedParam parameter = executable.parameters[0];
-    expect(parameter.kind, UnlinkedParamKind.optionalPositional);
-    expect(parameter.initializer, isNull);
-    expect(parameter.defaultValueCode, isEmpty);
-  }
-
-  test_constructor_initializing_formal_positional_withDefault() {
-    UnlinkedExecutable executable = findExecutable('',
-        executables:
-            serializeClassText('class C { C([this.x = 42]); final x; }')
-                .executables);
-    UnlinkedParam parameter = executable.parameters[0];
-    expect(parameter.kind, UnlinkedParamKind.optionalPositional);
-    expect(parameter.initializer, isNotNull);
-    expect(parameter.defaultValueCode, '42');
-    _assertCodeRange(parameter.codeRange, 13, 11);
-    assertUnlinkedConst(parameter.initializer.bodyExpr, '42',
-        operators: [UnlinkedExprOperation.pushInt], ints: [42]);
-  }
-
-  test_constructor_initializing_formal_required() {
-    UnlinkedExecutable executable = findExecutable('',
-        executables:
-            serializeClassText('class C { C(this.x); final x; }').executables);
-    UnlinkedParam parameter = executable.parameters[0];
-    expect(parameter.kind, UnlinkedParamKind.requiredPositional);
-  }
-
-  test_constructor_initializing_formal_typedef() {
-    UnlinkedExecutable executable = findExecutable('',
-        executables: serializeClassText(
-                'typedef F<T>(T x); class C<X> { C(this.f); F<X> f; }')
-            .executables);
-    UnlinkedParam parameter = executable.parameters[0];
-    expect(parameter.isFunctionTyped, isFalse);
-    expect(parameter.parameters, isEmpty);
-  }
-
-  test_constructor_initializing_formal_withDefault() {
-    UnlinkedExecutable executable =
-        findExecutable('', executables: serializeClassText(r'''
-class C {
-  C([this.x = 42]);
-  final int x;
-}''').executables);
-    UnlinkedParam param = executable.parameters[0];
-    expect(param.kind, UnlinkedParamKind.optionalPositional);
-    expect(param.defaultValueCode, '42');
-    assertUnlinkedConst(param.initializer.bodyExpr, '42',
-        operators: [UnlinkedExprOperation.pushInt], ints: [42]);
-  }
-
-  test_constructor_named() {
-    String text = 'class C { C.foo(); }';
-    UnlinkedExecutable executable = findExecutable('foo',
-        executables: serializeClassText(text).executables);
-    expect(executable.name, 'foo');
-    expect(executable.nameOffset, text.indexOf('foo'));
-    expect(executable.periodOffset, text.indexOf('.foo'));
-    expect(executable.nameEnd, text.indexOf('()'));
-    _assertCodeRange(executable.codeRange, 10, 8);
-  }
-
-  test_constructor_non_const() {
-    UnlinkedExecutable executable = findExecutable('',
-        executables: serializeClassText('class C { C(); }').executables);
-    expect(executable.isConst, isFalse);
-  }
-
-  test_constructor_non_factory() {
-    UnlinkedExecutable executable = findExecutable('',
-        executables: serializeClassText('class C { C(); }').executables);
-    expect(executable.isFactory, isFalse);
-  }
-
-  test_constructor_param_inferred_type_explicit() {
-    UnlinkedExecutable ctor =
-        serializeClassText('class C { C(int v); }').executables[0];
-    expect(ctor.kind, UnlinkedExecutableKind.constructor);
-    expect(ctor.parameters[0].inferredTypeSlot, 0);
-  }
-
-  test_constructor_param_inferred_type_implicit() {
-    UnlinkedExecutable ctor =
-        serializeClassText('class C { C(v); }').executables[0];
-    expect(ctor.kind, UnlinkedExecutableKind.constructor);
-    expect(ctor.parameters[0].inferredTypeSlot, 0);
-  }
-
-  test_constructor_redirected_factory_named() {
-    String text = '''
-class C {
-  factory C() = D.named;
-  C._();
-}
-class D extends C {
-  D.named() : super._();
-}
-''';
-    UnlinkedExecutable executable =
-        serializeClassText(text, className: 'C').executables[0];
-    expect(executable.isRedirectedConstructor, isTrue);
-    expect(executable.isFactory, isTrue);
-    expect(executable.redirectedConstructorName, isEmpty);
-    checkTypeRef(executable.redirectedConstructor, null, 'named',
-        expectedKind: ReferenceKind.constructor,
-        prefixExpectations: [
-          new _PrefixExpectation(ReferenceKind.classOrEnum, 'D')
-        ]);
-  }
-
-  test_constructor_redirected_factory_named_generic() {
-    String text = '''
-class C<T, U> {
-  factory C() = D<U, T>.named;
-  C._();
-}
-class D<T, U> extends C<U, T> {
-  D.named() : super._();
-}
-''';
-    UnlinkedExecutable executable =
-        serializeClassText(text, className: 'C').executables[0];
-    expect(executable.isRedirectedConstructor, isTrue);
-    expect(executable.isFactory, isTrue);
-    expect(executable.redirectedConstructorName, isEmpty);
-    checkTypeRef(executable.redirectedConstructor, null, 'named',
-        expectedKind: ReferenceKind.constructor,
-        prefixExpectations: [
-          new _PrefixExpectation(ReferenceKind.classOrEnum, 'D',
-              numTypeParameters: 2)
-        ],
-        numTypeArguments: 2);
-    checkParamTypeRef(executable.redirectedConstructor.typeArguments[0], 1);
-    checkParamTypeRef(executable.redirectedConstructor.typeArguments[1], 2);
-  }
-
-  test_constructor_redirected_factory_named_imported() {
-    addNamedSource('/foo.dart', '''
-import 'test.dart';
-class D extends C {
-  D.named() : super._();
-}
-''');
-    String text = '''
-import 'foo.dart';
-class C {
-  factory C() = D.named;
-  C._();
-}
-''';
-    UnlinkedExecutable executable =
-        serializeClassText(text, className: 'C').executables[0];
-    expect(executable.isRedirectedConstructor, isTrue);
-    expect(executable.isFactory, isTrue);
-    expect(executable.redirectedConstructorName, isEmpty);
-    checkTypeRef(executable.redirectedConstructor, null, 'named',
-        expectedKind: ReferenceKind.constructor,
-        prefixExpectations: [
-          new _PrefixExpectation(
-            ReferenceKind.classOrEnum,
-            'D',
-            absoluteUri: absUri('/foo.dart'),
-          )
-        ]);
-  }
-
-  test_constructor_redirected_factory_named_imported_generic() {
-    addNamedSource('/foo.dart', '''
-import 'test.dart';
-class D<T, U> extends C<U, T> {
-  D.named() : super._();
-}
-''');
-    String text = '''
-import 'foo.dart';
-class C<T, U> {
-  factory C() = D<U, T>.named;
-  C._();
-}
-''';
-    UnlinkedExecutable executable =
-        serializeClassText(text, className: 'C').executables[0];
-    expect(executable.isRedirectedConstructor, isTrue);
-    expect(executable.isFactory, isTrue);
-    expect(executable.redirectedConstructorName, isEmpty);
-    checkTypeRef(executable.redirectedConstructor, null, 'named',
-        expectedKind: ReferenceKind.constructor,
-        prefixExpectations: [
-          new _PrefixExpectation(
-            ReferenceKind.classOrEnum,
-            'D',
-            numTypeParameters: 2,
-            absoluteUri: absUri('/foo.dart'),
-          )
-        ],
-        numTypeArguments: 2);
-    checkParamTypeRef(executable.redirectedConstructor.typeArguments[0], 1);
-    checkParamTypeRef(executable.redirectedConstructor.typeArguments[1], 2);
-  }
-
-  test_constructor_redirected_factory_named_prefixed() {
-    addNamedSource('/foo.dart', '''
-import 'test.dart';
-class D extends C {
-  D.named() : super._();
-}
-''');
-    String text = '''
-import 'foo.dart' as foo;
-class C {
-  factory C() = foo.D.named;
-  C._();
-}
-''';
-    UnlinkedExecutable executable =
-        serializeClassText(text, className: 'C').executables[0];
-    expect(executable.isRedirectedConstructor, isTrue);
-    expect(executable.isFactory, isTrue);
-    expect(executable.redirectedConstructorName, isEmpty);
-    checkTypeRef(executable.redirectedConstructor, null, 'named',
-        expectedKind: ReferenceKind.constructor,
-        prefixExpectations: [
-          new _PrefixExpectation(
-            ReferenceKind.classOrEnum,
-            'D',
-            absoluteUri: absUri('/foo.dart'),
-          ),
-          new _PrefixExpectation(ReferenceKind.prefix, 'foo')
-        ]);
-  }
-
-  test_constructor_redirected_factory_named_prefixed_generic() {
-    addNamedSource('/foo.dart', '''
-import 'test.dart';
-class D<T, U> extends C<U, T> {
-  D.named() : super._();
-}
-''');
-    String text = '''
-import 'foo.dart' as foo;
-class C<T, U> {
-  factory C() = foo.D<U, T>.named;
-  C._();
-}
-''';
-    UnlinkedExecutable executable =
-        serializeClassText(text, className: 'C').executables[0];
-    expect(executable.isRedirectedConstructor, isTrue);
-    expect(executable.isFactory, isTrue);
-    expect(executable.redirectedConstructorName, isEmpty);
-    checkTypeRef(executable.redirectedConstructor, null, 'named',
-        expectedKind: ReferenceKind.constructor,
-        prefixExpectations: [
-          new _PrefixExpectation(
-            ReferenceKind.classOrEnum,
-            'D',
-            numTypeParameters: 2,
-            absoluteUri: absUri('/foo.dart'),
-          ),
-          new _PrefixExpectation(ReferenceKind.prefix, 'foo')
-        ],
-        numTypeArguments: 2);
-    checkParamTypeRef(executable.redirectedConstructor.typeArguments[0], 1);
-    checkParamTypeRef(executable.redirectedConstructor.typeArguments[1], 2);
-  }
-
-  test_constructor_redirected_factory_unnamed() {
-    String text = '''
-class C {
-  factory C() = D;
-  C._();
-}
-class D extends C {
-  D() : super._();
-}
-''';
-    UnlinkedExecutable executable =
-        serializeClassText(text, className: 'C').executables[0];
-    expect(executable.isRedirectedConstructor, isTrue);
-    expect(executable.isFactory, isTrue);
-    expect(executable.redirectedConstructorName, isEmpty);
-    checkTypeRef(executable.redirectedConstructor, null, 'D');
-  }
-
-  test_constructor_redirected_factory_unnamed_generic() {
-    String text = '''
-class C<T, U> {
-  factory C() = D<U, T>;
-  C._();
-}
-class D<T, U> extends C<U, T> {
-  D() : super._();
-}
-''';
-    UnlinkedExecutable executable =
-        serializeClassText(text, className: 'C').executables[0];
-    expect(executable.isRedirectedConstructor, isTrue);
-    expect(executable.isFactory, isTrue);
-    expect(executable.redirectedConstructorName, isEmpty);
-    checkTypeRef(executable.redirectedConstructor, null, 'D',
-        numTypeParameters: 2, numTypeArguments: 2);
-    checkParamTypeRef(executable.redirectedConstructor.typeArguments[0], 1);
-    checkParamTypeRef(executable.redirectedConstructor.typeArguments[1], 2);
-  }
-
-  test_constructor_redirected_factory_unnamed_imported() {
-    addNamedSource('/foo.dart', '''
-import 'test.dart';
-class D extends C {
-  D() : super._();
-}
-''');
-    String text = '''
-import 'foo.dart';
-class C {
-  factory C() = D;
-  C._();
-}
-''';
-    UnlinkedExecutable executable =
-        serializeClassText(text, className: 'C').executables[0];
-    expect(executable.isRedirectedConstructor, isTrue);
-    expect(executable.isFactory, isTrue);
-    expect(executable.redirectedConstructorName, isEmpty);
-    checkTypeRef(executable.redirectedConstructor, absUri('/foo.dart'), 'D');
-  }
-
-  test_constructor_redirected_factory_unnamed_imported_generic() {
-    addNamedSource('/foo.dart', '''
-import 'test.dart';
-class D<T, U> extends C<U, T> {
-  D() : super._();
-}
-''');
-    String text = '''
-import 'foo.dart';
-class C<T, U> {
-  factory C() = D<U, T>;
-  C._();
-}
-''';
-    UnlinkedExecutable executable =
-        serializeClassText(text, className: 'C').executables[0];
-    expect(executable.isRedirectedConstructor, isTrue);
-    expect(executable.isFactory, isTrue);
-    expect(executable.redirectedConstructorName, isEmpty);
-    checkTypeRef(executable.redirectedConstructor, absUri('/foo.dart'), 'D',
-        numTypeParameters: 2, numTypeArguments: 2);
-    checkParamTypeRef(executable.redirectedConstructor.typeArguments[0], 1);
-    checkParamTypeRef(executable.redirectedConstructor.typeArguments[1], 2);
-  }
-
-  test_constructor_redirected_factory_unnamed_prefixed() {
-    addNamedSource('/foo.dart', '''
-import 'test.dart';
-class D extends C {
-  D() : super._();
-}
-''');
-    String text = '''
-import 'foo.dart' as foo;
-class C {
-  factory C() = foo.D;
-  C._();
-}
-''';
-    UnlinkedExecutable executable =
-        serializeClassText(text, className: 'C').executables[0];
-    expect(executable.isRedirectedConstructor, isTrue);
-    expect(executable.isFactory, isTrue);
-    expect(executable.redirectedConstructorName, isEmpty);
-    checkTypeRef(executable.redirectedConstructor, absUri('/foo.dart'), 'D',
-        expectedPrefix: 'foo');
-  }
-
-  test_constructor_redirected_factory_unnamed_prefixed_generic() {
-    addNamedSource('/foo.dart', '''
-import 'test.dart';
-class D<T, U> extends C<U, T> {
-  D() : super._();
-}
-''');
-    String text = '''
-import 'foo.dart' as foo;
-class C<T, U> {
-  factory C() = foo.D<U, T>;
-  C._();
-}
-''';
-    UnlinkedExecutable executable =
-        serializeClassText(text, className: 'C').executables[0];
-    expect(executable.isRedirectedConstructor, isTrue);
-    expect(executable.isFactory, isTrue);
-    expect(executable.redirectedConstructorName, isEmpty);
-    checkTypeRef(executable.redirectedConstructor, absUri('/foo.dart'), 'D',
-        numTypeParameters: 2, expectedPrefix: 'foo', numTypeArguments: 2);
-    checkParamTypeRef(executable.redirectedConstructor.typeArguments[0], 1);
-    checkParamTypeRef(executable.redirectedConstructor.typeArguments[1], 2);
-  }
-
-  test_constructor_redirected_thisInvocation_named() {
-    String text = '''
-class C {
-  C() : this.named();
-  C.named();
-}
-''';
-    UnlinkedExecutable executable =
-        serializeClassText(text, className: 'C').executables[0];
-    expect(executable.isRedirectedConstructor, isTrue);
-    expect(executable.isFactory, isFalse);
-    expect(executable.redirectedConstructorName, 'named');
-    expect(executable.redirectedConstructor, isNull);
-  }
-
-  test_constructor_redirected_thisInvocation_unnamed() {
-    String text = '''
-class C {
-  C.named() : this();
-  C();
-}
-''';
-    UnlinkedExecutable executable =
-        serializeClassText(text, className: 'C').executables[0];
-    expect(executable.isRedirectedConstructor, isTrue);
-    expect(executable.isFactory, isFalse);
-    expect(executable.redirectedConstructorName, isEmpty);
-    expect(executable.redirectedConstructor, isNull);
-  }
-
-  test_constructor_return_type() {
-    UnlinkedExecutable executable = findExecutable('',
-        executables: serializeClassText('class C { C(); }').executables);
-    expect(executable.returnType, isNull);
-  }
-
-  test_constructor_return_type_parameterized() {
-    UnlinkedExecutable executable = findExecutable('',
-        executables: serializeClassText('class C<T, U> { C(); }').executables);
-    expect(executable.returnType, isNull);
-  }
-
-  test_constructor_withCycles_const() {
-    serializeLibraryText('''
-class C {
-  final x;
-  const C() : x = const D();
-}
-class D {
-  final x;
-  const D() : x = const C();
-}
-class E {
-  final x;
-  const E() : x = null;
-}
-''');
-    checkConstCycle('C');
-    checkConstCycle('D');
-    checkConstCycle('E', hasCycle: false);
-  }
-
-  test_constructor_withCycles_nonConst() {
-    serializeLibraryText('''
-class C {
-  final x;
-  C() : x = new D();
-}
-class D {
-  final x;
-  D() : x = new C();
-}
-''');
-    expect(findClass('C').executables[0].constCycleSlot, 0);
-    expect(findClass('D').executables[0].constCycleSlot, 0);
-  }
-
-  test_constructorCycle_redirectToImplicitConstructor() {
-    serializeLibraryText('''
-class C {
-  const factory C() = D;
-}
-class D extends C {}
-''', allowErrors: true);
-    checkConstCycle('C', hasCycle: false);
-  }
-
-  test_constructorCycle_redirectToNonConstConstructor() {
-    // It's not valid Dart but we need to make sure it doesn't crash
-    // summary generation.
-    serializeLibraryText('''
-class C {
-  const factory C() = D;
-}
-class D extends C {
-  D();
-}
-''', allowErrors: true);
-    checkConstCycle('C', hasCycle: false);
-  }
-
-  test_constructorCycle_redirectToSymbolConstructor() {
-    // The symbol constructor has some special case behaviors in analyzer.
-    // Make sure those special case behaviors don't cause problems.
-    serializeLibraryText('''
-class C {
-  const factory C(String name) = Symbol;
-}
-''', allowErrors: true);
-    checkConstCycle('C', hasCycle: false);
-  }
-
-  test_constructorCycle_referenceToClass() {
-    serializeLibraryText('''
-class C {
-  final x;
-  const C() : x = C;
-}
-''');
-    checkConstCycle('C', hasCycle: false);
-  }
-
-  test_constructorCycle_referenceToEnum() {
-    serializeLibraryText('''
-enum E { v }
-class C {
-  final x;
-  const C() : x = E;
-}
-''');
-    checkConstCycle('C', hasCycle: false);
-  }
-
-  test_constructorCycle_referenceToEnumValue() {
-    serializeLibraryText('''
-enum E { v }
-class C {
-  final x;
-  const C() : x = E.v;
-}
-''');
-    checkConstCycle('C', hasCycle: false);
-  }
-
-  test_constructorCycle_referenceToEnumValues() {
-    serializeLibraryText('''
-enum E { v }
-class C {
-  final x;
-  const C() : x = E.values;
-}
-''');
-    checkConstCycle('C', hasCycle: false);
-  }
-
-  test_constructorCycle_referenceToGenericParameter() {
-    // It's not valid Dart but we need to make sure it doesn't crash
-    // summary generation.
-    serializeLibraryText('''
-class C<T> {
-  final x;
-  const C() : x = T;
-}
-''', allowErrors: true);
-    checkConstCycle('C', hasCycle: false);
-  }
-
-  test_constructorCycle_referenceToGenericParameter_asSupertype() {
-    // It's not valid Dart but we need to make sure it doesn't crash
-    // summary generation.
-    serializeLibraryText('''
-class C<T> extends T {
-  const C();
-}
-''', allowErrors: true);
-    checkConstCycle('C', hasCycle: false);
-  }
-
-  test_constructorCycle_referenceToStaticMethod_inOtherClass() {
-    serializeLibraryText('''
-class C {
-  final x;
-  const C() : x = D.f;
-}
-class D {
-  static void f() {}
-}
-''');
-    checkConstCycle('C', hasCycle: false);
-  }
-
-  test_constructorCycle_referenceToStaticMethod_inSameClass() {
-    serializeLibraryText('''
-class C {
-  final x;
-  static void f() {}
-  const C() : x = f;
-}
-''');
-    checkConstCycle('C', hasCycle: false);
-  }
-
-  test_constructorCycle_referenceToTopLevelFunction() {
-    serializeLibraryText('''
-void f() {}
-class C {
-  final x;
-  const C() : x = f;
-}
-''');
-    checkConstCycle('C', hasCycle: false);
-  }
-
-  test_constructorCycle_referenceToTypedef() {
-    serializeLibraryText('''
-typedef F();
-class C {
-  final x;
-  const C() : x = F;
-}
-''');
-    checkConstCycle('C', hasCycle: false);
-  }
-
-  test_constructorCycle_referenceToUndefinedName() {
-    // It's not valid Dart but we need to make sure it doesn't crash
-    // summary generation.
-    serializeLibraryText('''
-class C {
-  final x;
-  const C() : x = foo;
-}
-''', allowErrors: true);
-    checkConstCycle('C', hasCycle: false);
-  }
-
-  test_constructorCycle_referenceToUndefinedName_viaPrefix() {
-    // It's not valid Dart but we need to make sure it doesn't crash
-    // summary generation.
-    addNamedSource('/a.dart', '');
-    serializeLibraryText('''
-import 'a.dart' as a;
-class C {
-  final x;
-  const C() : x = a.foo;
-}
-''', allowErrors: true);
-    checkConstCycle('C', hasCycle: false);
-  }
-
-  test_constructorCycle_referenceToUndefinedName_viaPrefix_nonExistentFile() {
-    // It's not valid Dart but we need to make sure it doesn't crash
-    // summary generation.
-    allowMissingFiles = true;
-    serializeLibraryText('''
-import 'a.dart' as a;
-class C {
-  final x;
-  const C() : x = a.foo;
-}
-''', allowErrors: true);
-    checkConstCycle('C', hasCycle: false);
-  }
-
-  test_constructorCycle_trivial() {
-    serializeLibraryText('''
-class C {
-  const C() : this();
-}
-''', allowErrors: true);
-    checkConstCycle('C');
-  }
-
-  test_constructorCycle_viaFactoryRedirect() {
-    serializeLibraryText('''
-class C {
-  const C();
-  const factory C.named() = D;
-}
-class D extends C {
-  final x;
-  const D() : x = y;
-}
-const y = const C.named();
-''', allowErrors: true);
-    checkConstCycle('C', hasCycle: false);
-    checkConstCycle('C', name: 'named');
-    checkConstCycle('D');
-  }
-
-  test_constructorCycle_viaFinalField() {
-    serializeLibraryText('''
-class C {
-  final x = const C();
-  const C();
-}
-''', allowErrors: true);
-    checkConstCycle('C');
-  }
-
-  test_constructorCycle_viaLength() {
-    // It's not valid Dart but we need to make sure it doesn't crash
-    // summary generation.
-    serializeLibraryText('''
-class C {
-  final x;
-  const C() : x = y.length;
-}
-const y = const C();
-''', allowErrors: true);
-    checkConstCycle('C');
-  }
-
-  test_constructorCycle_viaNamedConstructor() {
-    serializeLibraryText('''
-class C {
-  final x;
-  const C() : x = const D.named();
-}
-class D {
-  final x;
-  const D.named() : x = const C();
-}
-''');
-    checkConstCycle('C');
-    checkConstCycle('D', name: 'named');
-  }
-
-  test_constructorCycle_viaOrdinaryRedirect() {
-    serializeLibraryText('''
-class C {
-  final x;
-  const C() : this.named();
-  const C.named() : x = const C();
-}
-''');
-    checkConstCycle('C');
-    checkConstCycle('C', name: 'named');
-  }
-
-  test_constructorCycle_viaOrdinaryRedirect_suppressSupertype() {
-    // Since C redirects to C.named, it doesn't implicitly refer to B's unnamed
-    // constructor.  Therefore there is no cycle.
-    serializeLibraryText('''
-class B {
-  final x;
-  const B() : x = const C();
-  const B.named() : x = null;
-}
-class C extends B {
-  const C() : this.named();
-  const C.named() : super.named();
-}
-''');
-    checkConstCycle('B', hasCycle: false);
-    checkConstCycle('B', name: 'named', hasCycle: false);
-    checkConstCycle('C', hasCycle: false);
-    checkConstCycle('C', name: 'named', hasCycle: false);
-  }
-
-  test_constructorCycle_viaRedirectArgument() {
-    serializeLibraryText('''
-class C {
-  final x;
-  const C() : this.named(y);
-  const C.named(this.x);
-}
-const y = const C();
-''', allowErrors: true);
-    checkConstCycle('C');
-    checkConstCycle('C', name: 'named', hasCycle: false);
-  }
-
-  test_constructorCycle_viaStaticField_inOtherClass() {
-    serializeLibraryText('''
-class C {
-  final x;
-  const C() : x = D.y;
-}
-class D {
-  static const y = const C();
-}
-''', allowErrors: true);
-    checkConstCycle('C');
-  }
-
-  test_constructorCycle_viaStaticField_inSameClass() {
-    serializeLibraryText('''
-class C {
-  final x;
-  static const y = const C();
-  const C() : x = y;
-}
-''', allowErrors: true);
-    checkConstCycle('C');
-  }
-
-  test_constructorCycle_viaSuperArgument() {
-    serializeLibraryText('''
-class B {
-  final x;
-  const B(this.x);
-}
-class C extends B {
-  const C() : super(y);
-}
-const y = const C();
-''', allowErrors: true);
-    checkConstCycle('B', hasCycle: false);
-    checkConstCycle('C');
-  }
-
-  test_constructorCycle_viaSupertype() {
-    serializeLibraryText('''
-class C {
-  final x;
-  const C() : x = const D();
-}
-class D extends C {
-  const D();
-}
-''');
-    checkConstCycle('C');
-    checkConstCycle('D');
-  }
-
-  test_constructorCycle_viaSupertype_Enum() {
-    // It's not valid Dart but we need to make sure it doesn't crash
-    // summary generation.
-    serializeLibraryText('''
-enum E { v }
-class C extends E {
-  const C();
-}
-''', allowErrors: true);
-    checkConstCycle('C', hasCycle: false);
-  }
-
-  test_constructorCycle_viaSupertype_explicit() {
-    serializeLibraryText('''
-class C {
-  final x;
-  const C() : x = const D();
-  const C.named() : x = const D.named();
-}
-class D extends C {
-  const D() : super();
-  const D.named() : super.named();
-}
-''');
-    checkConstCycle('C');
-    checkConstCycle('C', name: 'named');
-    checkConstCycle('D');
-    checkConstCycle('D', name: 'named');
-  }
-
-  test_constructorCycle_viaSupertype_explicit_undefined() {
-    // It's not valid Dart but we need to make sure it doesn't crash
-    // summary generation.
-    serializeLibraryText('''
-class C {
-  final x;
-  const C() : x = const D();
-}
-class D extends C {
-  const D() : super.named();
-}
-''', allowErrors: true);
-    checkConstCycle('C', hasCycle: false);
-    checkConstCycle('D', hasCycle: false);
-  }
-
-  test_constructorCycle_viaSupertype_withDefaultTypeArgument() {
-    serializeLibraryText('''
-class C<T> {
-  final x;
-  const C() : x = const D();
-}
-class D extends C {
-  const D();
-}
-''');
-    checkConstCycle('C');
-    checkConstCycle('D');
-  }
-
-  test_constructorCycle_viaSupertype_withTypeArgument() {
-    serializeLibraryText('''
-class C<T> {
-  final x;
-  const C() : x = const D();
-}
-class D extends C<int> {
-  const D();
-}
-''');
-    checkConstCycle('C');
-    checkConstCycle('D');
-  }
-
-  test_constructorCycle_viaTopLevelVariable() {
-    serializeLibraryText('''
-class C {
-  final x;
-  const C() : x = y;
-}
-const y = const C();
-''', allowErrors: true);
-    checkConstCycle('C');
-  }
-
-  test_constructorCycle_viaTopLevelVariable_imported() {
-    addNamedSource('/a.dart', '''
-import 'test.dart';
-const y = const C();
-    ''');
-    serializeLibraryText('''
-import 'a.dart';
-class C {
-  final x;
-  const C() : x = y;
-}
-''', allowErrors: true);
-    checkConstCycle('C');
-  }
-
-  test_constructorCycle_viaTopLevelVariable_importedViaPrefix() {
-    addNamedSource('/a.dart', '''
-import 'test.dart';
-const y = const C();
-    ''');
-    serializeLibraryText('''
-import 'a.dart' as a;
-class C {
-  final x;
-  const C() : x = a.y;
-}
-''', allowErrors: true);
-    checkConstCycle('C');
-  }
-
-  test_dependencies_export_to_export_unused() {
-    addNamedSource('/a.dart', 'export "b.dart";');
-    addNamedSource('/b.dart', '');
-    serializeLibraryText('export "a.dart";');
-    // The main test library depends on b.dart, even though it doesn't
-    // re-export any names defined in b.dart, because a change to b.dart might
-    // cause it to start exporting a name that the main test library *does*
-    // use.
-    checkHasDependency(absUri('/b.dart'));
-  }
-
-  test_dependencies_export_unused() {
-    addNamedSource('/a.dart', '');
-    serializeLibraryText('export "a.dart";');
-    // The main test library depends on a.dart, even though it doesn't
-    // re-export any names defined in a.dart, because a change to a.dart might
-    // cause it to start exporting a name that the main test library *will*
-    // re-export.
-    checkHasDependency(absUri('/a.dart'));
-  }
-
-  test_dependencies_import_to_export() {
-    addNamedSource('/a.dart', 'library a; export "b.dart"; class A {}');
-    addNamedSource('/b.dart', 'library b;');
-    serializeLibraryText('import "a.dart"; A a;');
-    checkHasDependency(absUri('/a.dart'));
-    // The main test library depends on b.dart, because names defined in
-    // b.dart are exported by a.dart.
-    checkHasDependency(absUri('/b.dart'));
-  }
-
-  test_dependencies_import_to_export_in_subdirs_absolute_export() {
-    addNamedSource('/a/a.dart',
-        'library a; export "${absUri('/a/b/b.dart')}"; class A {}');
-    addNamedSource('/a/b/b.dart', 'library b;');
-    serializeLibraryText('import "a/a.dart"; A a;');
-    checkHasDependency(absUri('/a/a.dart'));
-    // The main test library depends on b.dart, because names defined in
-    // b.dart are exported by a.dart.
-    checkHasDependency(absUri('/a/b/b.dart'));
-  }
-
-  test_dependencies_import_to_export_in_subdirs_absolute_import() {
-    addNamedSource('/a/a.dart', 'library a; export "b/b.dart"; class A {}');
-    addNamedSource('/a/b/b.dart', 'library b;');
-    serializeLibraryText('import "${absUri('/a/a.dart')}"; A a;');
-    checkHasDependency(absUri('/a/a.dart'));
-    // The main test library depends on b.dart, because names defined in
-    // b.dart are exported by a.dart.
-    checkHasDependency(absUri('/a/b/b.dart'));
-  }
-
-  test_dependencies_import_to_export_in_subdirs_relative() {
-    addNamedSource('/a/a.dart', 'library a; export "b/b.dart"; class A {}');
-    addNamedSource('/a/b/b.dart', 'library b;');
-    serializeLibraryText('import "a/a.dart"; A a;');
-    checkHasDependency(absUri('/a/a.dart'));
-    // The main test library depends on b.dart, because names defined in
-    // b.dart are exported by a.dart.
-    checkHasDependency(absUri('/a/b/b.dart'));
-  }
-
-  test_dependencies_import_to_export_loop() {
-    addNamedSource('/a.dart', 'library a; export "b.dart"; class A {}');
-    addNamedSource('/b.dart', 'library b; export "a.dart";');
-    serializeLibraryText('import "a.dart"; A a;');
-    checkHasDependency(absUri('/a.dart'));
-    // Serialization should have been able to walk the transitive export
-    // dependencies to b.dart without going into an infinite loop.
-    checkHasDependency(absUri('/b.dart'));
-  }
-
-  test_dependencies_import_to_export_transitive_closure() {
-    addNamedSource('/a.dart', 'library a; export "b.dart"; class A {}');
-    addNamedSource('/b.dart', 'library b; export "c.dart";');
-    addNamedSource('/c.dart', 'library c;');
-    serializeLibraryText('import "a.dart"; A a;');
-    checkHasDependency(absUri('/a.dart'));
-    // The main test library depends on c.dart, because names defined in
-    // c.dart are exported by b.dart and then re-exported by a.dart.
-    checkHasDependency(absUri('/c.dart'));
-  }
-
-  test_dependencies_import_to_export_unused() {
-    addNamedSource('/a.dart', 'export "b.dart";');
-    addNamedSource('/b.dart', '');
-    serializeLibraryText('import "a.dart";', allowErrors: true);
-    // The main test library depends on b.dart, even though it doesn't use any
-    // names defined in b.dart, because a change to b.dart might cause it to
-    // start exporting a name that the main test library *does* use.
-    checkHasDependency(absUri('/b.dart'));
-  }
-
-  test_dependencies_import_transitive_closure() {
-    addNamedSource(
-        '/a.dart', 'library a; import "b.dart"; class A extends B {}');
-    addNamedSource('/b.dart', 'library b; class B {}');
-    serializeLibraryText('import "a.dart"; A a;');
-    checkHasDependency(absUri('/a.dart'));
-    // The main test library doesn't depend on b.dart, because no change to
-    // b.dart can possibly affect the serialized element model for it.
-    checkLacksDependency(absUri('/b.dart'));
-  }
-
-  test_dependencies_import_unused() {
-    addNamedSource('/a.dart', '');
-    serializeLibraryText('import "a.dart";', allowErrors: true);
-    // The main test library depends on a.dart, even though it doesn't use any
-    // names defined in a.dart, because a change to a.dart might cause it to
-    // start exporting a name that the main test library *does* use.
-    checkHasDependency(absUri('/a.dart'));
-  }
-
-  test_dependencies_parts() {
-    addNamedSource(
-        '/a.dart', 'library a; part "b.dart"; part "c.dart"; class A {}');
-    addNamedSource('/b.dart', 'part of a;');
-    addNamedSource('/c.dart', 'part of a;');
-    serializeLibraryText('import "a.dart"; A a;');
-    int dep = checkHasDependency(absUri('/a.dart'));
-    checkDependencyParts(
-        linked.dependencies[dep], [absUri('/b.dart'), absUri('/c.dart')]);
-  }
-
-  test_dependencies_parts_relative_to_importing_library() {
-    addNamedSource('/a/b.dart', 'export "c/d.dart";');
-    addNamedSource('/a/c/d.dart',
-        'library d; part "e/f.dart"; part "g/h.dart"; class D {}');
-    addNamedSource('/a/c/e/f.dart', 'part of d;');
-    addNamedSource('/a/c/g/h.dart', 'part of d;');
-    serializeLibraryText('import "a/b.dart"; D d;');
-    int dep = checkHasDependency(absUri('/a/c/d.dart'));
-    checkDependencyParts(linked.dependencies[dep],
-        [absUri('/a/c/e/f.dart'), absUri('/a/c/g/h.dart')]);
-  }
-
-  test_elements_in_part() {
-    addNamedSource('/part1.dart', '''
-part of my.lib;
-
-class C {}
-enum E { v }
-var v;
-f() {}
-typedef F();
-''');
-    serializeLibraryText('library my.lib; part "part1.dart";');
-    UnlinkedUnit unit = unlinkedUnits[1];
-    expect(findClass('C', unit: unit), isNotNull);
-    expect(findEnum('E', unit: unit), isNotNull);
-    expect(findVariable('v', variables: unit.variables), isNotNull);
-    expect(findExecutable('f', executables: unit.executables), isNotNull);
-    expect(findTypedef('F', unit: unit), isNotNull);
-  }
-
-  test_enum() {
-    String text = 'enum E { v1 }';
-    UnlinkedEnum e = serializeEnumText(text);
-    expect(e.name, 'E');
-    expect(e.nameOffset, text.indexOf('E'));
-    expect(e.values, hasLength(1));
-    expect(e.values[0].name, 'v1');
-    expect(e.values[0].nameOffset, text.indexOf('v1'));
-    _assertCodeRange(e.codeRange, 0, 13);
-    expect(unlinkedUnits[0].publicNamespace.names, hasLength(1));
-    expect(unlinkedUnits[0].publicNamespace.names[0].kind,
-        ReferenceKind.classOrEnum);
-    expect(unlinkedUnits[0].publicNamespace.names[0].name, 'E');
-    expect(unlinkedUnits[0].publicNamespace.names[0].numTypeParameters, 0);
-    expect(unlinkedUnits[0].publicNamespace.names[0].members, hasLength(2));
-    expect(unlinkedUnits[0].publicNamespace.names[0].members[0].kind,
-        ReferenceKind.propertyAccessor);
-    expect(unlinkedUnits[0].publicNamespace.names[0].members[0].name, 'values');
-    expect(
-        unlinkedUnits[0].publicNamespace.names[0].members[0].numTypeParameters,
-        0);
-    expect(unlinkedUnits[0].publicNamespace.names[0].members[1].kind,
-        ReferenceKind.propertyAccessor);
-    expect(unlinkedUnits[0].publicNamespace.names[0].members[1].name, 'v1');
-    expect(
-        unlinkedUnits[0].publicNamespace.names[0].members[1].numTypeParameters,
-        0);
-  }
-
-  test_enum_documented() {
-    String text = '''
-// Extra comment so doc comment offset != 0
-/**
- * Docs
- */
-enum E { v }''';
-    UnlinkedEnum enm = serializeEnumText(text);
-    expect(enm.documentationComment, isNotNull);
-    checkDocumentationComment(enm.documentationComment, text);
-  }
-
-  test_enum_order() {
-    UnlinkedEnum e = serializeEnumText('enum E { v1, v2 }');
-    expect(e.values, hasLength(2));
-    expect(e.values[0].name, 'v1');
-    expect(e.values[1].name, 'v2');
-  }
-
-  test_enum_private() {
-    serializeEnumText('enum _E { v1 }', '_E');
-    expect(unlinkedUnits[0].publicNamespace.names, isEmpty);
-  }
-
-  test_enum_value_documented() {
-    String text = '''
-enum E {
-  /**
-   * Docs
-   */
-  v
-}''';
-    UnlinkedEnumValue value = serializeEnumText(text).values[0];
-    expect(value.documentationComment, isNotNull);
-    checkDocumentationComment(value.documentationComment, text);
-  }
-
-  test_enum_value_private() {
-    serializeEnumText('enum E { _v }', 'E');
-    expect(unlinkedUnits[0].publicNamespace.names, hasLength(1));
-    expect(unlinkedUnits[0].publicNamespace.names[0].members, hasLength(1));
-    expect(unlinkedUnits[0].publicNamespace.names[0].members[0].name, 'values');
-  }
-
-  test_executable_abstract() {
-    UnlinkedExecutable executable =
-        serializeClassText('abstract class C { f(); }').executables[0];
-    expect(executable.isAbstract, isTrue);
-  }
-
-  test_executable_concrete() {
-    UnlinkedExecutable executable =
-        serializeClassText('abstract class C { f() {} }').executables[0];
-    expect(executable.isAbstract, isFalse);
-  }
-
-  test_executable_function() {
-    String text = '  f() {}';
-    UnlinkedExecutable executable = serializeExecutableText(text);
-    expect(executable.kind, UnlinkedExecutableKind.functionOrMethod);
-    expect(executable.returnType, isNull);
-    expect(executable.isAsynchronous, isFalse);
-    expect(executable.isExternal, isFalse);
-    expect(executable.isGenerator, isFalse);
-    expect(executable.nameOffset, text.indexOf('f'));
-    expect(executable.visibleOffset, 0);
-    expect(executable.visibleLength, 0);
-    expect(unlinkedUnits[0].publicNamespace.names, hasLength(1));
-    expect(unlinkedUnits[0].publicNamespace.names[0].kind,
-        ReferenceKind.topLevelFunction);
-    expect(unlinkedUnits[0].publicNamespace.names[0].name, 'f');
-    expect(unlinkedUnits[0].publicNamespace.names[0].numTypeParameters, 0);
-  }
-
-  test_executable_function_async() {
-    UnlinkedExecutable executable = serializeExecutableText(r'''
-import 'dart:async';
-Future f() async {}
-''');
-    expect(executable.isAsynchronous, isTrue);
-    expect(executable.isGenerator, isFalse);
-  }
-
-  test_executable_function_asyncStar() {
-    UnlinkedExecutable executable = serializeExecutableText(r'''
-import 'dart:async';
-Stream f() async* {}
-''');
-    expect(executable.isAsynchronous, isTrue);
-    expect(executable.isGenerator, isTrue);
-  }
-
-  test_executable_function_explicit_return() {
-    UnlinkedExecutable executable =
-        serializeExecutableText('dynamic f() => null;');
-    checkDynamicTypeRef(executable.returnType);
-  }
-
-  test_executable_function_external() {
-    UnlinkedExecutable executable = serializeExecutableText('external f();');
-    expect(executable.isExternal, isTrue);
-  }
-
-  test_executable_function_private() {
-    serializeExecutableText('_f() {}', executableName: '_f');
-    expect(unlinkedUnits[0].publicNamespace.names, isEmpty);
-  }
-
-  test_executable_getter() {
-    String text = 'int get f => 1;';
-    UnlinkedExecutable executable = serializeExecutableText(text);
-    expect(executable.kind, UnlinkedExecutableKind.getter);
-    expect(executable.returnType, isNotNull);
-    expect(executable.isAsynchronous, isFalse);
-    expect(executable.isExternal, isFalse);
-    expect(executable.isGenerator, isFalse);
-    expect(executable.nameOffset, text.indexOf('f'));
-    expect(findVariable('f'), isNull);
-    expect(findExecutable('f='), isNull);
-    expect(unlinkedUnits[0].publicNamespace.names, hasLength(1));
-    expect(unlinkedUnits[0].publicNamespace.names[0].kind,
-        ReferenceKind.topLevelPropertyAccessor);
-    expect(unlinkedUnits[0].publicNamespace.names[0].name, 'f');
-  }
-
-  test_executable_getter_external() {
-    UnlinkedExecutable executable =
-        serializeExecutableText('external int get f;');
-    expect(executable.isExternal, isTrue);
-  }
-
-  test_executable_getter_private() {
-    serializeExecutableText('int get _f => 1;', executableName: '_f');
-    expect(unlinkedUnits[0].publicNamespace.names, isEmpty);
-  }
-
-  test_executable_getter_type() {
-    UnlinkedExecutable executable = serializeExecutableText('int get f => 1;');
-    checkTypeRef(executable.returnType, 'dart:core', 'int');
-    expect(executable.parameters, isEmpty);
-  }
-
-  test_executable_getter_type_implicit() {
-    UnlinkedExecutable executable = serializeExecutableText('get f => 1;');
-    expect(executable.returnType, isNull);
-    expect(executable.parameters, isEmpty);
-  }
-
-  test_executable_localFunctions() {
-    String code = r'''
-f() {
-  f1() {}
-  {
-    f2() {}
-  }
-}
-''';
-    UnlinkedExecutable executable = serializeExecutableText(code);
-    List<UnlinkedExecutable> functions = executable.localFunctions;
-    expect(functions, isEmpty);
-  }
-
-  test_executable_member_function() {
-    UnlinkedExecutable executable = findExecutable('f',
-        executables: serializeClassText('class C { f() {} }').executables);
-    expect(executable.kind, UnlinkedExecutableKind.functionOrMethod);
-    expect(executable.returnType, isNull);
-    expect(executable.isAsynchronous, isFalse);
-    expect(executable.isExternal, isFalse);
-    expect(executable.isGenerator, isFalse);
-    expect(executable.visibleOffset, 0);
-    expect(executable.visibleLength, 0);
-    _assertCodeRange(executable.codeRange, 10, 6);
-  }
-
-  test_executable_member_function_async() {
-    UnlinkedExecutable executable =
-        findExecutable('f', executables: serializeClassText(r'''
-import 'dart:async';
-class C {
-  Future f() async {}
-}
-''').executables);
-    expect(executable.isAsynchronous, isTrue);
-    expect(executable.isGenerator, isFalse);
-  }
-
-  test_executable_member_function_asyncStar() {
-    UnlinkedExecutable executable =
-        findExecutable('f', executables: serializeClassText(r'''
-import 'dart:async';
-class C {
-  Stream f() async* {}
-}
-''').executables);
-    expect(executable.isAsynchronous, isTrue);
-    expect(executable.isGenerator, isTrue);
-  }
-
-  test_executable_member_function_explicit_return() {
-    UnlinkedExecutable executable = findExecutable('f',
-        executables:
-            serializeClassText('class C { dynamic f() => null; }').executables);
-    expect(executable.returnType, isNotNull);
-  }
-
-  test_executable_member_function_external() {
-    UnlinkedExecutable executable = findExecutable('f',
-        executables:
-            serializeClassText('class C { external f(); }').executables);
-    expect(executable.isExternal, isTrue);
-  }
-
-  test_executable_member_getter() {
-    UnlinkedClass cls = serializeClassText('class C { int get f => 1; }');
-    UnlinkedExecutable executable =
-        findExecutable('f', executables: cls.executables, failIfAbsent: true);
-    expect(executable.kind, UnlinkedExecutableKind.getter);
-    expect(executable.returnType, isNotNull);
-    expect(executable.isAsynchronous, isFalse);
-    expect(executable.isExternal, isFalse);
-    expect(executable.isGenerator, isFalse);
-    expect(executable.isStatic, isFalse);
-    _assertCodeRange(executable.codeRange, 10, 15);
-    expect(findVariable('f', variables: cls.fields), isNull);
-    expect(findExecutable('f=', executables: cls.executables), isNull);
-    expect(unlinkedUnits[0].publicNamespace.names, hasLength(1));
-    expect(unlinkedUnits[0].publicNamespace.names[0].name, 'C');
-    expect(unlinkedUnits[0].publicNamespace.names[0].members, isEmpty);
-  }
-
-  test_executable_member_getter_external() {
-    UnlinkedClass cls = serializeClassText('class C { external int get f; }');
-    UnlinkedExecutable executable =
-        findExecutable('f', executables: cls.executables, failIfAbsent: true);
-    expect(executable.isExternal, isTrue);
-  }
-
-  test_executable_member_getter_static() {
-    UnlinkedClass cls =
-        serializeClassText('class C { static int get f => 1; }');
-    UnlinkedExecutable executable =
-        findExecutable('f', executables: cls.executables, failIfAbsent: true);
-    expect(executable.isStatic, isTrue);
-    expect(unlinkedUnits[0].publicNamespace.names, hasLength(1));
-    expect(unlinkedUnits[0].publicNamespace.names[0].name, 'C');
-    expect(unlinkedUnits[0].publicNamespace.names[0].members, hasLength(1));
-    expect(unlinkedUnits[0].publicNamespace.names[0].members[0].name, 'f');
-    expect(unlinkedUnits[0].publicNamespace.names[0].members[0].kind,
-        ReferenceKind.propertyAccessor);
-    expect(
-        unlinkedUnits[0].publicNamespace.names[0].members[0].numTypeParameters,
-        0);
-    expect(
-        unlinkedUnits[0].publicNamespace.names[0].members[0].members, isEmpty);
-  }
-
-  test_executable_member_setter() {
-    UnlinkedClass cls = serializeClassText('class C { void set f(value) {} }');
-    UnlinkedExecutable executable =
-        findExecutable('f=', executables: cls.executables, failIfAbsent: true);
-    expect(executable.kind, UnlinkedExecutableKind.setter);
-    expect(executable.returnType, isNotNull);
-    expect(executable.isAsynchronous, isFalse);
-    expect(executable.isExternal, isFalse);
-    expect(executable.isGenerator, isFalse);
-    _assertCodeRange(executable.codeRange, 10, 20);
-    expect(findVariable('f', variables: cls.fields), isNull);
-    expect(findExecutable('f', executables: cls.executables), isNull);
-  }
-
-  test_executable_member_setter_external() {
-    UnlinkedClass cls =
-        serializeClassText('class C { external void set f(value); }');
-    UnlinkedExecutable executable =
-        findExecutable('f=', executables: cls.executables, failIfAbsent: true);
-    expect(executable.isExternal, isTrue);
-  }
-
-  test_executable_member_setter_implicit_return() {
-    UnlinkedClass cls = serializeClassText('class C { set f(value) {} }');
-    UnlinkedExecutable executable =
-        findExecutable('f=', executables: cls.executables, failIfAbsent: true);
-    expect(executable.returnType, isNull);
-  }
-
-  test_executable_name() {
-    UnlinkedExecutable executable = serializeExecutableText('f() {}');
-    expect(executable.name, 'f');
-  }
-
-  test_executable_no_flags() {
-    UnlinkedExecutable executable = serializeExecutableText('f() {}');
-    expect(executable.isAbstract, isFalse);
-    expect(executable.isConst, isFalse);
-    expect(executable.isFactory, isFalse);
-    expect(executable.isStatic, isFalse);
-  }
-
-  test_executable_non_static() {
-    UnlinkedExecutable executable =
-        serializeClassText('class C { f() {} }').executables[0];
-    expect(executable.isStatic, isFalse);
-  }
-
-  test_executable_non_static_top_level() {
-    // Top level executables are considered non-static.
-    UnlinkedExecutable executable = serializeExecutableText('f() {}');
-    expect(executable.isStatic, isFalse);
-  }
-
-  test_executable_operator() {
-    UnlinkedExecutable executable =
-        serializeClassText('class C { C operator+(C c) => null; }')
-            .executables[0];
-    expect(executable.kind, UnlinkedExecutableKind.functionOrMethod);
-    expect(executable.name, '+');
-    expect(executable.returnType, isNotNull);
-    expect(executable.isAbstract, false);
-    expect(executable.isAsynchronous, isFalse);
-    expect(executable.isConst, false);
-    expect(executable.isFactory, false);
-    expect(executable.isGenerator, isFalse);
-    expect(executable.isStatic, false);
-    expect(executable.parameters, hasLength(1));
-    checkTypeRef(executable.returnType, null, 'C');
-    expect(executable.typeParameters, isEmpty);
-    expect(executable.isExternal, false);
-  }
-
-  test_executable_operator_abstract() {
-    UnlinkedExecutable executable =
-        serializeClassText('class C { C operator+(C c); }', allowErrors: true)
-            .executables[0];
-    expect(executable.isAbstract, true);
-    expect(executable.isAsynchronous, isFalse);
-    expect(executable.isExternal, false);
-    expect(executable.isGenerator, isFalse);
-  }
-
-  test_executable_operator_equal() {
-    UnlinkedExecutable executable = serializeClassText(
-            'class C { bool operator==(Object other) => false; }')
-        .executables[0];
-    expect(executable.name, '==');
-  }
-
-  test_executable_operator_external() {
-    UnlinkedExecutable executable =
-        serializeClassText('class C { external C operator+(C c); }')
-            .executables[0];
-    expect(executable.isAbstract, false);
-    expect(executable.isAsynchronous, isFalse);
-    expect(executable.isExternal, true);
-    expect(executable.isGenerator, isFalse);
-  }
-
-  test_executable_operator_greater_equal() {
-    UnlinkedExecutable executable =
-        serializeClassText('class C { bool operator>=(C other) => false; }')
-            .executables[0];
-    expect(executable.name, '>=');
-  }
-
-  test_executable_operator_index() {
-    UnlinkedExecutable executable =
-        serializeClassText('class C { bool operator[](int i) => null; }')
-            .executables[0];
-    expect(executable.kind, UnlinkedExecutableKind.functionOrMethod);
-    expect(executable.name, '[]');
-    expect(executable.returnType, isNotNull);
-    expect(executable.isAbstract, false);
-    expect(executable.isConst, false);
-    expect(executable.isFactory, false);
-    expect(executable.isStatic, false);
-    expect(executable.parameters, hasLength(1));
-    checkTypeRef(executable.returnType, 'dart:core', 'bool');
-    expect(executable.typeParameters, isEmpty);
-  }
-
-  test_executable_operator_index_set() {
-    UnlinkedExecutable executable = serializeClassText(
-            'class C { void operator[]=(int i, bool v) => null; }')
-        .executables[0];
-    expect(executable.kind, UnlinkedExecutableKind.functionOrMethod);
-    expect(executable.name, '[]=');
-    expect(executable.returnType, isNotNull);
-    expect(executable.isAbstract, false);
-    expect(executable.isConst, false);
-    expect(executable.isFactory, false);
-    expect(executable.isStatic, false);
-    expect(executable.parameters, hasLength(2));
-    checkVoidTypeRef(executable.returnType);
-    expect(executable.typeParameters, isEmpty);
-  }
-
-  test_executable_operator_less_equal() {
-    UnlinkedExecutable executable =
-        serializeClassText('class C { bool operator<=(C other) => false; }')
-            .executables[0];
-    expect(executable.name, '<=');
-  }
-
-  test_executable_param_codeRange() {
-    UnlinkedExecutable executable = serializeExecutableText('f(int x) {}');
-    UnlinkedParam parameter = executable.parameters[0];
-    _assertCodeRange(parameter.codeRange, 2, 5);
-  }
-
-  test_executable_param_function_typed() {
-    UnlinkedExecutable executable = serializeExecutableText('f(g()) {}');
-    expect(executable.parameters[0].isFunctionTyped, isTrue);
-    expect(executable.parameters[0].type, isNull);
-  }
-
-  test_executable_param_function_typed_explicit_return_type() {
-    UnlinkedExecutable executable =
-        serializeExecutableText('f(dynamic g()) {}');
-    expect(executable.parameters[0].type, isNotNull);
-  }
-
-  test_executable_param_function_typed_param() {
-    UnlinkedExecutable executable = serializeExecutableText('f(g(x)) {}');
-    expect(executable.parameters[0].parameters, hasLength(1));
-  }
-
-  test_executable_param_function_typed_param_none() {
-    UnlinkedExecutable executable = serializeExecutableText('f(g()) {}');
-    expect(executable.parameters[0].parameters, isEmpty);
-  }
-
-  test_executable_param_function_typed_param_order() {
-    UnlinkedExecutable executable = serializeExecutableText('f(g(x, y)) {}');
-    expect(executable.parameters[0].parameters, hasLength(2));
-    expect(executable.parameters[0].parameters[0].name, 'x');
-    expect(executable.parameters[0].parameters[1].name, 'y');
-  }
-
-  test_executable_param_function_typed_return_type() {
-    UnlinkedExecutable executable = serializeExecutableText('f(int g()) {}');
-    checkTypeRef(executable.parameters[0].type, 'dart:core', 'int');
-  }
-
-  test_executable_param_function_typed_return_type_implicit() {
-    UnlinkedExecutable executable = serializeExecutableText('f(g()) {}');
-    expect(executable.parameters[0].isFunctionTyped, isTrue);
-    expect(executable.parameters[0].type, isNull);
-  }
-
-  test_executable_param_function_typed_return_type_void() {
-    UnlinkedExecutable executable = serializeExecutableText('f(void g()) {}');
-    checkVoidTypeRef(executable.parameters[0].type);
-  }
-
-  test_executable_param_function_typed_withDefault() {
-    UnlinkedExecutable executable = serializeExecutableText(r'''
-f([int p(int a2, String b2) = foo]) {}
-int foo(int a, String b) => 0;
-''');
-    UnlinkedParam param = executable.parameters[0];
-    expect(param.kind, UnlinkedParamKind.optionalPositional);
-    expect(param.initializer, isNotNull);
-    expect(param.defaultValueCode, 'foo');
-    assertUnlinkedConst(param.initializer.bodyExpr, 'foo', operators: [
-      UnlinkedExprOperation.pushReference
-    ], referenceValidators: [
-      (EntityRef r) => checkTypeRef(r, null, 'foo',
-          expectedKind: ReferenceKind.topLevelFunction)
-    ]);
-  }
-
-  test_executable_param_isFinal() {
-    String text = 'f(x, final y) {}';
-    UnlinkedExecutable executable = serializeExecutableText(text);
-    expect(executable.parameters, hasLength(2));
-    expect(executable.parameters[0].name, 'x');
-    expect(executable.parameters[0].isFinal, isFalse);
-    expect(executable.parameters[1].name, 'y');
-    expect(executable.parameters[1].isFinal, isTrue);
-  }
-
-  test_executable_param_kind_named() {
-    UnlinkedExecutable executable = serializeExecutableText('f({x}) {}');
-    UnlinkedParam param = executable.parameters[0];
-    expect(param.kind, UnlinkedParamKind.optionalNamed);
-    expect(param.initializer, isNull);
-    expect(param.defaultValueCode, isEmpty);
-  }
-
-  test_executable_param_kind_named_withDefault() {
-    UnlinkedExecutable executable = serializeExecutableText('f({x: 42}) {}');
-    UnlinkedParam param = executable.parameters[0];
-    expect(param.kind, UnlinkedParamKind.optionalNamed);
-    expect(param.initializer, isNotNull);
-    expect(param.defaultValueCode, '42');
-    _assertCodeRange(param.codeRange, 3, 5);
-    assertUnlinkedConst(param.initializer.bodyExpr, '42',
-        operators: [UnlinkedExprOperation.pushInt], ints: [42]);
-  }
-
-  test_executable_param_kind_positional() {
-    UnlinkedExecutable executable = serializeExecutableText('f([x]) {}');
-    UnlinkedParam param = executable.parameters[0];
-    expect(param.kind, UnlinkedParamKind.optionalPositional);
-    expect(param.initializer, isNull);
-    expect(param.defaultValueCode, isEmpty);
-  }
-
-  test_executable_param_kind_positional_withDefault() {
-    UnlinkedExecutable executable = serializeExecutableText('f([x = 42]) {}');
-    UnlinkedParam param = executable.parameters[0];
-    expect(param.kind, UnlinkedParamKind.optionalPositional);
-    expect(param.initializer, isNotNull);
-    expect(param.defaultValueCode, '42');
-    _assertCodeRange(param.codeRange, 3, 6);
-    assertUnlinkedConst(param.initializer.bodyExpr, '42',
-        operators: [UnlinkedExprOperation.pushInt], ints: [42]);
-  }
-
-  test_executable_param_kind_required() {
-    UnlinkedExecutable executable = serializeExecutableText('f(x) {}');
-    UnlinkedParam param = executable.parameters[0];
-    expect(param.kind, UnlinkedParamKind.requiredPositional);
-    expect(param.initializer, isNull);
-    expect(param.defaultValueCode, isEmpty);
-  }
-
-  test_executable_param_name() {
-    String text = 'f(x) {}';
-    UnlinkedExecutable executable = serializeExecutableText(text);
-    expect(executable.parameters, hasLength(1));
-    expect(executable.parameters[0].name, 'x');
-    expect(executable.parameters[0].nameOffset, text.indexOf('x'));
-  }
-
-  test_executable_param_no_flags() {
-    UnlinkedExecutable executable = serializeExecutableText('f(x) {}');
-    expect(executable.parameters[0].isFunctionTyped, isFalse);
-    expect(executable.parameters[0].isInitializingFormal, isFalse);
-  }
-
-  test_executable_param_non_function_typed() {
-    UnlinkedExecutable executable = serializeExecutableText('f(g) {}');
-    expect(executable.parameters[0].isFunctionTyped, isFalse);
-  }
-
-  test_executable_param_none() {
-    UnlinkedExecutable executable = serializeExecutableText('f() {}');
-    expect(executable.parameters, isEmpty);
-  }
-
-  test_executable_param_of_constructor_no_covariance() {
-    UnlinkedExecutable executable =
-        serializeClassText('class C { C(x); }').executables[0];
-    expect(executable.parameters[0].inheritsCovariantSlot, 0);
-  }
-
-  test_executable_param_of_method_covariance() {
-    UnlinkedExecutable executable =
-        serializeClassText('class C { m(x) {} }').executables[0];
-    expect(executable.parameters[0].inheritsCovariantSlot, isNot(0));
-  }
-
-  test_executable_param_of_param_no_covariance() {
-    UnlinkedExecutable executable =
-        serializeClassText('class C { m(f(x)) {} }').executables[0];
-    expect(executable.parameters[0].parameters[0].inheritsCovariantSlot, 0);
-  }
-
-  test_executable_param_of_setter_covariance() {
-    UnlinkedExecutable executable =
-        serializeClassText('class C { void set s(x) {} }').executables[0];
-    expect(executable.parameters[0].inheritsCovariantSlot, isNot(0));
-  }
-
-  test_executable_param_of_static_method_no_covariance() {
-    UnlinkedExecutable executable =
-        serializeClassText('class C { static m(x) {} }').executables[0];
-    expect(executable.parameters[0].inheritsCovariantSlot, 0);
-  }
-
-  test_executable_param_of_top_level_function_no_covariance() {
-    UnlinkedExecutable executable = serializeExecutableText('f(x) {}');
-    expect(executable.parameters[0].inheritsCovariantSlot, 0);
-  }
-
-  test_executable_param_order() {
-    UnlinkedExecutable executable = serializeExecutableText('f(x, y) {}');
-    expect(executable.parameters, hasLength(2));
-    expect(executable.parameters[0].name, 'x');
-    expect(executable.parameters[1].name, 'y');
-  }
-
-  test_executable_param_type_explicit() {
-    UnlinkedExecutable executable = serializeExecutableText('f(dynamic x) {}');
-    checkDynamicTypeRef(executable.parameters[0].type);
-  }
-
-  test_executable_param_type_implicit() {
-    UnlinkedExecutable executable = serializeExecutableText('f(x) {}');
-    expect(executable.parameters[0].type, isNull);
-  }
-
-  test_executable_param_type_typedef() {
-    UnlinkedExecutable executable = serializeExecutableText(r'''
-typedef MyFunction(int p);
-f(MyFunction myFunction) {}
-''');
-    expect(executable.parameters[0].isFunctionTyped, isFalse);
-    checkTypeRef(executable.parameters[0].type, null, 'MyFunction',
-        expectedKind: ReferenceKind.typedef);
-  }
-
-  test_executable_return_type() {
-    UnlinkedExecutable executable = serializeExecutableText('int f() => 1;');
-    checkTypeRef(executable.returnType, 'dart:core', 'int');
-  }
-
-  test_executable_return_type_implicit() {
-    UnlinkedExecutable executable = serializeExecutableText('f() {}');
-    expect(executable.returnType, isNull);
-  }
-
-  test_executable_return_type_void() {
-    UnlinkedExecutable executable = serializeExecutableText('void f() {}');
-    checkVoidTypeRef(executable.returnType);
-  }
-
-  test_executable_setter() {
-    String text = 'void set f(value) {}';
-    UnlinkedExecutable executable =
-        serializeExecutableText(text, executableName: 'f=');
-    expect(executable.kind, UnlinkedExecutableKind.setter);
-    expect(executable.returnType, isNotNull);
-    expect(executable.isAsynchronous, isFalse);
-    expect(executable.isExternal, isFalse);
-    expect(executable.isGenerator, isFalse);
-    expect(executable.nameOffset, text.indexOf('f'));
-    expect(findVariable('f'), isNull);
-    expect(findExecutable('f'), isNull);
-    expect(unlinkedUnits[0].publicNamespace.names, hasLength(1));
-    expect(unlinkedUnits[0].publicNamespace.names[0].kind,
-        ReferenceKind.topLevelPropertyAccessor);
-    expect(unlinkedUnits[0].publicNamespace.names[0].name, 'f=');
-  }
-
-  test_executable_setter_external() {
-    UnlinkedExecutable executable = serializeExecutableText(
-        'external void set f(value);',
-        executableName: 'f=');
-    expect(executable.isExternal, isTrue);
-  }
-
-  test_executable_setter_implicit_return() {
-    UnlinkedExecutable executable =
-        serializeExecutableText('set f(value) {}', executableName: 'f=');
-    expect(executable.returnType, isNull);
-  }
-
-  test_executable_setter_private() {
-    serializeExecutableText('void set _f(value) {}', executableName: '_f=');
-    expect(unlinkedUnits[0].publicNamespace.names, isEmpty);
-  }
-
-  test_executable_setter_type() {
-    UnlinkedExecutable executable = serializeExecutableText(
-        'void set f(int value) {}',
-        executableName: 'f=');
-    checkVoidTypeRef(executable.returnType);
-    expect(executable.parameters, hasLength(1));
-    expect(executable.parameters[0].name, 'value');
-    checkTypeRef(executable.parameters[0].type, 'dart:core', 'int');
-  }
-
-  test_executable_static() {
-    UnlinkedExecutable executable =
-        serializeClassText('class C { static f() {} }').executables[0];
-    expect(executable.isStatic, isTrue);
-  }
-
-  test_executable_type_param_f_bound_function() {
-    UnlinkedExecutable ex =
-        serializeExecutableText('void f<T, U extends List<T>>() {}');
-    EntityRef typeArgument = ex.typeParameters[1].bound.typeArguments[0];
-    checkParamTypeRef(typeArgument, 2);
-  }
-
-  test_executable_type_param_f_bound_method() {
-    UnlinkedExecutable ex =
-        serializeMethodText('void f<T, U extends List<T>>() {}');
-    EntityRef typeArgument = ex.typeParameters[1].bound.typeArguments[0];
-    checkParamTypeRef(typeArgument, 2);
-  }
-
-  test_executable_type_param_f_bound_self_ref_function() {
-    UnlinkedExecutable ex =
-        serializeExecutableText('void f<T, U extends List<U>>() {}');
-    EntityRef typeArgument = ex.typeParameters[1].bound.typeArguments[0];
-    checkParamTypeRef(typeArgument, 1);
-  }
-
-  test_executable_type_param_f_bound_self_ref_method() {
-    UnlinkedExecutable ex =
-        serializeMethodText('void f<T, U extends List<U>>() {}');
-    EntityRef typeArgument = ex.typeParameters[1].bound.typeArguments[0];
-    checkParamTypeRef(typeArgument, 1);
-  }
-
-  test_executable_type_param_in_parameter_function() {
-    UnlinkedExecutable ex = serializeExecutableText('void f<T>(T t) {}');
-    checkParamTypeRef(ex.parameters[0].type, 1);
-    expect(unlinkedUnits[0].publicNamespace.names[0].numTypeParameters, 1);
-  }
-
-  test_executable_type_param_in_parameter_method() {
-    UnlinkedExecutable ex = serializeMethodText('void f<T>(T t) {}');
-    checkParamTypeRef(ex.parameters[0].type, 1);
-  }
-
-  test_executable_type_param_in_return_type_function() {
-    UnlinkedExecutable ex = serializeExecutableText('T f<T>() => null;');
-    checkParamTypeRef(ex.returnType, 1);
-  }
-
-  test_executable_type_param_in_return_type_method() {
-    UnlinkedExecutable ex = serializeMethodText('T f<T>() => null;');
-    checkParamTypeRef(ex.returnType, 1);
-  }
-
-  test_export_class() {
-    addNamedSource('/a.dart', 'class C {}');
-    serializeLibraryText('export "a.dart";');
-    expect(linked.exportNames, hasLength(1));
-    checkExportName(linked.exportNames[0], absUri('/a.dart'), 'C',
-        ReferenceKind.classOrEnum);
-  }
-
-  test_export_class_alias() {
-    addNamedSource(
-        '/a.dart', 'class C extends _D with _E {} class _D {} class _E {}');
-    serializeLibraryText('export "a.dart";');
-    expect(linked.exportNames, hasLength(1));
-    checkExportName(linked.exportNames[0], absUri('/a.dart'), 'C',
-        ReferenceKind.classOrEnum);
-  }
-
-  test_export_configurations() {
-    addNamedSource('/foo.dart', 'class A {}');
-    addNamedSource('/foo_io.dart', 'class A {}');
-    addNamedSource('/foo_html.dart', 'class A {}');
-    String libraryText = r'''
-export 'foo.dart'
-  if (dart.library.io) 'foo_io.dart'
-  if (dart.flavor == 'html') 'foo_html.dart';
-
-class B extends A {}
-''';
-    serializeLibraryText(libraryText);
-    UnlinkedExportPublic exp = unlinkedUnits[0].publicNamespace.exports[0];
-    expect(exp.configurations, hasLength(2));
-    {
-      UnlinkedConfiguration configuration = exp.configurations[0];
-      expect(configuration.name, 'dart.library.io');
-      expect(configuration.value, 'true');
-      expect(configuration.uri, 'foo_io.dart');
-    }
-    {
-      UnlinkedConfiguration configuration = exp.configurations[1];
-      expect(configuration.name, 'dart.flavor');
-      expect(configuration.value, 'html');
-      expect(configuration.uri, 'foo_html.dart');
-    }
-  }
-
-  test_export_dependency() {
-    serializeLibraryText('export "dart:async";');
-    expect(unlinkedUnits[0].exports, hasLength(1));
-    checkDependency(linked.exportDependencies[0], 'dart:async');
-  }
-
-  test_export_enum() {
-    addNamedSource('/a.dart', 'enum E { v }');
-    serializeLibraryText('export "a.dart";');
-    expect(linked.exportNames, hasLength(1));
-    checkExportName(linked.exportNames[0], absUri('/a.dart'), 'E',
-        ReferenceKind.classOrEnum);
-  }
-
-  test_export_from_part() {
-    addNamedSource('/a.dart', 'library foo; part "b.dart";');
-    addNamedSource('/b.dart', 'part of foo; f() {}');
-    serializeLibraryText('export "a.dart";');
-    expect(linked.exportNames, hasLength(1));
-    checkExportName(linked.exportNames[0], absUri('/a.dart'), 'f',
-        ReferenceKind.topLevelFunction,
-        expectedTargetUnit: 1);
-  }
-
-  test_export_function() {
-    addNamedSource('/a.dart', 'f() {}');
-    serializeLibraryText('export "a.dart";');
-    expect(linked.exportNames, hasLength(1));
-    checkExportName(linked.exportNames[0], absUri('/a.dart'), 'f',
-        ReferenceKind.topLevelFunction);
-  }
-
-  test_export_getter() {
-    addNamedSource('/a.dart', 'get f => null');
-    serializeLibraryText('export "a.dart";');
-    expect(linked.exportNames, hasLength(1));
-    checkExportName(linked.exportNames[0], absUri('/a.dart'), 'f',
-        ReferenceKind.topLevelPropertyAccessor);
-  }
-
-  test_export_hide() {
-    addNamedSource('/a.dart', 'f() {} g() {}');
-    serializeLibraryText('export "a.dart" hide g;');
-    expect(linked.exportNames, hasLength(1));
-    checkExportName(linked.exportNames[0], absUri('/a.dart'), 'f',
-        ReferenceKind.topLevelFunction);
-  }
-
-  test_export_hide_order() {
-    serializeLibraryText('export "dart:async" hide Future, Stream;');
-    expect(unlinkedUnits[0].publicNamespace.exports, hasLength(1));
-    expect(
-        unlinkedUnits[0].publicNamespace.exports[0].combinators, hasLength(1));
-    expect(unlinkedUnits[0].publicNamespace.exports[0].combinators[0].shows,
-        isEmpty);
-    expect(unlinkedUnits[0].publicNamespace.exports[0].combinators[0].hides,
-        hasLength(2));
-    expect(unlinkedUnits[0].publicNamespace.exports[0].combinators[0].hides[0],
-        'Future');
-    expect(unlinkedUnits[0].publicNamespace.exports[0].combinators[0].hides[1],
-        'Stream');
-    expect(
-        unlinkedUnits[0].publicNamespace.exports[0].combinators[0].offset, 0);
-    expect(unlinkedUnits[0].publicNamespace.exports[0].combinators[0].end, 0);
-    expect(linked.exportNames, isNotEmpty);
-  }
-
-  test_export_missing() {
-    // Unresolved exports are included since this is necessary for proper
-    // dependency tracking.
-    allowMissingFiles = true;
-    serializeLibraryText('export "foo.dart";', allowErrors: true);
-    expect(unlinkedUnits[0].imports, hasLength(1));
-    checkDependency(linked.exportDependencies[0], absUri('/foo.dart'));
-  }
-
-  test_export_names_excludes_names_from_library() {
-    addNamedSource('/a.dart', 'part of my.lib; int y; int _y;');
-    serializeLibraryText('library my.lib; part "a.dart"; int x; int _x;');
-    expect(linked.exportNames, isEmpty);
-  }
-
-  test_export_no_combinators() {
-    serializeLibraryText('export "dart:async";');
-    expect(unlinkedUnits[0].publicNamespace.exports, hasLength(1));
-    expect(unlinkedUnits[0].publicNamespace.exports[0].combinators, isEmpty);
-  }
-
-  test_export_not_shadowed_by_prefix() {
-    addNamedSource('/a.dart', 'f() {}');
-    serializeLibraryText('export "a.dart"; import "dart:core" as f; f.int _x;');
-    expect(linked.exportNames, hasLength(1));
-    checkExportName(linked.exportNames[0], absUri('/a.dart'), 'f',
-        ReferenceKind.topLevelFunction);
-  }
-
-  test_export_offset() {
-    String libraryText = '    export "dart:async";';
-    serializeLibraryText(libraryText);
-    expect(unlinkedUnits[0].exports[0].uriOffset,
-        libraryText.indexOf('"dart:async"'));
-    expect(unlinkedUnits[0].exports[0].uriEnd, libraryText.indexOf(';'));
-    expect(unlinkedUnits[0].exports[0].offset, libraryText.indexOf('export'));
-  }
-
-  test_export_private() {
-    // Private names should not be exported.
-    addNamedSource('/a.dart', '_f() {}');
-    serializeLibraryText('export "a.dart";');
-    expect(linked.exportNames, isEmpty);
-  }
-
-  test_export_setter() {
-    addNamedSource('/a.dart', 'void set f(value) {}');
-    serializeLibraryText('export "a.dart";');
-    expect(linked.exportNames, hasLength(1));
-    checkExportName(linked.exportNames[0], absUri('/a.dart'), 'f=',
-        ReferenceKind.topLevelPropertyAccessor);
-  }
-
-  test_export_shadowed() {
-    // f() is not shown in exportNames because it is already defined at top
-    // level in the library.
-    addNamedSource('/a.dart', 'f() {}');
-    serializeLibraryText('export "a.dart"; f() {}');
-    expect(linked.exportNames, isEmpty);
-  }
-
-  test_export_shadowed_variable() {
-    // Neither `v` nor `v=` is shown in exportNames because both are defined at
-    // top level in the library by the declaration `var v;`.
-    addNamedSource('/a.dart', 'var v;');
-    serializeLibraryText('export "a.dart"; var v;');
-    expect(linked.exportNames, isEmpty);
-  }
-
-  test_export_shadowed_variable_const() {
-    // `v=` is shown in exportNames because the top level declaration
-    // `const v = 0;` only shadows `v`, not `v=`.
-    addNamedSource('/a.dart', 'var v;');
-    serializeLibraryText('export "a.dart"; const v = 0;');
-    expect(linked.exportNames, hasLength(1));
-    checkExportName(linked.exportNames[0], absUri('/a.dart'), 'v=',
-        ReferenceKind.topLevelPropertyAccessor);
-  }
-
-  test_export_shadowed_variable_final() {
-    // `v=` is shown in exportNames because the top level declaration
-    // `final v = 0;` only shadows `v`, not `v=`.
-    addNamedSource('/a.dart', 'var v;');
-    serializeLibraryText('export "a.dart"; final v = 0;');
-    expect(linked.exportNames, hasLength(1));
-    checkExportName(linked.exportNames[0], absUri('/a.dart'), 'v=',
-        ReferenceKind.topLevelPropertyAccessor);
-  }
-
-  test_export_show() {
-    addNamedSource('/a.dart', 'f() {} g() {}');
-    serializeLibraryText('export "a.dart" show f;');
-    expect(linked.exportNames, hasLength(1));
-    checkExportName(linked.exportNames[0], absUri('/a.dart'), 'f',
-        ReferenceKind.topLevelFunction);
-  }
-
-  test_export_show_order() {
-    String libraryText = 'export "dart:async" show Future, Stream;';
-    serializeLibraryText(libraryText);
-    expect(unlinkedUnits[0].publicNamespace.exports, hasLength(1));
-    expect(
-        unlinkedUnits[0].publicNamespace.exports[0].combinators, hasLength(1));
-    expect(unlinkedUnits[0].publicNamespace.exports[0].combinators[0].shows,
-        hasLength(2));
-    expect(unlinkedUnits[0].publicNamespace.exports[0].combinators[0].hides,
-        isEmpty);
-    expect(unlinkedUnits[0].publicNamespace.exports[0].combinators[0].shows[0],
-        'Future');
-    expect(unlinkedUnits[0].publicNamespace.exports[0].combinators[0].shows[1],
-        'Stream');
-    expect(unlinkedUnits[0].publicNamespace.exports[0].combinators[0].offset,
-        libraryText.indexOf('show'));
-    expect(unlinkedUnits[0].publicNamespace.exports[0].combinators[0].end,
-        libraryText.indexOf(';'));
-  }
-
-  test_export_typedef() {
-    addNamedSource('/a.dart', 'typedef F();');
-    serializeLibraryText('export "a.dart";');
-    expect(linked.exportNames, hasLength(1));
-    checkExportName(
-        linked.exportNames[0], absUri('/a.dart'), 'F', ReferenceKind.typedef);
-  }
-
-  test_export_typedef_genericFunction() {
-    addNamedSource('/a.dart', 'typedef F<S> = S Function<T>(T x);');
-    serializeLibraryText('export "a.dart";');
-    expect(linked.exportNames, hasLength(1));
-    checkExportName(linked.exportNames[0], absUri('/a.dart'), 'F',
-        ReferenceKind.genericFunctionTypedef);
-  }
-
-  test_export_uri() {
-    addNamedSource('/a.dart', 'library my.lib;');
-    String uriString = '"a.dart"';
-    String libraryText = 'export $uriString;';
-    serializeLibraryText(libraryText);
-    var unlinkedExports = unlinkedUnits[0].publicNamespace.exports;
-    expect(unlinkedExports, hasLength(1));
-    expect(unlinkedExports[0].uri, 'a.dart');
-    expect(unlinkedExports[0].configurations, isEmpty);
-  }
-
-  test_export_uri_invalid() {
-    String uriString = ':[invalid uri]';
-    String libraryText = 'export "$uriString";';
-    serializeLibraryText(libraryText);
-    expect(unlinkedUnits[0].publicNamespace.exports, hasLength(1));
-    expect(unlinkedUnits[0].publicNamespace.exports[0].uri, uriString);
-  }
-
-  test_export_uri_nullStringValue() {
-    String libraryText = r'''
-export "${'a'}.dart";
-''';
-    serializeLibraryText(libraryText);
-    var unlinkedExports = unlinkedUnits[0].publicNamespace.exports;
-    expect(unlinkedExports, hasLength(1));
-    expect(unlinkedExports[0].uri, '');
-    expect(unlinkedExports[0].configurations, isEmpty);
-  }
-
-  test_export_variable() {
-    addNamedSource('/a.dart', 'var v;');
-    serializeLibraryText('export "a.dart";');
-    expect(linked.exportNames, hasLength(2));
-    LinkedExportName getter =
-        linked.exportNames.firstWhere((e) => e.name == 'v');
-    expect(getter, isNotNull);
-    checkExportName(
-        getter, absUri('/a.dart'), 'v', ReferenceKind.topLevelPropertyAccessor);
-    LinkedExportName setter =
-        linked.exportNames.firstWhere((e) => e.name == 'v=');
-    expect(setter, isNotNull);
-    checkExportName(setter, absUri('/a.dart'), 'v=',
-        ReferenceKind.topLevelPropertyAccessor);
-  }
-
-  test_expr_assignOperator_assign() {
-    _assertAssignmentOperator(
-        '(a = 1 + 2) + 3', UnlinkedExprAssignOperator.assign);
-  }
-
-  test_expr_assignOperator_bitAnd() {
-    _assertAssignmentOperator(
-        '(a &= 1 + 2) + 3', UnlinkedExprAssignOperator.bitAnd);
-  }
-
-  test_expr_assignOperator_bitOr() {
-    _assertAssignmentOperator(
-        '(a |= 1 + 2) + 3', UnlinkedExprAssignOperator.bitOr);
-  }
-
-  test_expr_assignOperator_bitXor() {
-    _assertAssignmentOperator(
-        '(a ^= 1 + 2) + 3', UnlinkedExprAssignOperator.bitXor);
-  }
-
-  test_expr_assignOperator_divide() {
-    _assertAssignmentOperator(
-        '(a /= 1 + 2) + 3', UnlinkedExprAssignOperator.divide);
-  }
-
-  test_expr_assignOperator_floorDivide() {
-    _assertAssignmentOperator(
-        '(a ~/= 1 + 2) + 3', UnlinkedExprAssignOperator.floorDivide);
-  }
-
-  test_expr_assignOperator_ifNull() {
-    _assertAssignmentOperator(
-        '(a ??= 1 + 2) + 3', UnlinkedExprAssignOperator.ifNull);
-  }
-
-  test_expr_assignOperator_minus() {
-    _assertAssignmentOperator(
-        '(a -= 1 + 2) + 3', UnlinkedExprAssignOperator.minus);
-  }
-
-  test_expr_assignOperator_modulo() {
-    _assertAssignmentOperator(
-        '(a %= 1 + 2) + 3', UnlinkedExprAssignOperator.modulo);
-  }
-
-  test_expr_assignOperator_multiply() {
-    _assertAssignmentOperator(
-        '(a *= 1 + 2) + 3', UnlinkedExprAssignOperator.multiply);
-  }
-
-  test_expr_assignOperator_plus() {
-    _assertAssignmentOperator(
-        '(a += 1 + 2) + 3', UnlinkedExprAssignOperator.plus);
-  }
-
-  test_expr_assignOperator_shiftLeft() {
-    _assertAssignmentOperator(
-        '(a <<= 1 + 2) + 3', UnlinkedExprAssignOperator.shiftLeft);
-  }
-
-  test_expr_assignOperator_shiftRight() {
-    _assertAssignmentOperator(
-        '(a >>= 1 + 2) + 3', UnlinkedExprAssignOperator.shiftRight);
-  }
-
-  test_expr_assignToIndex_ofFieldSequence() {
-    UnlinkedVariable variable = serializeVariableText('''
-class A {
-  B b;
-}
-class B {
-  C c;
-}
-class C {
-  List<int> f = <int>[0, 1, 2];
-}
-A a = new A();
-final v = (a.b.c.f[1] = 5);
-''');
-    assertUnlinkedConst(variable.initializer.bodyExpr, '(a.b.c.f[1] = 5)',
-        isValidConst: false,
-        operators: [
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.pushReference,
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.assignToIndex,
-        ],
-        assignmentOperators: [(UnlinkedExprAssignOperator.assign)],
-        ints: [5, 1],
-        strings: [],
-        referenceValidators: [
-          (EntityRef r) => checkTypeRef(r, null, 'f',
-                  expectedKind: ReferenceKind.unresolved,
-                  prefixExpectations: [
-                    new _PrefixExpectation(ReferenceKind.unresolved, 'c'),
-                    new _PrefixExpectation(ReferenceKind.unresolved, 'b'),
-                    new _PrefixExpectation(
-                        ReferenceKind.topLevelPropertyAccessor, 'a')
-                  ])
-        ],
-        forTypeInferenceOnly: true);
-  }
-
-  test_expr_assignToIndex_ofIndexExpression() {
-    UnlinkedVariable variable = serializeVariableText('''
-class A {
- List<B> b;
-}
-class B {
-  List<C> c;
-}
-class C {
-  List<int> f = <int>[0, 1, 2];
-}
-A a = new A();
-final v = (a.b[1].c[2].f[3] = 5);
-''');
-    assertUnlinkedConst(variable.initializer.bodyExpr, '(a.b[1].c[2].f[3] = 5)',
-        isValidConst: false,
-        operators: [
-          // 5
-          UnlinkedExprOperation.pushInt,
-          // a.b[1]
-          UnlinkedExprOperation.pushReference,
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.extractIndex,
-          // c[2]
-          UnlinkedExprOperation.extractProperty,
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.extractIndex,
-          // f[3] = 5
-          UnlinkedExprOperation.extractProperty,
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.assignToIndex,
-        ],
-        assignmentOperators: [(UnlinkedExprAssignOperator.assign)],
-        ints: [
-          5,
-          1,
-          2,
-          3,
-        ],
-        strings: ['c', 'f'],
-        referenceValidators: [
-          (EntityRef r) => checkTypeRef(r, null, 'b',
-                  expectedKind: ReferenceKind.unresolved,
-                  prefixExpectations: [
-                    new _PrefixExpectation(
-                        ReferenceKind.topLevelPropertyAccessor, 'a')
-                  ])
-        ],
-        forTypeInferenceOnly: true);
-  }
-
-  test_expr_assignToIndex_ofTopLevelVariable() {
-    UnlinkedVariable variable = serializeVariableText('''
-List<int> a = <int>[0, 1, 2];
-final v = (a[1] = 5);
-''');
-    assertUnlinkedConst(variable.initializer.bodyExpr, '(a[1] = 5)',
-        isValidConst: false,
-        operators: [
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.pushReference,
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.assignToIndex,
-        ],
-        assignmentOperators: [(UnlinkedExprAssignOperator.assign)],
-        ints: [
-          5,
-          1,
-        ],
-        strings: [],
-        referenceValidators: [
-          (EntityRef r) => checkTypeRef(r, null, 'a',
-              expectedKind: ReferenceKind.topLevelPropertyAccessor)
-        ],
-        forTypeInferenceOnly: true);
-  }
-
-  test_expr_assignToProperty_ofInstanceCreation() {
-    UnlinkedVariable variable = serializeVariableText('''
-class C {
-  int f;
-}
-final v = (new C().f = 5);
-''');
-    assertUnlinkedConst(variable.initializer.bodyExpr, '(new C().f = 5)',
-        isValidConst: false,
-        operators: [
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.invokeConstructor,
-          UnlinkedExprOperation.assignToProperty,
-        ],
-        assignmentOperators: [(UnlinkedExprAssignOperator.assign)],
-        ints: [
-          5,
-          0,
-          0,
-        ],
-        strings: ['f'],
-        referenceValidators: [
-          (EntityRef r) => checkTypeRef(r, null, 'C',
-              expectedKind: ReferenceKind.classOrEnum)
-        ],
-        forTypeInferenceOnly: true);
-  }
-
-  test_expr_assignToRef_classStaticField() {
-    UnlinkedVariable variable = serializeVariableText('''
-class C {
-  static int f;
-}
-final v = (C.f = 1);
-''');
-    assertUnlinkedConst(variable.initializer.bodyExpr, '(C.f = 1)',
-        isValidConst: false,
-        operators: [
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.assignToRef,
-        ],
-        assignmentOperators: [(UnlinkedExprAssignOperator.assign)],
-        ints: [
-          1,
-        ],
-        strings: [],
-        referenceValidators: [
-          (EntityRef r) => checkTypeRef(r, null, 'f',
-                  expectedKind: ReferenceKind.unresolved,
-                  prefixExpectations: [
-                    new _PrefixExpectation(ReferenceKind.classOrEnum, 'C')
-                  ])
-        ],
-        forTypeInferenceOnly: true);
-  }
-
-  test_expr_assignToRef_fieldSequence() {
-    UnlinkedVariable variable = serializeVariableText('''
-class A {
-  B b;
-}
-class B {
-  C c;
-}
-class C {
-  int f;
-}
-A a = new A();
-final v = (a.b.c.f = 1);
-''');
-    assertUnlinkedConst(variable.initializer.bodyExpr, '(a.b.c.f = 1)',
-        isValidConst: false,
-        operators: [
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.assignToRef,
-        ],
-        assignmentOperators: [(UnlinkedExprAssignOperator.assign)],
-        ints: [
-          1,
-        ],
-        strings: [],
-        referenceValidators: [
-          (EntityRef r) => checkTypeRef(r, null, 'f',
-                  expectedKind: ReferenceKind.unresolved,
-                  prefixExpectations: [
-                    new _PrefixExpectation(ReferenceKind.unresolved, 'c'),
-                    new _PrefixExpectation(ReferenceKind.unresolved, 'b'),
-                    new _PrefixExpectation(
-                        ReferenceKind.topLevelPropertyAccessor, 'a')
-                  ])
-        ],
-        forTypeInferenceOnly: true);
-  }
-
-  test_expr_assignToRef_postfixDecrement() {
-    _assertRefPrefixPostfixIncrementDecrement(
-        'a-- + 2', UnlinkedExprAssignOperator.postfixDecrement);
-  }
-
-  test_expr_assignToRef_postfixIncrement() {
-    _assertRefPrefixPostfixIncrementDecrement(
-        'a++ + 2', UnlinkedExprAssignOperator.postfixIncrement);
-  }
-
-  test_expr_assignToRef_prefixDecrement() {
-    _assertRefPrefixPostfixIncrementDecrement(
-        '--a + 2', UnlinkedExprAssignOperator.prefixDecrement);
-  }
-
-  test_expr_assignToRef_prefixIncrement() {
-    _assertRefPrefixPostfixIncrementDecrement(
-        '++a + 2', UnlinkedExprAssignOperator.prefixIncrement);
-  }
-
-  test_expr_assignToRef_topLevelVariable() {
-    UnlinkedVariable variable = serializeVariableText('''
-int a = 0;
-final v = (a = 1);
-''');
-    assertUnlinkedConst(variable.initializer.bodyExpr, '(a = 1)',
-        isValidConst: false,
-        operators: [
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.assignToRef,
-        ],
-        assignmentOperators: [(UnlinkedExprAssignOperator.assign)],
-        ints: [
-          1,
-        ],
-        strings: [],
-        referenceValidators: [
-          (EntityRef r) => checkTypeRef(r, null, 'a',
-              expectedKind: ReferenceKind.topLevelPropertyAccessor)
-        ],
-        forTypeInferenceOnly: true);
-  }
-
-  test_expr_assignToRef_topLevelVariable_imported() {
-    addNamedSource('/a.dart', '''
-int a = 0;
-''');
-    UnlinkedVariable variable = serializeVariableText('''
-import 'a.dart';
-final v = (a = 1);
-''');
-    assertUnlinkedConst(variable.initializer.bodyExpr, '(a = 1)',
-        isValidConst: false,
-        operators: [
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.assignToRef,
-        ],
-        assignmentOperators: [(UnlinkedExprAssignOperator.assign)],
-        ints: [
-          1,
-        ],
-        strings: [],
-        referenceValidators: [
-          (EntityRef r) => checkTypeRef(r, absUri('/a.dart'), 'a',
-              expectedKind: ReferenceKind.topLevelPropertyAccessor)
-        ],
-        forTypeInferenceOnly: true);
-  }
-
-  test_expr_assignToRef_topLevelVariable_imported_withPrefix() {
-    addNamedSource('/a.dart', '''
-int a = 0;
-''');
-    UnlinkedVariable variable = serializeVariableText('''
-import 'a.dart' as p;
-final v = (p.a = 1);
-''');
-    assertUnlinkedConst(variable.initializer.bodyExpr, '(p.a = 1)',
-        isValidConst: false,
-        operators: [
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.assignToRef,
-        ],
-        assignmentOperators: [(UnlinkedExprAssignOperator.assign)],
-        ints: [
-          1,
-        ],
-        strings: [],
-        referenceValidators: [
-          (EntityRef r) {
-            return checkTypeRef(r, absUri('/a.dart'), 'a',
-                expectedKind: ReferenceKind.topLevelPropertyAccessor,
-                expectedPrefix: 'p');
-          }
-        ],
-        forTypeInferenceOnly: true);
-  }
-
-  test_expr_cascadeSection_assignToIndex() {
-    UnlinkedVariable variable = serializeVariableText('''
-class C {
-  List<int> items;
-}
-final C c = new C();
-final v = c.items..[1] = 2;
-''');
-    assertUnlinkedConst(variable.initializer.bodyExpr, 'c.items..[1] = 2',
-        isValidConst: false,
-        operators: [
-          UnlinkedExprOperation.pushReference,
-        ],
-        assignmentOperators: [],
-        ints: [],
-        strings: [],
-        referenceValidators: [
-          (EntityRef r) => checkTypeRef(r, null, 'items',
-                  expectedKind: ReferenceKind.unresolved,
-                  prefixExpectations: [
-                    new _PrefixExpectation(
-                        ReferenceKind.topLevelPropertyAccessor, 'c'),
-                  ])
-        ],
-        forTypeInferenceOnly: true);
-  }
-
-  test_expr_cascadeSection_assignToProperty() {
-    UnlinkedVariable variable = serializeVariableText('''
-class C {
-  int f1 = 0;
-  int f2 = 0;
-}
-final v = new C()..f1 = 1..f2 += 2;
-''');
-    assertUnlinkedConst(
-        variable.initializer.bodyExpr, 'new C()..f1 = 1..f2 += 2',
-        isValidConst: false,
-        operators: [
-          UnlinkedExprOperation.invokeConstructor,
-        ],
-        assignmentOperators: [],
-        ints: [0, 0],
-        strings: [],
-        referenceValidators: [
-          (EntityRef r) => checkTypeRef(r, null, 'C',
-              expectedKind: ReferenceKind.classOrEnum)
-        ],
-        forTypeInferenceOnly: true);
-  }
-
-  test_expr_cascadeSection_embedded() {
-    UnlinkedVariable variable = serializeVariableText('''
-class A {
-  int fa1;
-  B b;
-  int fa2;
-}
-class B {
-  int fb;
-}
-final v = new A()
-  ..fa1 = 1
-  ..b = (new B()..fb = 2)
-  ..fa2 = 3;
-''');
-    assertUnlinkedConst(variable.initializer.bodyExpr,
-        'new A()..fa1 = 1..b = (new B()..fb = 2)..fa2 = 3',
-        isValidConst: false,
-        operators: [
-          UnlinkedExprOperation.invokeConstructor,
-        ],
-        assignmentOperators: [],
-        ints: [
-          0,
-          0,
-        ],
-        strings: [],
-        referenceValidators: [
-          (EntityRef r) => checkTypeRef(r, null, 'A',
-              expectedKind: ReferenceKind.classOrEnum),
-        ],
-        forTypeInferenceOnly: true);
-  }
-
-  test_expr_cascadeSection_invokeMethod() {
-    UnlinkedVariable variable = serializeVariableText('''
-class A {
-  int m(int _) => 0;
-}
-final A a = new A();
-final v = a..m(5).abs()..m(6);
-''');
-    assertUnlinkedConst(variable.initializer.bodyExpr, 'a..m(5).abs()..m(6)',
-        isValidConst: false,
-        operators: [
-          UnlinkedExprOperation.pushReference,
-        ],
-        ints: [],
-        strings: [],
-        referenceValidators: [
-          (EntityRef r) => checkTypeRef(r, null, 'a',
-              expectedKind: ReferenceKind.topLevelPropertyAccessor),
-        ],
-        forTypeInferenceOnly: true);
-  }
-
-  test_expr_extractIndex_ofClassField() {
-    UnlinkedVariable variable = serializeVariableText('''
-class C {
-  List<int> get items => null;
-}
-final v = new C().items[5];
-''');
-    assertUnlinkedConst(variable.initializer.bodyExpr, 'new C().items[5]',
-        isValidConst: false,
-        operators: [
-          UnlinkedExprOperation.invokeConstructor,
-          UnlinkedExprOperation.extractProperty,
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.extractIndex,
-        ],
-        ints: [0, 0, 5],
-        strings: ['items'],
-        referenceValidators: [
-          (EntityRef r) => checkTypeRef(r, null, 'C',
-              expectedKind: ReferenceKind.classOrEnum)
-        ],
-        forTypeInferenceOnly: true);
-  }
-
-  test_expr_extractProperty_ofInvokeConstructor() {
-    UnlinkedVariable variable = serializeVariableText('''
-class C {
-  int f = 0;
-}
-final v = new C().f;
-''');
-    assertUnlinkedConst(variable.initializer.bodyExpr, 'new C().f',
-        isValidConst: false,
-        operators: [
-          UnlinkedExprOperation.invokeConstructor,
-          UnlinkedExprOperation.extractProperty,
-        ],
-        ints: [0, 0],
-        strings: ['f'],
-        referenceValidators: [
-          (EntityRef r) => checkTypeRef(r, null, 'C',
-              expectedKind: ReferenceKind.classOrEnum)
-        ],
-        forTypeInferenceOnly: true);
-  }
-
-  test_expr_functionExpression_asArgument() {
-    UnlinkedVariable variable = serializeVariableText('''
-final v = foo(5, () => 42);
-foo(a, b) {}
-''');
-    assertUnlinkedConst(variable.initializer.bodyExpr, 'foo(5, () => 42)',
-        isValidConst: false,
-        operators: [
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.pushLocalFunctionReference,
-          UnlinkedExprOperation.invokeMethodRef
-        ],
-        ints: [5, 0, 0, 0, 2, 0],
-        referenceValidators: [
-          (EntityRef r) => checkTypeRef(r, null, 'foo',
-              expectedKind: ReferenceKind.topLevelFunction)
-        ],
-        forTypeInferenceOnly: true);
-  }
-
-  test_expr_functionExpression_asArgument_multiple() {
-    UnlinkedVariable variable = serializeVariableText('''
-final v = foo(5, () => 42, () => 43);
-foo(a, b, c) {}
-''');
-    assertUnlinkedConst(
-        variable.initializer.bodyExpr, 'foo(5, () => 42, () => 43)',
-        isValidConst: false,
-        operators: [
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.pushLocalFunctionReference,
-          UnlinkedExprOperation.pushLocalFunctionReference,
-          UnlinkedExprOperation.invokeMethodRef
-        ],
-        ints: [5, 0, 0, 0, 1, 0, 3, 0],
-        referenceValidators: [
-          (EntityRef r) => checkTypeRef(r, null, 'foo',
-              expectedKind: ReferenceKind.topLevelFunction)
-        ],
-        forTypeInferenceOnly: true);
-  }
-
-  test_expr_functionExpression_withBlockBody() {
-    UnlinkedVariable variable = serializeVariableText('''
-final v = () { return 42; };
-''');
-    assertUnlinkedConst(variable.initializer.bodyExpr, '() { return 42; }',
-        isValidConst: false,
-        operators: [UnlinkedExprOperation.pushLocalFunctionReference],
-        ints: [0, 0],
-        forTypeInferenceOnly: true);
-  }
-
-  test_expr_functionExpression_withExpressionBody() {
-    UnlinkedVariable variable = serializeVariableText('''
-final v = () => 42;
-''');
-    assertUnlinkedConst(variable.initializer.bodyExpr, '() => 42',
-        isValidConst: false,
-        operators: [UnlinkedExprOperation.pushLocalFunctionReference],
-        ints: [0, 0],
-        forTypeInferenceOnly: true);
-  }
-
-  test_expr_functionExpressionInvocation_withBlockBody() {
-    UnlinkedVariable variable = serializeVariableText('''
-final v = ((a, b) {return 42;})(1, 2);
-''');
-    assertUnlinkedConst(
-        variable.initializer.bodyExpr, '((a, b) {return 42;})(1, 2)',
-        isValidConst: false,
-        operators: [
-          UnlinkedExprOperation.pushLocalFunctionReference,
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.invokeMethod
-        ],
-        ints: [0, 0, 1, 2, 0, 2, 0],
-        strings: ['call'],
-        forTypeInferenceOnly: true);
-  }
-
-  test_expr_functionExpressionInvocation_withExpressionBody() {
-    UnlinkedVariable variable = serializeVariableText('''
-final v = ((a, b) => 42)(1, 2);
-''');
-    assertUnlinkedConst(variable.initializer.bodyExpr, '((a, b) => 42)(1, 2)',
-        isValidConst: false,
-        operators: [
-          UnlinkedExprOperation.pushLocalFunctionReference,
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.invokeMethod
-        ],
-        ints: [0, 0, 1, 2, 0, 2, 0],
-        strings: ['call'],
-        forTypeInferenceOnly: true);
-  }
-
-  test_expr_inClosure() {
-    UnlinkedVariable variable = serializeVariableText('var v = () => 1;');
-    assertUnlinkedConst(variable.initializer.localFunctions[0].bodyExpr, '1',
-        operators: [UnlinkedExprOperation.pushInt],
-        ints: [1],
-        forTypeInferenceOnly: true);
-  }
-
-  test_expr_inClosure_noTypeInferenceNeeded() {
-    // We don't serialize closure body expressions for closures that don't need
-    // to participate in type inference.
-    UnlinkedVariable variable = serializeVariableText('Object v = () => 1;');
-    expect(variable.initializer.localFunctions[0].bodyExpr, isNull);
-  }
-
-  test_expr_inClosure_refersToOuterParam() {
-    UnlinkedVariable variable =
-        serializeVariableText('var v = (x) => (y) => x;');
-    assertUnlinkedConst(
-        variable.initializer.localFunctions[0].localFunctions[0].bodyExpr, 'x',
-        operators: [UnlinkedExprOperation.pushParameter],
-        strings: ['x'],
-        forTypeInferenceOnly: true);
-  }
-
-  test_expr_inClosure_refersToParam() {
-    UnlinkedVariable variable = serializeVariableText('var v = (x) => x;');
-    assertUnlinkedConst(variable.initializer.localFunctions[0].bodyExpr, 'x',
-        operators: [UnlinkedExprOperation.pushParameter],
-        strings: ['x'],
-        forTypeInferenceOnly: true);
-  }
-
-  test_expr_inClosure_refersToParam_methodCall() {
-    UnlinkedVariable variable = serializeVariableText('var v = (x) => x.f();');
-    assertUnlinkedConst(
-        variable.initializer.localFunctions[0].bodyExpr, 'x.f()',
-        operators: [
-          UnlinkedExprOperation.pushParameter,
-          UnlinkedExprOperation.invokeMethod
-        ],
-        strings: ['x', 'f'],
-        ints: [0, 0, 0],
-        forTypeInferenceOnly: true);
-  }
-
-  test_expr_inClosure_refersToParam_methodCall_prefixed() {
-    UnlinkedVariable variable =
-        serializeVariableText('var v = (x) => x.y.f();');
-    assertUnlinkedConst(
-        variable.initializer.localFunctions[0].bodyExpr, 'x.y.f()',
-        operators: [
-          UnlinkedExprOperation.pushParameter,
-          UnlinkedExprOperation.extractProperty,
-          UnlinkedExprOperation.invokeMethod
-        ],
-        strings: ['x', 'y', 'f'],
-        ints: [0, 0, 0],
-        forTypeInferenceOnly: true);
-  }
-
-  test_expr_inClosure_refersToParam_outOfScope() {
-    UnlinkedVariable variable =
-        serializeVariableText('var x; var v = (b) => (b ? (x) => x : x);');
-    assertUnlinkedConst(
-        variable.initializer.localFunctions[0].bodyExpr, '(b ? (x) => x : x)',
-        isValidConst: false,
-        operators: [
-          UnlinkedExprOperation.pushParameter,
-          UnlinkedExprOperation.pushLocalFunctionReference,
-          UnlinkedExprOperation.pushReference,
-          UnlinkedExprOperation.conditional,
-        ],
-        strings: ['b'],
-        ints: [0, 0],
-        referenceValidators: [
-          (EntityRef r) => checkTypeRef(r, null, 'x',
-              expectedKind: ReferenceKind.topLevelPropertyAccessor)
-        ],
-        forTypeInferenceOnly: true);
-  }
-
-  test_expr_inClosure_refersToParam_prefixedIdentifier() {
-    UnlinkedVariable variable = serializeVariableText('var v = (x) => x.y;');
-    assertUnlinkedConst(variable.initializer.localFunctions[0].bodyExpr, 'x.y',
-        operators: [
-          UnlinkedExprOperation.pushParameter,
-          UnlinkedExprOperation.extractProperty
-        ],
-        strings: ['x', 'y'],
-        forTypeInferenceOnly: true);
-  }
-
-  test_expr_inClosure_refersToParam_prefixedIdentifier_assign() {
-    UnlinkedVariable variable =
-        serializeVariableText('var v = (x) => x.y = null;');
-    assertUnlinkedConst(
-        variable.initializer.localFunctions[0].bodyExpr, 'x.y = null',
-        isValidConst: false,
-        operators: [
-          UnlinkedExprOperation.pushNull,
-          UnlinkedExprOperation.pushParameter,
-          UnlinkedExprOperation.assignToProperty
-        ],
-        strings: ['x', 'y'],
-        assignmentOperators: [UnlinkedExprAssignOperator.assign],
-        forTypeInferenceOnly: true);
-  }
-
-  test_expr_inClosure_refersToParam_prefixedPrefixedIdentifier() {
-    UnlinkedVariable variable = serializeVariableText('var v = (x) => x.y.z;');
-    assertUnlinkedConst(
-        variable.initializer.localFunctions[0].bodyExpr, 'x.y.z',
-        operators: [
-          UnlinkedExprOperation.pushParameter,
-          UnlinkedExprOperation.extractProperty,
-          UnlinkedExprOperation.extractProperty
-        ],
-        strings: ['x', 'y', 'z'],
-        forTypeInferenceOnly: true);
-  }
-
-  test_expr_inClosure_refersToParam_prefixedPrefixedIdentifier_assign() {
-    UnlinkedVariable variable =
-        serializeVariableText('var v = (x) => x.y.z = null;');
-    assertUnlinkedConst(
-        variable.initializer.localFunctions[0].bodyExpr, 'x.y.z = null',
-        isValidConst: false,
-        operators: [
-          UnlinkedExprOperation.pushNull,
-          UnlinkedExprOperation.pushParameter,
-          UnlinkedExprOperation.extractProperty,
-          UnlinkedExprOperation.assignToProperty
-        ],
-        strings: ['x', 'y', 'z'],
-        assignmentOperators: [UnlinkedExprAssignOperator.assign],
-        forTypeInferenceOnly: true);
-  }
-
-  test_expr_invalid_typeParameter_asPrefix() {
-    var variable = serializeClassText('''
-class C<T> {
-  final f = T.k;
-}
-''').fields[0];
-    if (containsNonConstExprs) {
-      assertUnlinkedConst(variable.initializer.bodyExpr, 'T.k',
-          isValidConst: false, operators: []);
-    } else {
-      expect(variable.initializer.bodyExpr, isNull);
-    }
-  }
-
-  test_expr_invokeMethod_instance() {
-    UnlinkedVariable variable = serializeVariableText('''
-class C {
-  int m(a, {b, c}) => 42;
-}
-final v = new C().m(1, b: 2, c: 3);
-''');
-    assertUnlinkedConst(
-        variable.initializer.bodyExpr, 'new C().m(1, b: 2, c: 3)',
-        isValidConst: false,
-        operators: [
-          UnlinkedExprOperation.invokeConstructor,
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.invokeMethod,
-        ],
-        ints: [0, 0, 1, 2, 3, 2, 1, 0],
-        strings: ['b', 'c', 'm'],
-        referenceValidators: [
-          (EntityRef r) => checkTypeRef(r, null, 'C',
-              expectedKind: ReferenceKind.classOrEnum)
-        ],
-        forTypeInferenceOnly: true);
-  }
-
-  test_expr_invokeMethod_withTypeParameters() {
-    UnlinkedVariable variable = serializeVariableText('''
-class C {
-  f<T, U>() => null;
-}
-final v = new C().f<int, String>();
-''');
-    assertUnlinkedConst(
-        variable.initializer.bodyExpr, 'new C().f<int, String>()',
-        isValidConst: false,
-        operators: [
-          UnlinkedExprOperation.invokeConstructor,
-          UnlinkedExprOperation.invokeMethod
-        ],
-        ints: [0, 0, 0, 0, 2],
-        strings: ['f'],
-        referenceValidators: [
-          (EntityRef r) => checkTypeRef(r, null, 'C'),
-          (EntityRef r) => checkTypeRef(r, 'dart:core', 'int'),
-          (EntityRef r) => checkTypeRef(r, 'dart:core', 'String')
-        ],
-        forTypeInferenceOnly: true);
-  }
-
-  test_expr_invokeMethodRef_instance() {
-    UnlinkedVariable variable = serializeVariableText('''
-class A {
-  B b;
-}
-class B {
-  C c;
-}
-class C {
-  int m(int a, int b) => a + b;
-}
-A a = new A();
-final v = a.b.c.m(10, 20);
-''');
-    assertUnlinkedConst(variable.initializer.bodyExpr, 'a.b.c.m(10, 20)',
-        operators: [
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.invokeMethodRef,
-        ],
-        ints: [10, 20, 0, 2, 0],
-        strings: [],
-        referenceValidators: [
-          (EntityRef r) => checkTypeRef(r, null, 'm',
-                  expectedKind: ReferenceKind.unresolved,
-                  prefixExpectations: [
-                    new _PrefixExpectation(ReferenceKind.unresolved, 'c'),
-                    new _PrefixExpectation(ReferenceKind.unresolved, 'b'),
-                    new _PrefixExpectation(
-                        ReferenceKind.topLevelPropertyAccessor, 'a')
-                  ])
-        ],
-        forTypeInferenceOnly: true);
-  }
-
-  test_expr_invokeMethodRef_static_importedWithPrefix() {
-    addNamedSource('/a.dart', '''
-class C {
-  static int m() => 42;
-}
-''');
-    UnlinkedVariable variable = serializeVariableText('''
-import 'a.dart' as p;
-final v = p.C.m();
-''');
-    assertUnlinkedConst(variable.initializer.bodyExpr, 'p.C.m()',
-        operators: [
-          UnlinkedExprOperation.invokeMethodRef,
-        ],
-        ints: [0, 0, 0],
-        strings: [],
-        referenceValidators: [
-          (EntityRef r) => checkTypeRef(r, null, 'm',
-                  expectedKind: ReferenceKind.method,
-                  prefixExpectations: [
-                    new _PrefixExpectation(ReferenceKind.classOrEnum, 'C',
-                        absoluteUri: absUri('/a.dart')),
-                    new _PrefixExpectation(ReferenceKind.prefix, 'p')
-                  ])
-        ],
-        forTypeInferenceOnly: true);
-  }
-
-  test_expr_invokeMethodRef_with_reference_arg() {
-    UnlinkedVariable variable = serializeVariableText('''
-f(x) => null;
-final u = null;
-final v = f(u);
-''');
-    assertUnlinkedConst(variable.initializer.bodyExpr, 'f(u)',
-        operators: [
-          UnlinkedExprOperation.pushReference,
-          UnlinkedExprOperation.invokeMethodRef
-        ],
-        ints: [0, 1, 0],
-        referenceValidators: [
-          (EntityRef r) => checkTypeRef(r, null, 'u',
-              expectedKind: ReferenceKind.topLevelPropertyAccessor),
-          (EntityRef r) => checkTypeRef(r, null, 'f',
-              expectedKind: ReferenceKind.topLevelFunction)
-        ],
-        forTypeInferenceOnly: true);
-  }
-
-  test_expr_invokeMethodRef_withTypeParameters() {
-    UnlinkedVariable variable = serializeVariableText('''
-f<T, U>() => null;
-final v = f<int, String>();
-''');
-    assertUnlinkedConst(variable.initializer.bodyExpr, 'f<int, String>()',
-        operators: [UnlinkedExprOperation.invokeMethodRef],
-        ints: [0, 0, 2],
-        referenceValidators: [
-          (EntityRef r) => checkTypeRef(r, null, 'f',
-              expectedKind: ReferenceKind.topLevelFunction,
-              numTypeParameters: 2),
-          (EntityRef r) => checkTypeRef(r, 'dart:core', 'int'),
-          (EntityRef r) => checkTypeRef(r, 'dart:core', 'String')
-        ],
-        forTypeInferenceOnly: true);
-  }
-
-  test_expr_list_for() {
-    UnlinkedVariable variable =
-        serializeVariableText('int i; var v = [for (i = 0; i < 10; i++) i];');
-    assertUnlinkedConst(
-        variable.initializer.bodyExpr, '[for (i = 0; i < 10; i++) i]',
-        isValidConst: false,
-        operators: [
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.assignToRef,
-          UnlinkedExprOperation.pushReference,
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.less,
-          UnlinkedExprOperation.assignToRef,
-          UnlinkedExprOperation.forParts,
-          UnlinkedExprOperation.pushReference,
-          UnlinkedExprOperation.forElement,
-          UnlinkedExprOperation.makeUntypedList
-        ],
-        assignmentOperators: [
-          UnlinkedExprAssignOperator.assign,
-          UnlinkedExprAssignOperator.postfixIncrement
-        ],
-        ints: [
-          0,
-          10,
-          1,
-          1
-        ],
-        referenceValidators: [
-          (EntityRef r) => checkTypeRef(r, null, 'i',
-              expectedKind: ReferenceKind.topLevelPropertyAccessor),
-          (EntityRef r) => checkTypeRef(r, null, 'i',
-              expectedKind: ReferenceKind.topLevelPropertyAccessor),
-          (EntityRef r) => checkTypeRef(r, null, 'i',
-              expectedKind: ReferenceKind.topLevelPropertyAccessor),
-          (EntityRef r) => checkTypeRef(r, null, 'i',
-              expectedKind: ReferenceKind.topLevelPropertyAccessor)
-        ]);
-  }
-
-  test_expr_list_for_each_with_declaration_typed() {
-    UnlinkedVariable variable =
-        serializeVariableText('var v = [for (int i in []) i];');
-    assertUnlinkedConst(variable.initializer.bodyExpr, '[for (int i in []) i]',
-        isValidConst: false,
-        operators: [
-          UnlinkedExprOperation.makeUntypedList,
-          UnlinkedExprOperation.forEachPartsWithTypedDeclaration,
-          UnlinkedExprOperation.pushParameter,
-          UnlinkedExprOperation.forElement,
-          UnlinkedExprOperation.makeUntypedList
-        ],
-        ints: [
-          0,
-          1
-        ],
-        strings: [
-          'i',
-          'i'
-        ],
-        referenceValidators: [
-          (EntityRef r) => checkTypeRef(r, 'dart:core', 'int')
-        ]);
-  }
-
-  test_expr_list_for_each_with_declaration_untyped() {
-    UnlinkedVariable variable =
-        serializeVariableText('var v = [for (var i in []) i];');
-    assertUnlinkedConst(variable.initializer.bodyExpr, '[for (var i in []) i]',
-        isValidConst: false,
-        operators: [
-          UnlinkedExprOperation.makeUntypedList,
-          UnlinkedExprOperation.forEachPartsWithUntypedDeclaration,
-          UnlinkedExprOperation.pushParameter,
-          UnlinkedExprOperation.forElement,
-          UnlinkedExprOperation.makeUntypedList
-        ],
-        ints: [
-          0,
-          1
-        ],
-        strings: [
-          'i',
-          'i'
-        ]);
-  }
-
-  test_expr_list_for_each_with_identifier() {
-    UnlinkedVariable variable =
-        serializeVariableText('int i; var v = [for (i in []) i];');
-    assertUnlinkedConst(variable.initializer.bodyExpr, '[for (i in []) i]',
-        isValidConst: false,
-        operators: [
-          UnlinkedExprOperation.pushReference,
-          UnlinkedExprOperation.makeUntypedList,
-          UnlinkedExprOperation.forEachPartsWithIdentifier,
-          UnlinkedExprOperation.pushReference,
-          UnlinkedExprOperation.forElement,
-          UnlinkedExprOperation.makeUntypedList
-        ],
-        ints: [
-          0,
-          1
-        ],
-        referenceValidators: [
-          (EntityRef r) => checkTypeRef(r, null, 'i',
-              expectedKind: ReferenceKind.topLevelPropertyAccessor),
-          (EntityRef r) => checkTypeRef(r, null, 'i',
-              expectedKind: ReferenceKind.topLevelPropertyAccessor)
-        ]);
-  }
-
-  test_expr_list_for_each_with_identifier_await() {
-    UnlinkedVariable variable =
-        serializeVariableText('int i; var v = [await for (i in []) i];');
-    assertUnlinkedConst(
-        variable.initializer.bodyExpr, '[await for (i in []) i]',
-        isValidConst: false,
-        operators: [
-          UnlinkedExprOperation.pushReference,
-          UnlinkedExprOperation.makeUntypedList,
-          UnlinkedExprOperation.forEachPartsWithIdentifier,
-          UnlinkedExprOperation.pushReference,
-          UnlinkedExprOperation.forElementWithAwait,
-          UnlinkedExprOperation.makeUntypedList
-        ],
-        ints: [
-          0,
-          1
-        ],
-        referenceValidators: [
-          (EntityRef r) => checkTypeRef(r, null, 'i',
-              expectedKind: ReferenceKind.topLevelPropertyAccessor),
-          (EntityRef r) => checkTypeRef(r, null, 'i',
-              expectedKind: ReferenceKind.topLevelPropertyAccessor)
-        ]);
-  }
-
-  test_expr_list_for_empty_condition() {
-    UnlinkedVariable variable =
-        serializeVariableText('int i; var v = [for (i = 0;; i++) i];');
-    assertUnlinkedConst(variable.initializer.bodyExpr, '[for (i = 0;; i++) i]',
-        isValidConst: false,
-        operators: [
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.assignToRef,
-          UnlinkedExprOperation.pushEmptyExpression,
-          UnlinkedExprOperation.assignToRef,
-          UnlinkedExprOperation.forParts,
-          UnlinkedExprOperation.pushReference,
-          UnlinkedExprOperation.forElement,
-          UnlinkedExprOperation.makeUntypedList
-        ],
-        assignmentOperators: [
-          UnlinkedExprAssignOperator.assign,
-          UnlinkedExprAssignOperator.postfixIncrement
-        ],
-        ints: [
-          0,
-          1,
-          1
-        ],
-        referenceValidators: [
-          (EntityRef r) => checkTypeRef(r, null, 'i',
-              expectedKind: ReferenceKind.topLevelPropertyAccessor),
-          (EntityRef r) => checkTypeRef(r, null, 'i',
-              expectedKind: ReferenceKind.topLevelPropertyAccessor),
-          (EntityRef r) => checkTypeRef(r, null, 'i',
-              expectedKind: ReferenceKind.topLevelPropertyAccessor)
-        ]);
-  }
-
-  test_expr_list_for_empty_initializer() {
-    UnlinkedVariable variable =
-        serializeVariableText('int i; var v = [for (; i < 10; i++) i];');
-    assertUnlinkedConst(
-        variable.initializer.bodyExpr, '[for (; i < 10; i++) i]',
-        isValidConst: false,
-        operators: [
-          UnlinkedExprOperation.pushEmptyExpression,
-          UnlinkedExprOperation.pushReference,
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.less,
-          UnlinkedExprOperation.assignToRef,
-          UnlinkedExprOperation.forParts,
-          UnlinkedExprOperation.pushReference,
-          UnlinkedExprOperation.forElement,
-          UnlinkedExprOperation.makeUntypedList
-        ],
-        assignmentOperators: [
-          UnlinkedExprAssignOperator.postfixIncrement
-        ],
-        ints: [
-          10,
-          1,
-          1
-        ],
-        referenceValidators: [
-          (EntityRef r) => checkTypeRef(r, null, 'i',
-              expectedKind: ReferenceKind.topLevelPropertyAccessor),
-          (EntityRef r) => checkTypeRef(r, null, 'i',
-              expectedKind: ReferenceKind.topLevelPropertyAccessor),
-          (EntityRef r) => checkTypeRef(r, null, 'i',
-              expectedKind: ReferenceKind.topLevelPropertyAccessor)
-        ]);
-  }
-
-  test_expr_list_for_two_updaters() {
-    UnlinkedVariable variable = serializeVariableText(
-        'int i; int j; var v = [for (i = 0; i < 10; i++, j++) i];');
-    assertUnlinkedConst(
-        variable.initializer.bodyExpr, '[for (i = 0; i < 10; i++, j++) i]',
-        isValidConst: false,
-        operators: [
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.assignToRef,
-          UnlinkedExprOperation.pushReference,
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.less,
-          UnlinkedExprOperation.assignToRef,
-          UnlinkedExprOperation.assignToRef,
-          UnlinkedExprOperation.forParts,
-          UnlinkedExprOperation.pushReference,
-          UnlinkedExprOperation.forElement,
-          UnlinkedExprOperation.makeUntypedList
-        ],
-        assignmentOperators: [
-          UnlinkedExprAssignOperator.assign,
-          UnlinkedExprAssignOperator.postfixIncrement,
-          UnlinkedExprAssignOperator.postfixIncrement
-        ],
-        ints: [
-          0,
-          10,
-          2,
-          1
-        ],
-        referenceValidators: [
-          (EntityRef r) => checkTypeRef(r, null, 'i',
-              expectedKind: ReferenceKind.topLevelPropertyAccessor),
-          (EntityRef r) => checkTypeRef(r, null, 'i',
-              expectedKind: ReferenceKind.topLevelPropertyAccessor),
-          (EntityRef r) => checkTypeRef(r, null, 'i',
-              expectedKind: ReferenceKind.topLevelPropertyAccessor),
-          (EntityRef r) => checkTypeRef(r, null, 'j',
-              expectedKind: ReferenceKind.topLevelPropertyAccessor),
-          (EntityRef r) => checkTypeRef(r, null, 'i',
-              expectedKind: ReferenceKind.topLevelPropertyAccessor)
-        ]);
-  }
-
-  test_expr_list_for_with_one_declaration_typed() {
-    UnlinkedVariable variable =
-        serializeVariableText('var v = [for (int i = 0; i < 10; i++) i];');
-    assertUnlinkedConst(
-        variable.initializer.bodyExpr, '[for (int i = 0; i < 10; i++) i]',
-        isValidConst: false,
-        operators: [
-          UnlinkedExprOperation.variableDeclarationStart,
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.variableDeclaration,
-          UnlinkedExprOperation.forInitializerDeclarationsTyped,
-          UnlinkedExprOperation.pushParameter,
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.less,
-          UnlinkedExprOperation.assignToParameter,
-          UnlinkedExprOperation.forParts,
-          UnlinkedExprOperation.pushParameter,
-          UnlinkedExprOperation.forElement,
-          UnlinkedExprOperation.makeUntypedList
-        ],
-        assignmentOperators: [
-          UnlinkedExprAssignOperator.postfixIncrement
-        ],
-        ints: [
-          0,
-          0,
-          1,
-          10,
-          1,
-          1
-        ],
-        strings: [
-          'i',
-          'i',
-          'i',
-          'i'
-        ],
-        referenceValidators: [
-          (EntityRef r) => checkTypeRef(r, 'dart:core', 'int')
-        ]);
-  }
-
-  test_expr_list_for_with_one_declaration_untyped() {
-    UnlinkedVariable variable =
-        serializeVariableText('var v = [for (var i = 0; i < 10; i++) i];');
-    assertUnlinkedConst(
-        variable.initializer.bodyExpr, '[for (var i = 0; i < 10; i++) i]',
-        isValidConst: false,
-        operators: [
-          UnlinkedExprOperation.variableDeclarationStart,
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.variableDeclaration,
-          UnlinkedExprOperation.forInitializerDeclarationsUntyped,
-          UnlinkedExprOperation.pushParameter,
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.less,
-          UnlinkedExprOperation.assignToParameter,
-          UnlinkedExprOperation.forParts,
-          UnlinkedExprOperation.pushParameter,
-          UnlinkedExprOperation.forElement,
-          UnlinkedExprOperation.makeUntypedList
-        ],
-        assignmentOperators: [
-          UnlinkedExprAssignOperator.postfixIncrement
-        ],
-        ints: [
-          0,
-          0,
-          1,
-          10,
-          1,
-          1
-        ],
-        strings: [
-          'i',
-          'i',
-          'i',
-          'i'
-        ]);
-  }
-
-  test_expr_list_for_with_two_declarations_untyped() {
-    UnlinkedVariable variable = serializeVariableText(
-        'var v = [for (var i = 0, j = 0; i < 10; i++) i];');
-    assertUnlinkedConst(variable.initializer.bodyExpr,
-        '[for (var i = 0, j = 0; i < 10; i++) i]',
-        isValidConst: false,
-        operators: [
-          UnlinkedExprOperation.variableDeclarationStart,
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.variableDeclaration,
-          UnlinkedExprOperation.variableDeclarationStart,
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.variableDeclaration,
-          UnlinkedExprOperation.forInitializerDeclarationsUntyped,
-          UnlinkedExprOperation.pushParameter,
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.less,
-          UnlinkedExprOperation.assignToParameter,
-          UnlinkedExprOperation.forParts,
-          UnlinkedExprOperation.pushParameter,
-          UnlinkedExprOperation.forElement,
-          UnlinkedExprOperation.makeUntypedList
-        ],
-        assignmentOperators: [
-          UnlinkedExprAssignOperator.postfixIncrement
-        ],
-        ints: [
-          0,
-          0,
-          0,
-          0,
-          2,
-          10,
-          1,
-          1
-        ],
-        strings: [
-          'i',
-          'j',
-          'i',
-          'i',
-          'i'
-        ]);
-  }
-
-  test_expr_list_for_with_uninitialized_declaration_untyped() {
-    UnlinkedVariable variable =
-        serializeVariableText('var v = [for (var i; i < 10; i++) i];');
-    assertUnlinkedConst(
-        variable.initializer.bodyExpr, '[for (var i; i < 10; i++) i]',
-        isValidConst: false,
-        operators: [
-          UnlinkedExprOperation.variableDeclarationStart,
-          UnlinkedExprOperation.pushEmptyExpression,
-          UnlinkedExprOperation.variableDeclaration,
-          UnlinkedExprOperation.forInitializerDeclarationsUntyped,
-          UnlinkedExprOperation.pushParameter,
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.less,
-          UnlinkedExprOperation.assignToParameter,
-          UnlinkedExprOperation.forParts,
-          UnlinkedExprOperation.pushParameter,
-          UnlinkedExprOperation.forElement,
-          UnlinkedExprOperation.makeUntypedList
-        ],
-        assignmentOperators: [
-          UnlinkedExprAssignOperator.postfixIncrement
-        ],
-        ints: [
-          0,
-          1,
-          10,
-          1,
-          1
-        ],
-        strings: [
-          'i',
-          'i',
-          'i',
-          'i'
-        ]);
-  }
-
-  test_expr_list_for_zero_updaters() {
-    UnlinkedVariable variable =
-        serializeVariableText('int i; var v = [for (i = 0; i < 10;) i];');
-    assertUnlinkedConst(
-        variable.initializer.bodyExpr, '[for (i = 0; i < 10;) i]',
-        isValidConst: false,
-        operators: [
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.assignToRef,
-          UnlinkedExprOperation.pushReference,
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.less,
-          UnlinkedExprOperation.forParts,
-          UnlinkedExprOperation.pushReference,
-          UnlinkedExprOperation.forElement,
-          UnlinkedExprOperation.makeUntypedList
-        ],
-        assignmentOperators: [
-          UnlinkedExprAssignOperator.assign
-        ],
-        ints: [
-          0,
-          10,
-          0,
-          1
-        ],
-        referenceValidators: [
-          (EntityRef r) => checkTypeRef(r, null, 'i',
-              expectedKind: ReferenceKind.topLevelPropertyAccessor),
-          (EntityRef r) => checkTypeRef(r, null, 'i',
-              expectedKind: ReferenceKind.topLevelPropertyAccessor),
-          (EntityRef r) => checkTypeRef(r, null, 'i',
-              expectedKind: ReferenceKind.topLevelPropertyAccessor)
-        ]);
-  }
-
-  test_expr_makeTypedList() {
-    UnlinkedVariable variable =
-        serializeVariableText('var v = <int>[11, 22, 33];');
-    assertUnlinkedConst(variable.initializer.bodyExpr, '<int>[11, 22, 33]',
-        operators: [UnlinkedExprOperation.makeTypedList],
-        ints: [0],
-        referenceValidators: [
-          (EntityRef r) => checkTypeRef(r, 'dart:core', 'int',
-              expectedKind: ReferenceKind.classOrEnum)
-        ],
-        forTypeInferenceOnly: true);
-  }
-
-  test_expr_makeTypedMap() {
-    UnlinkedVariable variable = serializeVariableText(
-        'var v = <int, String>{11: "aaa", 22: "bbb", 33: "ccc"};');
-    assertUnlinkedConst(variable.initializer.bodyExpr,
-        '<int, String>{11: "aaa", 22: "bbb", 33: "ccc"}',
-        operators: [UnlinkedExprOperation.makeTypedMap2],
-        ints: [0],
-        referenceValidators: [
-          (EntityRef r) => checkTypeRef(r, 'dart:core', 'int',
-              expectedKind: ReferenceKind.classOrEnum),
-          (EntityRef r) => checkTypeRef(r, 'dart:core', 'String',
-              expectedKind: ReferenceKind.classOrEnum)
-        ],
-        forTypeInferenceOnly: true);
-  }
-
-  test_expr_makeTypedSet() {
-    UnlinkedVariable variable =
-        serializeVariableText('var v = <int>{11, 22, 33};');
-    assertUnlinkedConst(variable.initializer.bodyExpr, '<int>{11, 22, 33}',
-        operators: [UnlinkedExprOperation.makeTypedSet],
-        ints: [0],
-        referenceValidators: [
-          (EntityRef r) => checkTypeRef(r, 'dart:core', 'int',
-              expectedKind: ReferenceKind.classOrEnum)
-        ],
-        forTypeInferenceOnly: true);
-  }
-
-  test_expr_makeUntypedList() {
-    UnlinkedVariable variable = serializeVariableText('var v = [11, 22, 33];');
-    assertUnlinkedConst(variable.initializer.bodyExpr, '[11, 22, 33]',
-        operators: [
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.makeUntypedList
-        ],
-        ints: [11, 22, 33, 3],
-        forTypeInferenceOnly: true);
-  }
-
-  test_expr_makeUntypedMap() {
-    UnlinkedVariable variable =
-        serializeVariableText('var v = {11: "aaa", 22: "bbb", 33: "ccc"};');
-    assertUnlinkedConst(
-        variable.initializer.bodyExpr, '{11: "aaa", 22: "bbb", 33: "ccc"}',
-        operators: [
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.pushString,
-          UnlinkedExprOperation.makeMapLiteralEntry,
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.pushString,
-          UnlinkedExprOperation.makeMapLiteralEntry,
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.pushString,
-          UnlinkedExprOperation.makeMapLiteralEntry,
-          UnlinkedExprOperation.makeUntypedSetOrMap
-        ],
-        ints: [11, 22, 33, 3],
-        strings: ['aaa', 'bbb', 'ccc'],
-        forTypeInferenceOnly: true);
-  }
-
-  test_expr_makeUntypedSet() {
-    UnlinkedVariable variable = serializeVariableText('var v = {11, 22, 33};');
-    assertUnlinkedConst(variable.initializer.bodyExpr, '{11, 22, 33}',
-        operators: [
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.makeUntypedSetOrMap
-        ],
-        ints: [11, 22, 33, 3],
-        forTypeInferenceOnly: true);
-  }
-
-  test_expr_map_for() {
-    UnlinkedVariable variable = serializeVariableText(
-        'int i; var v = {1: 2, for (i = 0; i < 10; i++) i: i};');
-    assertUnlinkedConst(
-        variable.initializer.bodyExpr, '{1: 2, for (i = 0; i < 10; i++) i: i}',
-        isValidConst: false,
-        operators: [
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.makeMapLiteralEntry,
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.assignToRef,
-          UnlinkedExprOperation.pushReference,
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.less,
-          UnlinkedExprOperation.assignToRef,
-          UnlinkedExprOperation.forParts,
-          UnlinkedExprOperation.pushReference,
-          UnlinkedExprOperation.pushReference,
-          UnlinkedExprOperation.makeMapLiteralEntry,
-          UnlinkedExprOperation.forElement,
-          UnlinkedExprOperation.makeUntypedSetOrMap
-        ],
-        assignmentOperators: [
-          UnlinkedExprAssignOperator.assign,
-          UnlinkedExprAssignOperator.postfixIncrement
-        ],
-        ints: [
-          1,
-          2,
-          0,
-          10,
-          1,
-          2
-        ],
-        referenceValidators: [
-          (EntityRef r) => checkTypeRef(r, null, 'i',
-              expectedKind: ReferenceKind.topLevelPropertyAccessor),
-          (EntityRef r) => checkTypeRef(r, null, 'i',
-              expectedKind: ReferenceKind.topLevelPropertyAccessor),
-          (EntityRef r) => checkTypeRef(r, null, 'i',
-              expectedKind: ReferenceKind.topLevelPropertyAccessor),
-          (EntityRef r) => checkTypeRef(r, null, 'i',
-              expectedKind: ReferenceKind.topLevelPropertyAccessor),
-          (EntityRef r) => checkTypeRef(r, null, 'i',
-              expectedKind: ReferenceKind.topLevelPropertyAccessor)
-        ]);
-  }
-
-  test_expr_set_for() {
-    UnlinkedVariable variable = serializeVariableText(
-        'int i; var v = {1, for (i = 0; i < 10; i++) i};');
-    assertUnlinkedConst(
-        variable.initializer.bodyExpr, '{1, for (i = 0; i < 10; i++) i}',
-        isValidConst: false,
-        operators: [
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.assignToRef,
-          UnlinkedExprOperation.pushReference,
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.less,
-          UnlinkedExprOperation.assignToRef,
-          UnlinkedExprOperation.forParts,
-          UnlinkedExprOperation.pushReference,
-          UnlinkedExprOperation.forElement,
-          UnlinkedExprOperation.makeUntypedSetOrMap
-        ],
-        assignmentOperators: [
-          UnlinkedExprAssignOperator.assign,
-          UnlinkedExprAssignOperator.postfixIncrement
-        ],
-        ints: [
-          1,
-          0,
-          10,
-          1,
-          2
-        ],
-        referenceValidators: [
-          (EntityRef r) => checkTypeRef(r, null, 'i',
-              expectedKind: ReferenceKind.topLevelPropertyAccessor),
-          (EntityRef r) => checkTypeRef(r, null, 'i',
-              expectedKind: ReferenceKind.topLevelPropertyAccessor),
-          (EntityRef r) => checkTypeRef(r, null, 'i',
-              expectedKind: ReferenceKind.topLevelPropertyAccessor),
-          (EntityRef r) => checkTypeRef(r, null, 'i',
-              expectedKind: ReferenceKind.topLevelPropertyAccessor)
-        ]);
-  }
-
-  test_expr_super() {
-    UnlinkedVariable variable = serializeVariableText('''
-final v = super;
-''');
-    assertUnlinkedConst(variable.initializer.bodyExpr, 'super',
-        operators: [
-          UnlinkedExprOperation.pushSuper,
-        ],
-        forTypeInferenceOnly: true);
-  }
-
-  test_expr_this() {
-    UnlinkedVariable variable = serializeVariableText('''
-final v = this;
-''');
-    assertUnlinkedConst(variable.initializer.bodyExpr, 'this',
-        operators: [
-          UnlinkedExprOperation.pushThis,
-        ],
-        forTypeInferenceOnly: true);
-  }
-
-  test_expr_throwException() {
-    UnlinkedVariable variable = serializeVariableText('''
-final v = throw 1 + 2;
-''');
-    assertUnlinkedConst(variable.initializer.bodyExpr, 'throw 1 + 2',
-        isValidConst: false,
-        operators: [
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.add,
-          UnlinkedExprOperation.throwException,
-        ],
-        ints: [1, 2],
-        forTypeInferenceOnly: true);
-  }
-
-  test_expr_typeCast() {
-    UnlinkedVariable variable = serializeVariableText('''
-final v = 42 as num;
-''');
-    assertUnlinkedConst(variable.initializer.bodyExpr, '42 as num',
-        isValidConst: false,
-        operators: [
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.typeCast,
-        ],
-        ints: [42],
-        referenceValidators: [
-          (EntityRef r) => checkTypeRef(r, 'dart:core', 'num',
-              expectedKind: ReferenceKind.classOrEnum)
-        ],
-        forTypeInferenceOnly: true);
-  }
-
-  test_expr_typeCheck() {
-    UnlinkedVariable variable = serializeVariableText('''
-final v = 42 is num;
-''');
-    assertUnlinkedConst(variable.initializer.bodyExpr, '42 is num',
-        isValidConst: false,
-        operators: [
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.typeCheck,
-        ],
-        ints: [42],
-        referenceValidators: [
-          (EntityRef r) => checkTypeRef(r, 'dart:core', 'num',
-              expectedKind: ReferenceKind.classOrEnum)
-        ],
-        forTypeInferenceOnly: true);
-  }
-
-  test_field() {
-    UnlinkedClass cls = serializeClassText('class C { int i; }');
-    UnlinkedVariable variable = findVariable('i', variables: cls.fields);
-    expect(variable, isNotNull);
-    expect(variable.isConst, isFalse);
-    expect(variable.isLate, isFalse);
-    expect(variable.isStatic, isFalse);
-    expect(variable.isFinal, isFalse);
-    expect(variable.initializer, isNull);
-    expect(variable.inheritsCovariantSlot, isNot(0));
-    expect(findExecutable('i', executables: cls.executables), isNull);
-    expect(findExecutable('i=', executables: cls.executables), isNull);
-    expect(unlinkedUnits[0].publicNamespace.names, hasLength(1));
-    expect(unlinkedUnits[0].publicNamespace.names[0].name, 'C');
-    expect(unlinkedUnits[0].publicNamespace.names[0].members, isEmpty);
-  }
-
-  test_field_const() {
-    UnlinkedVariable variable =
-        serializeClassText('class C { static const int i = 0; }').fields[0];
-    expect(variable.isConst, isTrue);
-    expect(variable.inheritsCovariantSlot, 0);
-    assertUnlinkedConst(variable.initializer.bodyExpr, '0',
-        operators: [UnlinkedExprOperation.pushInt], ints: [0]);
-  }
-
-  test_field_documented() {
-    String text = '''
-class C {
-  /**
-   * Docs
-   */
-  var v;
-}''';
-    UnlinkedVariable variable = serializeClassText(text).fields[0];
-    expect(variable.documentationComment, isNotNull);
-    checkDocumentationComment(variable.documentationComment, text);
-  }
-
-  test_field_final_notConstExpr() {
-    UnlinkedVariable variable = serializeClassText(r'''
-class C {
-  final f = 1 + m();
-  static int m() => 42;
-}''').fields[0];
-    expect(variable.isFinal, isTrue);
-    if (containsNonConstExprs) {
-      assertUnlinkedConst(variable.initializer.bodyExpr, '1 + m()', operators: [
-        UnlinkedExprOperation.pushInt,
-        UnlinkedExprOperation.invokeMethodRef,
-        UnlinkedExprOperation.add,
-      ], ints: [
-        1,
-        0,
-        0,
-        0
-      ], strings: [], referenceValidators: [
-        (EntityRef r) => checkTypeRef(r, null, 'm',
-                expectedKind: ReferenceKind.method,
-                prefixExpectations: [
-                  new _PrefixExpectation(ReferenceKind.classOrEnum, 'C')
-                ])
-      ]);
-    } else {
-      expect(variable.initializer.bodyExpr, isNull);
-    }
-  }
-
-  test_field_final_typeParameter() {
-    UnlinkedVariable variable = serializeClassText(r'''
-class C<T> {
-  final f = <T>[];
-}''').fields[0];
-    expect(variable.isFinal, isTrue);
-    if (containsNonConstExprs) {
-      assertUnlinkedConst(variable.initializer.bodyExpr, '<T>[]',
-          operators: [UnlinkedExprOperation.makeTypedList],
-          ints: [0],
-          referenceValidators: [(EntityRef r) => checkParamTypeRef(r, 1)]);
-    } else {
-      expect(variable.initializer.bodyExpr, isNull);
-    }
-  }
-
-  test_field_formal_param_inferred_type_explicit() {
-    UnlinkedClass cls = serializeClassText(
-        'class C extends D { var v; C(int this.v); }'
-        ' abstract class D { num get v; }',
-        className: 'C');
-    checkInferredTypeSlot(cls.fields[0].inferredTypeSlot, 'dart:core', 'num');
-    expect(cls.executables[0].kind, UnlinkedExecutableKind.constructor);
-    expect(cls.executables[0].parameters[0].inferredTypeSlot, 0);
-  }
-
-  test_field_formal_param_inferred_type_implicit() {
-    // Both the field `v` and the constructor argument `this.v` will have their
-    // type inferred by strong mode.  But only the field should have its
-    // inferred type stored in the summary, since the standard rules for field
-    // formal parameters will take care of the rest (they implicitly inherit
-    // the type of the associated field).
-    UnlinkedClass cls = serializeClassText(
-        'class C extends D { var v; C(this.v); }'
-        ' abstract class D { int get v; }',
-        className: 'C');
-    checkInferredTypeSlot(cls.fields[0].inferredTypeSlot, 'dart:core', 'int');
-    expect(cls.executables[0].kind, UnlinkedExecutableKind.constructor);
-    expect(cls.executables[0].parameters[0].inferredTypeSlot, 0);
-  }
-
-  test_field_inferred_type_nonstatic_explicit_initialized() {
-    UnlinkedVariable v = serializeClassText('class C { num v = 0; }').fields[0];
-    expect(v.inferredTypeSlot, 0);
-  }
-
-  test_field_inferred_type_nonstatic_explicit_uninitialized() {
-    UnlinkedVariable v = serializeClassText(
-            'class C extends D { num v; } abstract class D { int get v; }',
-            className: 'C',
-            allowErrors: true)
-        .fields[0];
-    expect(v.inferredTypeSlot, 0);
-  }
-
-  test_field_inferred_type_nonstatic_implicit_initialized() {
-    UnlinkedVariable v = serializeClassText('class C { var v = 0; }').fields[0];
-    checkInferredTypeSlot(v.inferredTypeSlot, 'dart:core', 'int');
-  }
-
-  test_field_inferred_type_nonstatic_implicit_uninitialized() {
-    UnlinkedVariable v = serializeClassText(
-            'class C extends D { var v; } abstract class D { int get v; }',
-            className: 'C')
-        .fields[0];
-    checkInferredTypeSlot(v.inferredTypeSlot, 'dart:core', 'int');
-  }
-
-  test_field_inferred_type_static_explicit_initialized() {
-    UnlinkedVariable v =
-        serializeClassText('class C { static int v = 0; }').fields[0];
-    expect(v.inferredTypeSlot, 0);
-  }
-
-  test_field_inferred_type_static_implicit_initialized() {
-    UnlinkedVariable v =
-        serializeClassText('class C { static var v = 0; }').fields[0];
-    checkInferredTypeSlot(v.inferredTypeSlot, 'dart:core', 'int');
-  }
-
-  test_field_inferred_type_static_implicit_uninitialized() {
-    UnlinkedVariable v =
-        serializeClassText('class C { static var v; }').fields[0];
-    expect(v.inferredTypeSlot, 0);
-  }
-
-  test_field_initializer_constConstructor_typed() {
-    UnlinkedVariable variable = serializeClassText('''
-class C {
-  int x = 0;
-  const C();
-}
-''').fields[0];
-    expect(variable.initializer.bodyExpr, isNull);
-    expect(variable.inheritsCovariantSlot, isNot(0));
-  }
-
-  test_field_initializer_final_constConstructor_typed() {
-    UnlinkedVariable variable = serializeClassText('''
-class C {
-  final int x = 0;
-  const C();
-}
-''').fields[0];
-    expect(variable.initializer.bodyExpr, isNotNull);
-    expect(variable.inheritsCovariantSlot, 0);
-  }
-
-  test_field_initializer_final_constConstructor_untyped() {
-    UnlinkedVariable variable = serializeClassText('''
-class C {
-  final x = 0;
-  const C();
-}
-''').fields[0];
-    expect(variable.initializer.bodyExpr, isNotNull);
-    expect(variable.inheritsCovariantSlot, 0);
-  }
-
-  test_field_initializer_final_typed() {
-    UnlinkedVariable variable =
-        serializeClassText('class C { final int x = 0; }').fields[0];
-    expect(variable.initializer.bodyExpr, isNull);
-    expect(variable.inheritsCovariantSlot, 0);
-  }
-
-  test_field_initializer_final_untyped() {
-    UnlinkedVariable variable =
-        serializeClassText('class C { final x = 0; }').fields[0];
-    if (containsNonConstExprs) {
-      expect(variable.initializer.bodyExpr, isNotNull);
-    } else {
-      expect(variable.initializer.bodyExpr, isNull);
-    }
-    expect(variable.inheritsCovariantSlot, 0);
-  }
-
-  test_field_initializer_static_constConstructor_typed() {
-    UnlinkedVariable variable = serializeClassText('''
-class C {
-  static int x = 0;
-  const C();
-}
-''').fields[0];
-    expect(variable.initializer.bodyExpr, isNull);
-    expect(variable.inheritsCovariantSlot, 0);
-  }
-
-  test_field_initializer_static_constConstructor_untyped() {
-    UnlinkedVariable variable = serializeClassText('''
-class C {
-  static var x = 0;
-  const C();
-}
-''').fields[0];
-    if (containsNonConstExprs) {
-      expect(variable.initializer.bodyExpr, isNotNull);
-    } else {
-      expect(variable.initializer.bodyExpr, isNull);
-    }
-    expect(variable.inheritsCovariantSlot, 0);
-  }
-
-  test_field_initializer_static_final_constConstructor_typed() {
-    UnlinkedVariable variable = serializeClassText('''
-class C {
-  static final int x = 0;
-  const C();
-}
-''').fields[0];
-    expect(variable.initializer.bodyExpr, isNull);
-    expect(variable.inheritsCovariantSlot, 0);
-  }
-
-  test_field_initializer_static_final_constConstructor_untyped() {
-    UnlinkedVariable variable = serializeClassText('''
-class C {
-  static final x = 0;
-  const C();
-}
-''').fields[0];
-    if (containsNonConstExprs) {
-      expect(variable.initializer.bodyExpr, isNotNull);
-    } else {
-      expect(variable.initializer.bodyExpr, isNull);
-    }
-    expect(variable.inheritsCovariantSlot, 0);
-  }
-
-  test_field_initializer_typed() {
-    UnlinkedVariable variable =
-        serializeClassText('class C { int x = 0; }').fields[0];
-    expect(variable.initializer.bodyExpr, isNull);
-    expect(variable.inheritsCovariantSlot, isNot(0));
-  }
-
-  test_field_initializer_untyped() {
-    UnlinkedVariable variable =
-        serializeClassText('class C { var x = 0; }').fields[0];
-    if (containsNonConstExprs) {
-      expect(variable.initializer.bodyExpr, isNotNull);
-    } else {
-      expect(variable.initializer.bodyExpr, isNull);
-    }
-    expect(variable.inheritsCovariantSlot, isNot(0));
-  }
-
-  test_field_late() {
-    featureSet = enableNnbd;
-    UnlinkedClass cls = serializeClassText('class C { late int i; }');
-    UnlinkedVariable variable = findVariable('i', variables: cls.fields);
-    expect(variable, isNotNull);
-    expect(variable.isConst, isFalse);
-    expect(variable.isLate, isTrue);
-    expect(variable.isStatic, isFalse);
-    expect(variable.isFinal, isFalse);
-    expect(variable.initializer, isNull);
-    expect(variable.inheritsCovariantSlot, isNot(0));
-    expect(findExecutable('i', executables: cls.executables), isNull);
-    expect(findExecutable('i=', executables: cls.executables), isNull);
-    expect(unlinkedUnits[0].publicNamespace.names, hasLength(1));
-    expect(unlinkedUnits[0].publicNamespace.names[0].name, 'C');
-    expect(unlinkedUnits[0].publicNamespace.names[0].members, isEmpty);
-  }
-
-  test_field_static() {
-    UnlinkedVariable variable =
-        serializeClassText('class C { static int i; }').fields[0];
-    expect(variable.isLate, isFalse);
-    expect(variable.isStatic, isTrue);
-    expect(variable.initializer, isNull);
-    expect(variable.inheritsCovariantSlot, 0);
-    expect(unlinkedUnits[0].publicNamespace.names, hasLength(1));
-    expect(unlinkedUnits[0].publicNamespace.names[0].name, 'C');
-    expect(unlinkedUnits[0].publicNamespace.names[0].members, hasLength(1));
-    expect(unlinkedUnits[0].publicNamespace.names[0].members[0].name, 'i');
-    expect(unlinkedUnits[0].publicNamespace.names[0].members[0].kind,
-        ReferenceKind.propertyAccessor);
-    expect(
-        unlinkedUnits[0].publicNamespace.names[0].members[0].numTypeParameters,
-        0);
-    expect(
-        unlinkedUnits[0].publicNamespace.names[0].members[0].members, isEmpty);
-  }
-
-  test_field_static_final() {
-    UnlinkedVariable variable =
-        serializeClassText('class C { static final int i = 0; }').fields[0];
-    expect(variable.isLate, isFalse);
-    expect(variable.isStatic, isTrue);
-    expect(variable.isFinal, isTrue);
-    expect(variable.initializer.bodyExpr, isNull);
-    expect(variable.inheritsCovariantSlot, 0);
-  }
-
-  test_field_static_final_late() {
-    featureSet = enableNnbd;
-    UnlinkedVariable variable =
-        serializeClassText('class C { static late final int i = 0; }')
-            .fields[0];
-    expect(variable.isLate, isTrue);
-    expect(variable.isStatic, isTrue);
-    expect(variable.isFinal, isTrue);
-    expect(variable.initializer.bodyExpr, isNull);
-    expect(variable.inheritsCovariantSlot, 0);
-  }
-
-  test_field_static_final_untyped() {
-    UnlinkedVariable variable =
-        serializeClassText('class C { static final x = 0; }').fields[0];
-    if (containsNonConstExprs) {
-      expect(variable.initializer.bodyExpr, isNotNull);
-    } else {
-      expect(variable.initializer.bodyExpr, isNull);
-    }
-    expect(variable.inheritsCovariantSlot, 0);
-  }
-
-  test_field_static_late() {
-    featureSet = enableNnbd;
-    UnlinkedVariable variable =
-        serializeClassText('class C { static late int i; }').fields[0];
-    expect(variable.isLate, isTrue);
-    expect(variable.isStatic, isTrue);
-    expect(variable.initializer, isNull);
-    expect(variable.inheritsCovariantSlot, 0);
-    expect(unlinkedUnits[0].publicNamespace.names, hasLength(1));
-    expect(unlinkedUnits[0].publicNamespace.names[0].name, 'C');
-    expect(unlinkedUnits[0].publicNamespace.names[0].members, hasLength(1));
-    expect(unlinkedUnits[0].publicNamespace.names[0].members[0].name, 'i');
-    expect(unlinkedUnits[0].publicNamespace.names[0].members[0].kind,
-        ReferenceKind.propertyAccessor);
-    expect(
-        unlinkedUnits[0].publicNamespace.names[0].members[0].numTypeParameters,
-        0);
-    expect(
-        unlinkedUnits[0].publicNamespace.names[0].members[0].members, isEmpty);
-  }
-
-  test_fully_linked_references_follow_other_references() {
-    if (skipFullyLinkedData) {
-      return;
-    }
-    serializeLibraryText('final x = 0; String y;');
-    checkLinkedTypeSlot(
-        unlinkedUnits[0].variables[0].inferredTypeSlot, 'dart:core', 'int');
-    checkTypeRef(unlinkedUnits[0].variables[1].type, 'dart:core', 'String');
-    // Even though the definition of y follows the definition of x, the linked
-    // type reference for x should use a higher numbered reference than the
-    // unlinked type reference for y.
-    EntityRef propagatedType =
-        getTypeRefForSlot(unlinkedUnits[0].variables[0].inferredTypeSlot);
-    expect(unlinkedUnits[0].variables[1].type.reference,
-        lessThan(propagatedType.reference));
-  }
-
-  test_function_documented() {
-    String text = '''
-// Extra comment so doc comment offset != 0
-/**
- * Docs
- */
-f() {}''';
-    UnlinkedExecutable executable = serializeExecutableText(text);
-    expect(executable.documentationComment, isNotNull);
-    checkDocumentationComment(executable.documentationComment, text);
-  }
-
-  test_function_inferred_type_implicit_param() {
-    UnlinkedExecutable f = serializeExecutableText('void f(value) {}');
-    expect(f.parameters[0].inferredTypeSlot, 0);
-  }
-
-  test_function_inferred_type_implicit_return() {
-    UnlinkedExecutable f = serializeExecutableText('f() => null;');
-    expect(f.inferredReturnTypeSlot, 0);
-  }
-
-  test_function_type_nullability_suffix_none() {
-    featureSet = enableNnbd;
-    EntityRef typeRef = serializeTypeText('void Function()');
-    expect(typeRef.entityKind, EntityRefKind.genericFunctionType);
-    expect(typeRef.nullabilitySuffix, EntityRefNullabilitySuffix.none);
-  }
-
-  test_function_type_nullability_suffix_question() {
-    featureSet = enableNnbd;
-    EntityRef typeRef = serializeTypeText('void Function()?');
-    expect(typeRef.entityKind, EntityRefKind.genericFunctionType);
-    expect(typeRef.nullabilitySuffix, EntityRefNullabilitySuffix.question);
-  }
-
-  test_function_type_nullability_suffix_star() {
-    featureSet = disableNnbd;
-    EntityRef typeRef = serializeTypeText('void Function()');
-    expect(typeRef.entityKind, EntityRefKind.genericFunctionType);
-    expect(
-        typeRef.nullabilitySuffix, EntityRefNullabilitySuffix.starOrIrrelevant);
-  }
-
-  test_generic_method_in_generic_class() {
-    UnlinkedClass cls = serializeClassText(
-        'class C<T, U> { void m<V, W>(T t, U u, V v, W w) {} }');
-    List<UnlinkedParam> params = cls.executables[0].parameters;
-    checkParamTypeRef(params[0].type, 4);
-    checkParamTypeRef(params[1].type, 3);
-    checkParamTypeRef(params[2].type, 2);
-    checkParamTypeRef(params[3].type, 1);
-  }
-
-  test_getter_documented() {
-    String text = '''
-// Extra comment so doc comment offset != 0
-/**
- * Docs
- */
-get f => null;''';
-    UnlinkedExecutable executable = serializeExecutableText(text);
-    expect(executable.documentationComment, isNotNull);
-    checkDocumentationComment(executable.documentationComment, text);
-  }
-
-  test_getter_inferred_type_nonstatic_explicit_return() {
-    UnlinkedExecutable f = serializeClassText(
-            'class C extends D { num get f => null; }'
-            ' abstract class D { int get f; }',
-            className: 'C',
-            allowErrors: true)
-        .executables[0];
-    expect(f.inferredReturnTypeSlot, 0);
-  }
-
-  test_getter_inferred_type_nonstatic_implicit_return() {
-    UnlinkedExecutable f = serializeClassText(
-            'class C extends D { get f => null; } abstract class D { int get f; }',
-            className: 'C')
-        .executables[0];
-    checkInferredTypeSlot(f.inferredReturnTypeSlot, 'dart:core', 'int');
-  }
-
-  test_getter_inferred_type_static_implicit_return() {
-    UnlinkedExecutable f = serializeClassText(
-            'class C extends D { static get f => null; }'
-            ' class D { static int get f => null; }',
-            className: 'C')
-        .executables[0];
-    expect(f.inferredReturnTypeSlot, 0);
-  }
-
-  test_implicit_dependencies_follow_other_dependencies() {
-    if (skipFullyLinkedData) {
-      return;
-    }
-    addNamedSource('/a.dart', 'import "b.dart"; class C {} D f() => null;');
-    addNamedSource('/b.dart', 'class D {}');
-    serializeLibraryText('import "a.dart"; final x = f(); C y;');
-    // The dependency on b.dart is implicit, so it should be placed at the end
-    // of the dependency list, after a.dart, even though the code that refers
-    // to b.dart comes before the code that refers to a.dart.
-    int aDep = checkHasDependency(absUri('/a.dart'), fullyLinked: false);
-    int bDep = checkHasDependency(absUri('/b.dart'), fullyLinked: true);
-    expect(aDep, lessThan(bDep));
-  }
-
-  test_import_configurations() {
-    addNamedSource('/foo.dart', 'bar() {}');
-    addNamedSource('/foo_io.dart', 'bar() {}');
-    addNamedSource('/foo_html.dart', 'bar() {}');
-    String libraryText = r'''
-import 'foo.dart'
-  if (dart.library.io) 'foo_io.dart'
-  if (dart.flavor == 'html') 'foo_html.dart';
-''';
-    serializeLibraryText(libraryText);
-    UnlinkedImport imp = unlinkedUnits[0].imports[0];
-    expect(imp.configurations, hasLength(2));
-    {
-      UnlinkedConfiguration configuration = imp.configurations[0];
-      expect(configuration.name, 'dart.library.io');
-      expect(configuration.value, 'true');
-      expect(configuration.uri, 'foo_io.dart');
-    }
-    {
-      UnlinkedConfiguration configuration = imp.configurations[1];
-      expect(configuration.name, 'dart.flavor');
-      expect(configuration.value, 'html');
-      expect(configuration.uri, 'foo_html.dart');
-    }
-  }
-
-  test_import_deferred() {
-    serializeLibraryText(
-        'import "dart:async" deferred as a; main() { print(a.Future); }');
-    expect(unlinkedUnits[0].imports[0].isDeferred, isTrue);
-  }
-
-  test_import_dependency() {
-    serializeLibraryText('import "dart:async"; Future x;');
-    // Second import is the implicit import of dart:core
-    expect(unlinkedUnits[0].imports, hasLength(2));
-    checkDependency(linked.importDependencies[0], 'dart:async');
-  }
-
-  test_import_explicit() {
-    serializeLibraryText('import "dart:core"; int i;');
-    expect(unlinkedUnits[0].imports, hasLength(1));
-    expect(unlinkedUnits[0].imports[0].isImplicit, isFalse);
-  }
-
-  test_import_hide_order() {
-    serializeLibraryText(
-        'import "dart:async" hide Future, Stream; Completer c;');
-    // Second import is the implicit import of dart:core
-    expect(unlinkedUnits[0].imports, hasLength(2));
-    expect(unlinkedUnits[0].imports[0].combinators, hasLength(1));
-    expect(unlinkedUnits[0].imports[0].combinators[0].shows, isEmpty);
-    expect(unlinkedUnits[0].imports[0].combinators[0].hides, hasLength(2));
-    expect(unlinkedUnits[0].imports[0].combinators[0].hides[0], 'Future');
-    expect(unlinkedUnits[0].imports[0].combinators[0].hides[1], 'Stream');
-    expect(unlinkedUnits[0].imports[0].combinators[0].offset, 0);
-    expect(unlinkedUnits[0].imports[0].combinators[0].end, 0);
-  }
-
-  test_import_implicit() {
-    // The implicit import of dart:core is represented in the model.
-    serializeLibraryText('');
-    expect(unlinkedUnits[0].imports, hasLength(1));
-    checkDependency(linked.importDependencies[0], 'dart:core');
-    expect(unlinkedUnits[0].imports[0].uri, isEmpty);
-    expect(unlinkedUnits[0].imports[0].uriOffset, 0);
-    expect(unlinkedUnits[0].imports[0].uriEnd, 0);
-    expect(unlinkedUnits[0].imports[0].prefixReference, 0);
-    expect(unlinkedUnits[0].imports[0].combinators, isEmpty);
-    expect(unlinkedUnits[0].imports[0].isImplicit, isTrue);
-  }
-
-  test_import_missing() {
-    // Unresolved imports are included since this is necessary for proper
-    // dependency tracking.
-    allowMissingFiles = true;
-    serializeLibraryText('import "foo.dart";', allowErrors: true);
-    // Second import is the implicit import of dart:core
-    expect(unlinkedUnits[0].imports, hasLength(2));
-    checkDependency(linked.importDependencies[0], absUri('/foo.dart'));
-  }
-
-  test_import_no_combinators() {
-    serializeLibraryText('import "dart:async"; Future x;');
-    // Second import is the implicit import of dart:core
-    expect(unlinkedUnits[0].imports, hasLength(2));
-    expect(unlinkedUnits[0].imports[0].combinators, isEmpty);
-  }
-
-  test_import_no_flags() {
-    serializeLibraryText('import "dart:async"; Future x;');
-    expect(unlinkedUnits[0].imports[0].isImplicit, isFalse);
-    expect(unlinkedUnits[0].imports[0].isDeferred, isFalse);
-  }
-
-  test_import_non_deferred() {
-    serializeLibraryText(
-        'import "dart:async" as a; main() { print(a.Future); }');
-    expect(unlinkedUnits[0].imports[0].isDeferred, isFalse);
-  }
-
-  test_import_of_file_with_missing_part() {
-    // Other references in foo.dart should be resolved even though foo.dart's
-    // part declaration for bar.dart refers to a non-existent file.
-    allowMissingFiles = true;
-    addNamedSource('/foo.dart', 'part "bar.dart"; class C {}');
-    serializeLibraryText('import "foo.dart"; C x;');
-    checkTypeRef(findVariable('x').type, absUri('/foo.dart'), 'C');
-  }
-
-  test_import_of_missing_export() {
-    // Other references in foo.dart should be resolved even though foo.dart's
-    // re-export of bar.dart refers to a non-existent file.
-    allowMissingFiles = true;
-    addNamedSource('/foo.dart', 'export "bar.dart"; class C {}');
-    serializeLibraryText('import "foo.dart"; C x;');
-    checkTypeRef(findVariable('x').type, absUri('/foo.dart'), 'C');
-  }
-
-  test_import_offset() {
-    String libraryText = '    import "dart:async"; Future x;';
-    serializeLibraryText(libraryText);
-    expect(unlinkedUnits[0].imports[0].offset, libraryText.indexOf('import'));
-    expect(unlinkedUnits[0].imports[0].uriOffset,
-        libraryText.indexOf('"dart:async"'));
-    expect(unlinkedUnits[0].imports[0].uriEnd, libraryText.indexOf('; Future'));
-  }
-
-  test_import_prefix_name() {
-    String libraryText = 'import "dart:async" as a; a.Future x;';
-    serializeLibraryText(libraryText);
-    // Second import is the implicit import of dart:core
-    expect(unlinkedUnits[0].imports, hasLength(2));
-    checkPrefix(unlinkedUnits[0].imports[0].prefixReference, 'a');
-    expect(unlinkedUnits[0].imports[0].prefixOffset, libraryText.indexOf('a;'));
-  }
-
-  test_import_prefix_none() {
-    serializeLibraryText('import "dart:async"; Future x;');
-    // Second import is the implicit import of dart:core
-    expect(unlinkedUnits[0].imports, hasLength(2));
-    expect(unlinkedUnits[0].imports[0].prefixReference, 0);
-  }
-
-  test_import_prefix_not_in_public_namespace() {
-    serializeLibraryText('import "dart:async" as a; a.Future v;');
-    expect(unlinkedUnits[0].publicNamespace.names, hasLength(2));
-    expect(unlinkedUnits[0].publicNamespace.names[0].name, 'v');
-    expect(unlinkedUnits[0].publicNamespace.names[1].name, 'v=');
-  }
-
-  test_import_prefix_reference() {
-    UnlinkedVariable variable =
-        serializeVariableText('import "dart:async" as a; a.Future v;');
-    checkTypeRef(variable.type, 'dart:async', 'Future',
-        expectedPrefix: 'a', numTypeParameters: 1);
-  }
-
-  test_import_prefixes_take_precedence_over_imported_names() {
-    addNamedSource('/a.dart', 'class b {} class A');
-    addNamedSource('/b.dart', 'class Cls {}');
-    addNamedSource('/c.dart', 'class Cls {}');
-    addNamedSource('/d.dart', 'class c {} class D');
-    serializeLibraryText('''
-import 'a.dart';
-import 'b.dart' as b;
-import 'c.dart' as c;
-import 'd.dart';
-A aCls;
-b.Cls bCls;
-c.Cls cCls;
-D dCls;
-''');
-    checkTypeRef(findVariable('aCls').type, absUri('/a.dart'), 'A');
-    checkTypeRef(findVariable('bCls').type, absUri('/b.dart'), 'Cls',
-        expectedPrefix: 'b');
-    checkTypeRef(findVariable('cCls').type, absUri('/c.dart'), 'Cls',
-        expectedPrefix: 'c');
-    checkTypeRef(findVariable('dCls').type, absUri('/d.dart'), 'D');
-  }
-
-  test_import_reference() {
-    UnlinkedVariable variable =
-        serializeVariableText('import "dart:async"; Future v;');
-    checkTypeRef(variable.type, 'dart:async', 'Future', numTypeParameters: 1);
-  }
-
-  test_import_reference_merged_no_prefix() {
-    serializeLibraryText('''
-import "dart:async" show Future;
-import "dart:async" show Stream;
-
-Future f;
-Stream s;
-''');
-    {
-      EntityRef typeRef = findVariable('f').type;
-      checkTypeRef(typeRef, 'dart:async', 'Future', numTypeParameters: 1);
-    }
-    {
-      EntityRef typeRef = findVariable('s').type;
-      checkTypeRef(typeRef, 'dart:async', 'Stream',
-          expectedTargetUnit: 1, numTypeParameters: 1);
-    }
-  }
-
-  test_import_reference_merged_prefixed() {
-    serializeLibraryText('''
-import "dart:async" as a show Future;
-import "dart:async" as a show Stream;
-
-a.Future f;
-a.Stream s;
-''');
-    {
-      EntityRef typeRef = findVariable('f').type;
-      checkTypeRef(typeRef, 'dart:async', 'Future',
-          expectedPrefix: 'a', numTypeParameters: 1);
-    }
-    {
-      EntityRef typeRef = findVariable('s').type;
-      checkTypeRef(typeRef, 'dart:async', 'Stream',
-          expectedTargetUnit: 1, expectedPrefix: 'a', numTypeParameters: 1);
-    }
-  }
-
-  test_import_reference_merged_prefixed_separate_libraries() {
-    addNamedSource('/a.dart', 'class A {}');
-    addNamedSource('/b.dart', 'class B {}');
-    serializeLibraryText('''
-import 'a.dart' as p;
-import 'b.dart' as p;
-
-p.A a;
-p.B b;
-''');
-    checkTypeRef(findVariable('a').type, absUri('/a.dart'), 'A',
-        expectedPrefix: 'p');
-    checkTypeRef(findVariable('b').type, absUri('/b.dart'), 'B',
-        expectedPrefix: 'p');
-  }
-
-  test_import_self() {
-    serializeLibraryText('''
-import 'test.dart' as p;
-class C {}
-class D extends p.C {} // Prevent "unused import" warning
-''');
-    expect(unlinkedUnits[0].imports[0].uri, 'test.dart');
-    checkDependency(linked.importDependencies[0], absUri('/test.dart'));
-    checkTypeRef(
-        unlinkedUnits[0].classes[1].supertype, absUri('/test.dart'), 'C',
-        expectedPrefix: 'p');
-  }
-
-  test_import_show_order() {
-    String libraryText =
-        'import "dart:async" show Future, Stream; Future x; Stream y;';
-    serializeLibraryText(libraryText);
-    // Second import is the implicit import of dart:core
-    expect(unlinkedUnits[0].imports, hasLength(2));
-    expect(unlinkedUnits[0].imports[0].combinators, hasLength(1));
-    expect(unlinkedUnits[0].imports[0].combinators[0].shows, hasLength(2));
-    expect(unlinkedUnits[0].imports[0].combinators[0].hides, isEmpty);
-    expect(unlinkedUnits[0].imports[0].combinators[0].shows[0], 'Future');
-    expect(unlinkedUnits[0].imports[0].combinators[0].shows[1], 'Stream');
-    expect(unlinkedUnits[0].imports[0].combinators[0].offset,
-        libraryText.indexOf('show'));
-    expect(unlinkedUnits[0].imports[0].combinators[0].end,
-        libraryText.indexOf('; Future'));
-  }
-
-  test_import_uri() {
-    String uriString = '"dart:async"';
-    String libraryText = 'import $uriString; Future x;';
-    serializeLibraryText(libraryText);
-    // Second import is the implicit import of dart:core
-    expect(unlinkedUnits[0].imports, hasLength(2));
-    expect(unlinkedUnits[0].imports[0].uri, 'dart:async');
-  }
-
-  test_import_uri_invalid() {
-    String uriString = ':[invalid uri]';
-    String libraryText = 'import "$uriString";';
-    serializeLibraryText(libraryText);
-    // Second import is the implicit import of dart:core
-    expect(unlinkedUnits[0].imports, hasLength(2));
-    expect(unlinkedUnits[0].imports[0].uri, uriString);
-  }
-
-  test_import_uri_nullStringValue() {
-    String libraryText = r'''
-import "${'a'}.dart";
-''';
-    serializeLibraryText(libraryText);
-    // Second import is the implicit import of dart:core
-    expect(unlinkedUnits[0].imports, hasLength(2));
-    expect(unlinkedUnits[0].imports[0].uri, '');
-  }
-
-  test_inferred_function_type_parameter_type_with_unrelated_type_param() {
-    if (skipFullyLinkedData) {
-      return;
-    }
-    UnlinkedClass c = serializeClassText('''
-abstract class B<T> {
-  void f(void g());
-}
-class C<T> extends B<T> {
-  void f(g) {}
-}
-''');
-    expect(c.executables, hasLength(1));
-    UnlinkedExecutable f = c.executables[0];
-    expect(f.parameters, hasLength(1));
-    UnlinkedParam g = f.parameters[0];
-    expect(g.name, 'g');
-    EntityRef typeRef = getTypeRefForSlot(g.inferredTypeSlot);
-
-    // The type that is inferred for C.f's parameter g is "() -> void".
-    // Therefore it has no type arguments. However, the associated element for
-    // that function type is B.f's parameter g, and B has a type parameter, so
-    // the inferred type *may* safely record that T as a type parameter, in
-    // which case this assertion can be altered accordingly.
-    checkTypeRef(typeRef, null, 'f',
-        numTypeArguments: 0, entityKind: EntityRefKind.genericFunctionType);
-  }
-
-  test_inferred_type_keeps_leading_dynamic() {
-    if (skipFullyLinkedData) {
-      return;
-    }
-    UnlinkedClass cls =
-        serializeClassText('class C { final x = <dynamic, int>{}; }');
-    EntityRef type = getTypeRefForSlot(cls.fields[0].inferredTypeSlot);
-    // Check that x has inferred type `Map<dynamic, int>`.
-    checkLinkedTypeRef(type, 'dart:core', 'Map',
-        numTypeParameters: 2, numTypeArguments: 2);
-    checkLinkedTypeRef(type.typeArguments[0], null, 'dynamic');
-    checkLinkedTypeRef(type.typeArguments[1], 'dart:core', 'int');
-  }
-
-  test_inferred_type_reference_shared_prefixed() {
-    if (skipFullyLinkedData) {
-      return;
-    }
-    // Variable `y` has an inferred type of `p.C`.  Verify that the reference
-    // used by the explicit type of `x` is re-used for the inferred type.
-    addNamedSource('/a.dart', 'class C {}');
-    serializeLibraryText('import "a.dart" as p; p.C x; var y = new p.C();');
-    EntityRef xType = findVariable('x').type;
-    EntityRef yType = getTypeRefForSlot(findVariable('y').inferredTypeSlot);
-    expect(yType.reference, xType.reference);
-  }
-
-  test_inferred_type_refers_to_bound_type_param() {
-    if (skipFullyLinkedData) {
-      return;
-    }
-    UnlinkedClass cls = serializeClassText(
-        'class C<T> extends D<int, T> { var v; }'
-        ' abstract class D<U, V> { Map<V, U> get v; }',
-        className: 'C');
-    EntityRef type = getTypeRefForSlot(cls.fields[0].inferredTypeSlot);
-    // Check that v has inferred type Map<T, int>.
-    checkLinkedTypeRef(type, 'dart:core', 'Map',
-        numTypeParameters: 2, numTypeArguments: 2);
-    checkParamTypeRef(type.typeArguments[0], 1);
-    checkLinkedTypeRef(type.typeArguments[1], 'dart:core', 'int');
-  }
-
-  test_inferred_type_refers_to_function_typed_param_of_typedef() {
-    if (skipFullyLinkedData) {
-      return;
-    }
-    UnlinkedVariable v = serializeVariableText('''
-typedef void F(int g(String s));
-F h() => null;
-var v = h();
-''');
-    EntityRef typeRef = getTypeRefForSlot(v.inferredTypeSlot);
-    checkLinkedTypeRef(typeRef, null, 'F', expectedKind: ReferenceKind.typedef);
-    expect(typeRef.implicitFunctionTypeIndices, isEmpty);
-  }
-
-  test_inferred_type_refers_to_function_typed_parameter_type_generic_class() {
-    if (skipFullyLinkedData) {
-      return;
-    }
-    UnlinkedClass cls = serializeClassText(
-        'class C<T, U> extends D<U, int> { void f(int x, g) {} }'
-        ' abstract class D<V, W> { void f(int x, W g(V s)); }',
-        className: 'C');
-    EntityRef type =
-        getTypeRefForSlot(cls.executables[0].parameters[1].inferredTypeSlot);
-    // Check that parameter g's inferred type is the type implied by D.f's 1st
-    // (zero-based) parameter.
-    expect(type.implicitFunctionTypeIndices, isEmpty);
-    expect(type.paramReference, 0);
-    // Note: this *may* legally have two type arguments (V, W), but for the
-    // moment does not in practice, so we assert isEmpty.
-    expect(type.typeArguments, isEmpty);
-    expect(type.entityKind, EntityRefKind.syntheticFunction);
-    expect(type.syntheticParams, hasLength(1));
-    checkParamTypeRef(type.syntheticParams[0].type, 1);
-    checkLinkedTypeRef(type.syntheticReturnType, 'dart:core', 'int');
-  }
-
-  test_inferred_type_refers_to_function_typed_parameter_type_other_lib() {
-    if (skipFullyLinkedData) {
-      return;
-    }
-    addNamedSource('/a.dart', 'import "b.dart"; abstract class D extends E {}');
-    addNamedSource(
-        '/b.dart', 'abstract class E { void f(int x, int g(String s)); }');
-    UnlinkedClass cls = serializeClassText(
-        'import "a.dart"; class C extends D { void f(int x, g) {} }');
-    EntityRef type =
-        getTypeRefForSlot(cls.executables[0].parameters[1].inferredTypeSlot);
-    expect(type.implicitFunctionTypeIndices, isEmpty);
-    expect(type.paramReference, 0);
-    // Note: this *may* legally have two type arguments (V, W), but for the
-    // moment does not in practice, so we assert isEmpty.
-    expect(type.typeArguments, isEmpty);
-    expect(type.entityKind, EntityRefKind.syntheticFunction);
-    expect(type.syntheticParams, hasLength(1));
-    checkLinkedTypeRef(type.syntheticReturnType, 'dart:core', 'int');
-    checkLinkedTypeRef(type.syntheticParams[0].type, 'dart:core', 'String');
-  }
-
-  test_inferred_type_refers_to_method_function_typed_parameter_type() {
-    if (skipFullyLinkedData) {
-      return;
-    }
-    UnlinkedClass cls = serializeClassText(
-        'class C extends D { void f(int x, g) {} }'
-        ' abstract class D { void f(int x, int g(String s)); }',
-        className: 'C');
-    EntityRef type =
-        getTypeRefForSlot(cls.executables[0].parameters[1].inferredTypeSlot);
-
-    expect(type.implicitFunctionTypeIndices, isEmpty);
-    expect(type.paramReference, 0);
-    // Note: this *may* legally have two type arguments (V, W), but for the
-    // moment does not in practice, so we assert isEmpty.
-    expect(type.typeArguments, isEmpty);
-    expect(type.entityKind, EntityRefKind.syntheticFunction);
-    expect(type.syntheticParams, hasLength(1));
-    checkLinkedTypeRef(type.syntheticReturnType, 'dart:core', 'int');
-    checkLinkedTypeRef(type.syntheticParams[0].type, 'dart:core', 'String');
-  }
-
-  test_inferred_type_refers_to_nested_function_typed_param() {
-    if (skipFullyLinkedData) {
-      return;
-    }
-    UnlinkedVariable v = serializeVariableText('''
-dynamic f(void g(int x, void h())) => null;
-T extract<T>(dynamic f2(void g2(int x2, T h2)) => null;
-var v = extract(f);
-''');
-    EntityRef typeRef = getTypeRefForSlot(v.inferredTypeSlot);
-    checkLinkedTypeRef(typeRef, null, 'f',
-        expectedKind: ReferenceKind.topLevelFunction);
-    expect(typeRef.implicitFunctionTypeIndices, [0, 1]);
-  }
-
-  test_inferred_type_refers_to_nested_function_typed_param_named() {
-    if (skipFullyLinkedData) {
-      return;
-    }
-    UnlinkedVariable v = serializeVariableText('''
-dynamic f({void g(int x, void h())}) => null;
-T extract<T>(dynamic f2({void g(int x2, T h2)})) => null;
-var v = extract(f);
-''');
-    EntityRef typeRef = getTypeRefForSlot(v.inferredTypeSlot);
-    checkLinkedTypeRef(typeRef, null, 'f',
-        expectedKind: ReferenceKind.topLevelFunction);
-    expect(typeRef.implicitFunctionTypeIndices, [0, 1]);
-  }
-
-  test_inferred_type_refers_to_setter_function_typed_parameter_type() {
-    if (skipFullyLinkedData) {
-      return;
-    }
-    UnlinkedClass cls = serializeClassText(
-        'class C extends D { void set f(g) {} }'
-        ' abstract class D { void set f(int g(String s)); }',
-        className: 'C');
-    EntityRef type =
-        getTypeRefForSlot(cls.executables[0].parameters[0].inferredTypeSlot);
-    // Check that parameter g's inferred type is the type implied by D.f's 1st
-    // (zero-based) parameter.
-    expect(type.implicitFunctionTypeIndices, [0]);
-    expect(type.paramReference, 0);
-    expect(type.typeArguments, isEmpty);
-    expect(type.reference,
-        greaterThanOrEqualTo(unlinkedUnits[0].references.length));
-    LinkedReference linkedReference =
-        linked.units[0].references[type.reference];
-    expect(linkedReference.dependency, 0);
-    expect(linkedReference.kind, ReferenceKind.propertyAccessor);
-    expect(linkedReference.name, 'f=');
-    expect(linkedReference.numTypeParameters, 0);
-    expect(linkedReference.unit, 0);
-    expect(linkedReference.containingReference, isNot(0));
-    expect(linkedReference.containingReference, lessThan(type.reference));
-    checkReferenceIndex(linkedReference.containingReference, null, 'D');
-  }
-
-  test_inferred_type_skips_trailing_dynamic() {
-    if (skipFullyLinkedData) {
-      return;
-    }
-    UnlinkedClass cls =
-        serializeClassText('class C { final x = <int, dynamic>{}; }');
-    EntityRef type = getTypeRefForSlot(cls.fields[0].inferredTypeSlot);
-    // Check that x has inferred type `Map<int, dynamic>`.
-    checkLinkedTypeRef(type, 'dart:core', 'Map',
-        numTypeParameters: 2, numTypeArguments: 2);
-    checkLinkedTypeRef(type.typeArguments[0], 'dart:core', 'int');
-    checkLinkedDynamicTypeRef(type.typeArguments[1]);
-  }
-
-  test_inferred_type_skips_unnecessary_dynamic() {
-    if (skipFullyLinkedData) {
-      return;
-    }
-    UnlinkedClass cls = serializeClassText('class C { final x = []; }');
-    EntityRef type = getTypeRefForSlot(cls.fields[0].inferredTypeSlot);
-    // Check that x has inferred type `List<dynamic>`.
-    checkLinkedTypeRef(type, 'dart:core', 'List',
-        numTypeParameters: 1, numTypeArguments: 1);
-  }
-
-  test_inferred_type_undefined() {
-    if (skipFullyLinkedData) {
-      return;
-    }
-    UnlinkedVariable v = serializeVariableText('var v = <Undefined>[];');
-    var typeRef = getTypeRefForSlot(v.inferredTypeSlot);
-    checkLinkedTypeRef(typeRef, 'dart:core', 'List',
-        numTypeArguments: 1, numTypeParameters: 1);
-    checkLinkedDynamicTypeRef(typeRef.typeArguments[0]);
-  }
-
-  test_initializer_executable_with_bottom_return_type() {
-    // The synthetic executable for `v` has type `() => Bottom`.
-    UnlinkedVariable variable = serializeVariableText('int v = null;');
-    expect(variable.initializer.returnType, isNull);
-    checkInferredTypeSlot(
-        variable.initializer.inferredReturnTypeSlot, null, 'Never',
-        onlyInStrongMode: false);
-  }
-
-  test_initializer_executable_with_imported_return_type() {
-    addNamedSource('/a.dart', 'class C { D d; } class D {}');
-    // The synthetic executable for `v` has type `() => D`; `D` is defined in
-    // a library that is imported.  Note: `v` is mis-typed as `int` to prevent
-    // type propagation, which would complicate the test.
-    UnlinkedVariable variable = serializeVariableText(
-        'import "a.dart"; int v = new C().d;',
-        allowErrors: true);
-    expect(variable.initializer.returnType, isNull);
-    checkInferredTypeSlot(
-        variable.initializer.inferredReturnTypeSlot, absUri('/a.dart'), 'D',
-        onlyInStrongMode: false);
-    checkHasDependency(absUri('/a.dart'), fullyLinked: false);
-  }
-
-  test_initializer_executable_with_return_type_from_closure() {
-    if (skipFullyLinkedData) {
-      return;
-    }
-    // The synthetic executable for `v` has type `() => () => int`, where the
-    // `() => int` part refers to the closure declared inside the initializer
-    // for v.  Note: `v` is mis-typed as `int` to prevent type propagation,
-    // which would complicate the test.
-    UnlinkedVariable variable =
-        serializeVariableText('int v = () => 0;', allowErrors: true);
-    EntityRef closureType =
-        getTypeRefForSlot(variable.initializer.inferredReturnTypeSlot);
-    checkLinkedTypeRef(closureType, null, '',
-        expectedKind: ReferenceKind.function);
-    int initializerIndex =
-        definingUnit.references[closureType.reference].containingReference;
-    checkReferenceIndex(initializerIndex, null, '',
-        expectedKind: ReferenceKind.function);
-    int variableIndex =
-        definingUnit.references[initializerIndex].containingReference;
-    checkReferenceIndex(variableIndex, null, 'v',
-        expectedKind: ReferenceKind.topLevelPropertyAccessor);
-    expect(definingUnit.references[variableIndex].containingReference, 0);
-  }
-
-  test_initializer_executable_with_return_type_from_closure_field() {
-    if (skipFullyLinkedData) {
-      return;
-    }
-    // The synthetic executable for `v` has type `() => () => int`, where the
-    // `() => int` part refers to the closure declared inside the initializer
-    // for v.  Note: `v` is mis-typed as `int` to prevent type propagation,
-    // which would complicate the test.
-    UnlinkedClass cls = serializeClassText('''
-class C {
-  int v = () => 0;
-}
-''', allowErrors: true);
-    UnlinkedVariable variable = cls.fields[0];
-    EntityRef closureType =
-        getTypeRefForSlot(variable.initializer.inferredReturnTypeSlot);
-    checkLinkedTypeRef(closureType, null, '',
-        expectedKind: ReferenceKind.function);
-    int initializerIndex =
-        definingUnit.references[closureType.reference].containingReference;
-    checkReferenceIndex(initializerIndex, null, '',
-        expectedKind: ReferenceKind.function);
-    int variableIndex =
-        definingUnit.references[initializerIndex].containingReference;
-    checkReferenceIndex(variableIndex, null, 'v',
-        expectedKind: ReferenceKind.propertyAccessor);
-    int classIndex = definingUnit.references[variableIndex].containingReference;
-    checkReferenceIndex(classIndex, null, 'C');
-    expect(definingUnit.references[classIndex].containingReference, 0);
-  }
-
-  test_initializer_executable_with_unimported_return_type() {
-    addNamedSource('/a.dart', 'import "b.dart"; class C { D d; }');
-    addNamedSource('/b.dart', 'class D {}');
-    // The synthetic executable for `v` has type `() => D`; `D` is defined in
-    // a library that is not imported.  Note: `v` is mis-typed as `int` to
-    // prevent type propagation, which would complicate the test.
-    UnlinkedVariable variable = serializeVariableText(
-        'import "a.dart"; int v = new C().d;',
-        allowErrors: true);
-    expect(variable.initializer.returnType, isNull);
-    checkInferredTypeSlot(
-        variable.initializer.inferredReturnTypeSlot, absUri('/b.dart'), 'D',
-        onlyInStrongMode: false);
-    if (!skipFullyLinkedData) {
-      checkHasDependency('b.dart', fullyLinked: true);
-    }
-  }
-
-  test_library_documented() {
-    String text = '''
-// Extra comment so doc comment offset != 0
-/**
- * Docs
- */
-library foo;''';
-    serializeLibraryText(text);
-    expect(unlinkedUnits[0].libraryDocumentationComment, isNotNull);
-    checkDocumentationComment(
-        unlinkedUnits[0].libraryDocumentationComment, text);
-  }
-
-  test_library_name_with_spaces() {
-    String text = 'library foo . bar ;';
-    serializeLibraryText(text);
-    expect(unlinkedUnits[0].libraryName, 'foo.bar');
-    expect(unlinkedUnits[0].libraryNameOffset, text.indexOf('foo . bar'));
-    expect(unlinkedUnits[0].libraryNameLength, 'foo . bar'.length);
-  }
-
-  test_library_named() {
-    String text = 'library foo.bar;';
-    serializeLibraryText(text);
-    expect(unlinkedUnits[0].libraryName, 'foo.bar');
-    expect(unlinkedUnits[0].libraryNameOffset, text.indexOf('foo.bar'));
-    expect(unlinkedUnits[0].libraryNameLength, 'foo.bar'.length);
-  }
-
-  test_library_unnamed() {
-    serializeLibraryText('');
-    expect(unlinkedUnits[0].libraryName, isEmpty);
-    expect(unlinkedUnits[0].libraryNameOffset, 0);
-    expect(unlinkedUnits[0].libraryNameLength, 0);
-  }
-
-  test_library_with_missing_part() {
-    // References to other parts should still be resolved.
-    allowMissingFiles = true;
-    addNamedSource('/bar.dart', 'part of my.lib; class C {}');
-    serializeLibraryText(
-        'library my.lib; part "foo.dart"; part "bar.dart"; C c;',
-        allowErrors: true);
-    checkTypeRef(findVariable('c').type, null, 'C', expectedTargetUnit: 2);
-  }
-
-  test_lineStarts() {
-    String text = '''
-int foo;
-class Test {}
-
-int bar;'''
-        .replaceAll('\r\n', '\n');
-    serializeLibraryText(text);
-    expect(unlinkedUnits[0].lineStarts, [0, 9, 23, 24]);
-  }
-
-  test_linked_reference_reuse() {
-    if (skipFullyLinkedData) {
-      return;
-    }
-    // When the reference for a linked type is the same as an explicitly
-    // referenced type, the explicit reference should be re-used.
-    addNamedSource('/a.dart', 'class C {}');
-    addNamedSource('/b.dart', 'import "a.dart"; C f() => null;');
-    serializeLibraryText(
-        'import "a.dart"; import "b.dart"; C c1; final c2 = f();');
-    int explicitReference = findVariable('c1').type.reference;
-    expect(getTypeRefForSlot(findVariable('c2').inferredTypeSlot).reference,
-        explicitReference);
-  }
-
-  test_linked_type_dependency_reuse() {
-    if (skipFullyLinkedData) {
-      return;
-    }
-    // When the dependency for a linked type is the same as an explicit
-    // dependency, the explicit dependency should be re-used.
-    addNamedSource('/a.dart', 'class C {} class D {}');
-    addNamedSource('/b.dart', 'import "a.dart"; D f() => null;');
-    serializeLibraryText(
-        'import "a.dart"; import "b.dart"; C c; final d = f();');
-    int cReference = findVariable('c').type.reference;
-    int explicitDependency = linked.units[0].references[cReference].dependency;
-    int dReference =
-        getTypeRefForSlot(findVariable('d').inferredTypeSlot).reference;
-    expect(
-        linked.units[0].references[dReference].dependency, explicitDependency);
-  }
-
-  test_local_names_take_precedence_over_imported_names() {
-    addNamedSource('/a.dart', 'class C {} class D {}');
-    serializeLibraryText('''
-import 'a.dart';
-class C {}
-C c;
-D d;''');
-    checkTypeRef(findVariable('c').type, null, 'C');
-    checkTypeRef(findVariable('d').type, absUri('/a.dart'), 'D');
-  }
-
-  test_localNameShadowsImportPrefix() {
-    serializeLibraryText('import "dart:async" as a; class a {}; a x;');
-    checkTypeRef(findVariable('x').type, null, 'a');
-  }
-
-  test_metadata_classDeclaration() {
-    checkAnnotationA(
-        serializeClassText('const a = null; @a class C {}').annotations);
-  }
-
-  test_metadata_classTypeAlias() {
-    checkAnnotationA(serializeClassText(
-            'const a = null; @a class C = D with E; class D {} class E {}',
-            className: 'C')
-        .annotations);
-  }
-
-  test_metadata_constructor_call_named() {
-    UnlinkedClass cls = serializeClassText(
-        'class A { const A.named(); } @A.named() class C {}');
-    expect(cls.annotations, hasLength(1));
-    assertUnlinkedConst(cls.annotations[0], 'A.named()', operators: [
-      UnlinkedExprOperation.invokeConstructor,
-    ], ints: [
-      0,
-      0
-    ], referenceValidators: [
-      (EntityRef r) => checkTypeRef(r, null, 'named',
-              expectedKind: ReferenceKind.constructor,
-              prefixExpectations: [
-                new _PrefixExpectation(ReferenceKind.classOrEnum, 'A')
-              ])
-    ]);
-  }
-
-  test_metadata_constructor_call_named_prefixed() {
-    addNamedSource('/foo.dart', 'class A { const A.named(); }');
-    UnlinkedClass cls = serializeClassText(
-        'import "foo.dart" as foo; @foo.A.named() class C {}');
-    expect(cls.annotations, hasLength(1));
-    assertUnlinkedConst(cls.annotations[0], 'foo.A.named()', operators: [
-      UnlinkedExprOperation.invokeConstructor,
-    ], ints: [
-      0,
-      0
-    ], referenceValidators: [
-      (EntityRef r) => checkTypeRef(r, null, 'named',
-              expectedKind: ReferenceKind.constructor,
-              prefixExpectations: [
-                new _PrefixExpectation(
-                  ReferenceKind.classOrEnum,
-                  'A',
-                  absoluteUri: absUri('/foo.dart'),
-                ),
-                new _PrefixExpectation(ReferenceKind.prefix, 'foo')
-              ])
-    ]);
-  }
-
-  test_metadata_constructor_call_named_prefixed_unresolved_class() {
-    addNamedSource('/foo.dart', '');
-    UnlinkedClass cls = serializeClassText(
-        'import "foo.dart" as foo; @foo.A.named() class C {}',
-        allowErrors: true);
-    expect(cls.annotations, hasLength(1));
-    assertUnlinkedConst(cls.annotations[0], 'foo.A.named()', operators: [
-      UnlinkedExprOperation.invokeConstructor,
-    ], ints: [
-      0,
-      0
-    ], referenceValidators: [
-      (EntityRef r) => checkTypeRef(r, null, 'named',
-              expectedKind: ReferenceKind.unresolved,
-              prefixExpectations: [
-                new _PrefixExpectation(ReferenceKind.unresolved, 'A'),
-                new _PrefixExpectation(ReferenceKind.prefix, 'foo')
-              ])
-    ]);
-  }
-
-  test_metadata_constructor_call_named_prefixed_unresolved_constructor() {
-    addNamedSource('/foo.dart', 'class A {}');
-    UnlinkedClass cls = serializeClassText(
-        'import "foo.dart" as foo; @foo.A.named() class C {}',
-        allowErrors: true);
-    expect(cls.annotations, hasLength(1));
-    assertUnlinkedConst(cls.annotations[0], 'foo.A.named()', operators: [
-      UnlinkedExprOperation.invokeConstructor,
-    ], ints: [
-      0,
-      0
-    ], referenceValidators: [
-      (EntityRef r) => checkTypeRef(r, null, 'named',
-              expectedKind: ReferenceKind.unresolved,
-              prefixExpectations: [
-                new _PrefixExpectation(
-                  ReferenceKind.classOrEnum,
-                  'A',
-                  absoluteUri: absUri('/foo.dart'),
-                ),
-                new _PrefixExpectation(ReferenceKind.prefix, 'foo')
-              ])
-    ]);
-  }
-
-  test_metadata_constructor_call_named_unresolved_class() {
-    UnlinkedClass cls =
-        serializeClassText('@A.named() class C {}', allowErrors: true);
-    expect(cls.annotations, hasLength(1));
-    assertUnlinkedConst(cls.annotations[0], 'A.named()', operators: [
-      UnlinkedExprOperation.invokeConstructor,
-    ], ints: [
-      0,
-      0
-    ], referenceValidators: [
-      (EntityRef r) => checkTypeRef(r, null, 'named',
-              expectedKind: ReferenceKind.unresolved,
-              prefixExpectations: [
-                new _PrefixExpectation(ReferenceKind.unresolved, 'A')
-              ])
-    ]);
-  }
-
-  test_metadata_constructor_call_named_unresolved_constructor() {
-    UnlinkedClass cls = serializeClassText('class A {} @A.named() class C {}',
-        allowErrors: true);
-    expect(cls.annotations, hasLength(1));
-    assertUnlinkedConst(cls.annotations[0], 'A.named()', operators: [
-      UnlinkedExprOperation.invokeConstructor,
-    ], ints: [
-      0,
-      0
-    ], referenceValidators: [
-      (EntityRef r) => checkTypeRef(r, null, 'named',
-              expectedKind: ReferenceKind.unresolved,
-              prefixExpectations: [
-                new _PrefixExpectation(ReferenceKind.classOrEnum, 'A')
-              ])
-    ]);
-  }
-
-  test_metadata_constructor_call_unnamed() {
-    UnlinkedClass cls =
-        serializeClassText('class A { const A(); } @A() class C {}');
-    expect(cls.annotations, hasLength(1));
-    assertUnlinkedConst(cls.annotations[0], 'A()', operators: [
-      UnlinkedExprOperation.invokeConstructor,
-    ], ints: [
-      0,
-      0
-    ], referenceValidators: [
-      (EntityRef r) =>
-          checkTypeRef(r, null, 'A', expectedKind: ReferenceKind.classOrEnum)
-    ]);
-  }
-
-  test_metadata_constructor_call_unnamed_prefixed() {
-    addNamedSource('/foo.dart', 'class A { const A(); }');
-    UnlinkedClass cls =
-        serializeClassText('import "foo.dart" as foo; @foo.A() class C {}');
-    expect(cls.annotations, hasLength(1));
-    assertUnlinkedConst(cls.annotations[0], 'foo.A()', operators: [
-      UnlinkedExprOperation.invokeConstructor,
-    ], ints: [
-      0,
-      0
-    ], referenceValidators: [
-      (EntityRef r) => checkTypeRef(r, absUri('/foo.dart'), 'A',
-          expectedKind: ReferenceKind.classOrEnum, expectedPrefix: 'foo')
-    ]);
-  }
-
-  test_metadata_constructor_call_unnamed_prefixed_unresolved() {
-    addNamedSource('/foo.dart', '');
-    UnlinkedClass cls = serializeClassText(
-        'import "foo.dart" as foo; @foo.A() class C {}',
-        allowErrors: true);
-    expect(cls.annotations, hasLength(1));
-    assertUnlinkedConst(cls.annotations[0], 'foo.A()', operators: [
-      UnlinkedExprOperation.invokeConstructor,
-    ], ints: [
-      0,
-      0
-    ], referenceValidators: [
-      (EntityRef r) => checkTypeRef(r, null, 'A',
-          expectedKind: ReferenceKind.unresolved, expectedPrefix: 'foo')
-    ]);
-  }
-
-  test_metadata_constructor_call_unnamed_unresolved() {
-    UnlinkedClass cls =
-        serializeClassText('@A() class C {}', allowErrors: true);
-    expect(cls.annotations, hasLength(1));
-    assertUnlinkedConst(cls.annotations[0], 'A()', operators: [
-      UnlinkedExprOperation.invokeConstructor,
-    ], ints: [
-      0,
-      0
-    ], referenceValidators: [
-      (EntityRef r) =>
-          checkTypeRef(r, null, 'A', expectedKind: ReferenceKind.unresolved)
-    ]);
-  }
-
-  test_metadata_constructor_call_with_args() {
-    UnlinkedClass cls =
-        serializeClassText('class A { const A(x); } @A(null) class C {}');
-    expect(cls.annotations, hasLength(1));
-    assertUnlinkedConst(cls.annotations[0], 'A(null)', operators: [
-      UnlinkedExprOperation.pushNull,
-      UnlinkedExprOperation.invokeConstructor,
-    ], ints: [
-      0,
-      1
-    ], referenceValidators: [
-      (EntityRef r) =>
-          checkTypeRef(r, null, 'A', expectedKind: ReferenceKind.classOrEnum)
-    ]);
-  }
-
-  test_metadata_constructorDeclaration_named() {
-    checkAnnotationA(
-        serializeClassText('const a = null; class C { @a C.named(); }')
-            .executables[0]
-            .annotations);
-  }
-
-  test_metadata_constructorDeclaration_unnamed() {
-    checkAnnotationA(serializeClassText('const a = null; class C { @a C(); }')
-        .executables[0]
-        .annotations);
-  }
-
-  test_metadata_enumConstantDeclaration() {
-    checkAnnotationA(serializeEnumText('const a = null; enum E { @a v }')
-        .values[0]
-        .annotations);
-  }
-
-  test_metadata_enumDeclaration() {
-    checkAnnotationA(
-        serializeEnumText('const a = null; @a enum E { v }').annotations);
-  }
-
-  test_metadata_exportDirective() {
-    addNamedSource('/foo.dart', '');
-    serializeLibraryText('@a export "foo.dart"; const a = null;');
-    checkAnnotationA(unlinkedUnits[0].exports[0].annotations);
-  }
-
-  test_metadata_fieldDeclaration() {
-    checkAnnotationA(serializeClassText('const a = null; class C { @a int x; }')
-        .fields[0]
-        .annotations);
-  }
-
-  test_metadata_fieldFormalParameter() {
-    checkAnnotationA(
-        serializeClassText('const a = null; class C { var x; C(@a this.x); }')
-            .executables[0]
-            .parameters[0]
-            .annotations);
-  }
-
-  test_metadata_fieldFormalParameter_withDefault() {
-    checkAnnotationA(serializeClassText(
-            'const a = null; class C { var x; C([@a this.x = null]); }')
-        .executables[0]
-        .parameters[0]
-        .annotations);
-  }
-
-  test_metadata_functionDeclaration_function() {
-    checkAnnotationA(
-        serializeExecutableText('const a = null; @a f() {}').annotations);
-  }
-
-  test_metadata_functionDeclaration_getter() {
-    checkAnnotationA(
-        serializeExecutableText('const a = null; @a get f => null;')
-            .annotations);
-  }
-
-  test_metadata_functionDeclaration_setter() {
-    checkAnnotationA(serializeExecutableText(
-            'const a = null; @a set f(value) {}',
-            executableName: 'f=')
-        .annotations);
-  }
-
-  test_metadata_functionTypeAlias() {
-    checkAnnotationA(
-        serializeTypedefText('const a = null; @a typedef F();').annotations);
-  }
-
-  test_metadata_functionTypedFormalParameter() {
-    checkAnnotationA(serializeExecutableText('const a = null; f(@a g()) {}')
-        .parameters[0]
-        .annotations);
-  }
-
-  test_metadata_functionTypedFormalParameter_withDefault() {
-    checkAnnotationA(
-        serializeExecutableText('const a = null; f([@a g() = null]) {}')
-            .parameters[0]
-            .annotations);
-  }
-
-  test_metadata_importDirective() {
-    addNamedSource('/foo.dart', 'const b = null;');
-    serializeLibraryText('@a import "foo.dart"; const a = b;');
-    checkAnnotationA(unlinkedUnits[0].imports[0].annotations);
-  }
-
-  test_metadata_invalid_assignable() {
-    // Verify that the following does not cause an exception to be thrown.
-    serializeLibraryText('@a(-b=""c');
-    expect(unlinkedUnits, hasLength(1));
-    List<UnlinkedVariable> variables = unlinkedUnits[0].variables;
-    if (Parser.useFasta) {
-      // Fasta recovers by appending `)` after `c`
-      expect(variables, isEmpty);
-    } else {
-      expect(variables, hasLength(1));
-      List<UnlinkedExpr> annotations = variables[0].annotations;
-      expect(annotations, hasLength(1));
-      expect(annotations[0].isValidConst, isFalse);
-    }
-  }
-
-  test_metadata_invalid_instanceCreation_argument_super() {
-    List<UnlinkedExpr> annotations = serializeClassText('''
-class A {
-  const A(_);
-}
-
-@A(super)
-class C {}
-''').annotations;
-    expect(annotations, hasLength(1));
-    assertUnlinkedConst(annotations[0], 'A(super)', operators: [
-      UnlinkedExprOperation.pushSuper,
-      UnlinkedExprOperation.invokeConstructor,
-    ], ints: [
-      0,
-      1
-    ], referenceValidators: [
-      (EntityRef r) =>
-          checkTypeRef(r, null, 'A', expectedKind: ReferenceKind.classOrEnum)
-    ]);
-  }
-
-  test_metadata_invalid_instanceCreation_argument_this() {
-    List<UnlinkedExpr> annotations = serializeClassText('''
-class A {
-  const A(_);
-}
-
-@A(this)
-class C {}
-''').annotations;
-    expect(annotations, hasLength(1));
-    assertUnlinkedConst(annotations[0], 'A(this)', operators: [
-      UnlinkedExprOperation.pushThis,
-      UnlinkedExprOperation.invokeConstructor,
-    ], ints: [
-      0,
-      1
-    ], referenceValidators: [
-      (EntityRef r) =>
-          checkTypeRef(r, null, 'A', expectedKind: ReferenceKind.classOrEnum)
-    ]);
-  }
-
-  test_metadata_libraryDirective() {
-    serializeLibraryText('@a library L; const a = null;');
-    checkAnnotationA(unlinkedUnits[0].libraryAnnotations);
-  }
-
-  test_metadata_methodDeclaration_getter() {
-    checkAnnotationA(
-        serializeClassText('const a = null; class C { @a get m => null; }')
-            .executables[0]
-            .annotations);
-  }
-
-  test_metadata_methodDeclaration_method() {
-    checkAnnotationA(serializeClassText('const a = null; class C { @a m() {} }')
-        .executables[0]
-        .annotations);
-  }
-
-  test_metadata_methodDeclaration_setter() {
-    checkAnnotationA(
-        serializeClassText('const a = null; class C { @a set m(value) {} }')
-            .executables[0]
-            .annotations);
-  }
-
-  test_metadata_mixinDeclaration() {
-    checkAnnotationA(
-        serializeMixinText('const a = null; @a mixin M {}').annotations);
-  }
-
-  test_metadata_multiple_annotations() {
-    UnlinkedClass cls =
-        serializeClassText('const a = null, b = null; @a @b class C {}');
-    List<UnlinkedExpr> annotations = cls.annotations;
-    expect(annotations, hasLength(2));
-    assertUnlinkedConst(annotations[0], 'a', operators: [
-      UnlinkedExprOperation.pushReference
-    ], referenceValidators: [
-      (EntityRef r) => checkTypeRef(r, null, 'a',
-          expectedKind: ReferenceKind.topLevelPropertyAccessor)
-    ]);
-    assertUnlinkedConst(annotations[1], 'b', operators: [
-      UnlinkedExprOperation.pushReference
-    ], referenceValidators: [
-      (EntityRef r) => checkTypeRef(r, null, 'b',
-          expectedKind: ReferenceKind.topLevelPropertyAccessor)
-    ]);
-  }
-
-  test_metadata_partDirective() {
-    addNamedSource('/foo.dart', 'part of L;');
-    serializeLibraryText('library L; @a part "foo.dart"; const a = null;');
-    checkAnnotationA(unlinkedUnits[0].parts[0].annotations);
-  }
-
-  test_metadata_prefixed_variable() {
-    addNamedSource('/a.dart', 'const b = null;');
-    UnlinkedClass cls =
-        serializeClassText('import "a.dart" as a; @a.b class C {}');
-    expect(cls.annotations, hasLength(1));
-    assertUnlinkedConst(cls.annotations[0], 'a.b', operators: [
-      UnlinkedExprOperation.pushReference
-    ], referenceValidators: [
-      (EntityRef r) => checkTypeRef(r, absUri('/a.dart'), 'b',
-          expectedKind: ReferenceKind.topLevelPropertyAccessor,
-          expectedPrefix: 'a')
-    ]);
-  }
-
-  test_metadata_prefixed_variable_unresolved() {
-    addNamedSource('/a.dart', '');
-    UnlinkedClass cls = serializeClassText(
-        'import "a.dart" as a; @a.b class C {}',
-        allowErrors: true);
-    expect(cls.annotations, hasLength(1));
-    assertUnlinkedConst(cls.annotations[0], 'a.b', operators: [
-      UnlinkedExprOperation.pushReference
-    ], referenceValidators: [
-      (EntityRef r) => checkTypeRef(r, null, 'b',
-          expectedKind: ReferenceKind.unresolved, expectedPrefix: 'a')
-    ]);
-  }
-
-  test_metadata_simpleFormalParameter() {
-    checkAnnotationA(serializeExecutableText('const a = null; f(@a x) {}')
-        .parameters[0]
-        .annotations);
-  }
-
-  test_metadata_simpleFormalParameter_withDefault() {
-    checkAnnotationA(
-        serializeExecutableText('const a = null; f([@a x = null]) {}')
-            .parameters[0]
-            .annotations);
-  }
-
-  test_metadata_topLevelVariableDeclaration() {
-    checkAnnotationA(
-        serializeVariableText('const a = null; @a int v;').annotations);
-  }
-
-  test_metadata_typeParameter_ofClass() {
-    checkAnnotationA(serializeClassText('const a = null; class C<@a T> {}')
-        .typeParameters[0]
-        .annotations);
-  }
-
-  test_metadata_typeParameter_ofClassTypeAlias() {
-    checkAnnotationA(serializeClassText(
-            'const a = null; class C<@a T> = D with E; class D {} class E {}',
-            className: 'C')
-        .typeParameters[0]
-        .annotations);
-  }
-
-  test_metadata_typeParameter_ofFunction() {
-    checkAnnotationA(serializeExecutableText('const a = null; f<@a T>() {}')
-        .typeParameters[0]
-        .annotations);
-  }
-
-  test_metadata_typeParameter_ofTypedef() {
-    checkAnnotationA(serializeTypedefText('const a = null; typedef F<@a T>();')
-        .typeParameters[0]
-        .annotations);
-  }
-
-  test_metadata_variable_unresolved() {
-    UnlinkedClass cls = serializeClassText('@a class C {}', allowErrors: true);
-    expect(cls.annotations, hasLength(1));
-    assertUnlinkedConst(cls.annotations[0], 'a', operators: [
-      UnlinkedExprOperation.pushReference
-    ], referenceValidators: [
-      (EntityRef r) =>
-          checkTypeRef(r, null, 'a', expectedKind: ReferenceKind.unresolved)
-    ]);
-  }
-
-  test_method_documented() {
-    String text = '''
-class C {
-  /**
-   * Docs
-   */
-  f() {}
-}''';
-    UnlinkedExecutable executable = serializeClassText(text).executables[0];
-    expect(executable.documentationComment, isNotNull);
-    checkDocumentationComment(executable.documentationComment, text);
-  }
-
-  test_method_inferred_type_nonstatic_explicit_param() {
-    UnlinkedExecutable f = serializeClassText(
-            'class C extends D { void f(num value) {} }'
-            ' abstract class D { void f(int value); }',
-            className: 'C')
-        .executables[0];
-    expect(f.parameters[0].inferredTypeSlot, 0);
-  }
-
-  test_method_inferred_type_nonstatic_explicit_return() {
-    UnlinkedExecutable f = serializeClassText(
-            'class C extends D { num f() => null; } abstract class D { int f(); }',
-            className: 'C',
-            allowErrors: true)
-        .executables[0];
-    expect(f.inferredReturnTypeSlot, 0);
-  }
-
-  test_method_inferred_type_nonstatic_implicit_param() {
-    UnlinkedExecutable f = serializeClassText(
-            'class C extends D { void f(value) {} }'
-            ' abstract class D { void f(int value); }',
-            className: 'C')
-        .executables[0];
-    checkInferredTypeSlot(f.parameters[0].inferredTypeSlot, 'dart:core', 'int');
-  }
-
-  test_method_inferred_type_nonstatic_implicit_return() {
-    UnlinkedExecutable f = serializeClassText(
-            'class C extends D { f() => null; } abstract class D { int f(); }',
-            className: 'C')
-        .executables[0];
-    checkInferredTypeSlot(f.inferredReturnTypeSlot, 'dart:core', 'int');
-  }
-
-  test_method_inferred_type_static_implicit_param() {
-    UnlinkedExecutable f = serializeClassText(
-            'class C extends D { static void f(value) {} }'
-            ' class D { static void f(int value) {} }',
-            className: 'C')
-        .executables[0];
-    expect(f.parameters[0].inferredTypeSlot, 0);
-  }
-
-  test_method_inferred_type_static_implicit_return() {
-    UnlinkedExecutable f = serializeClassText(
-            'class C extends D { static f() => null; }'
-            ' class D { static int f() => null; }',
-            className: 'C')
-        .executables[0];
-    expect(f.inferredReturnTypeSlot, 0);
-  }
-
-  test_mixin() {
-    UnlinkedClass mixin = serializeMixinText('mixin M {}');
-    expect(mixin.name, 'M');
-    expect(mixin.nameOffset, 6);
-
-    expect(mixin.executables, isEmpty);
-    expect(mixin.interfaces, isEmpty);
-    expect(mixin.mixins, isEmpty);
-    expect(mixin.superclassConstraints, isEmpty);
-  }
-
-  test_mixin_codeRange() {
-    UnlinkedClass mixin = serializeMixinText(' mixin M {}');
-    _assertCodeRange(mixin.codeRange, 1, 10);
-  }
-
-  test_mixin_documented() {
-    String text = '''
-// Extra comment so doc comment offset != 0
-/**
- * Docs
- */
-mixin M {}''';
-    UnlinkedClass mixin = serializeMixinText(text);
-    expect(mixin.documentationComment, isNotNull);
-    checkDocumentationComment(mixin.documentationComment, text);
-  }
-
-  test_mixin_documented_tripleSlash() {
-    String text = '''
-/// aaa
-/// bbbb
-/// cc
-mixin M {}''';
-    UnlinkedClass mixin = serializeMixinText(text);
-    UnlinkedDocumentationComment comment = mixin.documentationComment;
-    expect(comment, isNotNull);
-    expect(comment.text, '/// aaa\n/// bbbb\n/// cc');
-  }
-
-  test_mixin_executables() {
-    UnlinkedClass mixin = serializeMixinText(r'''
-mixin M {
-  double f;
-  int get g => 0;
-  set s(int v) {}
-  int m(int v) => 0;
-}
-''');
-    expect(mixin.fields, hasLength(1));
-    expect(mixin.fields[0].name, 'f');
-    checkTypeRef(mixin.fields[0].type, 'dart:core', 'double');
-
-    expect(mixin.executables, hasLength(3));
-
-    expect(mixin.executables[0].name, 'g');
-    expect(mixin.executables[0].kind, UnlinkedExecutableKind.getter);
-    checkTypeRef(mixin.executables[0].returnType, 'dart:core', 'int');
-
-    expect(mixin.executables[1].name, 's=');
-    expect(mixin.executables[1].kind, UnlinkedExecutableKind.setter);
-
-    expect(mixin.executables[2].name, 'm');
-    expect(mixin.executables[2].kind, UnlinkedExecutableKind.functionOrMethod);
-    checkTypeRef(mixin.executables[2].returnType, 'dart:core', 'int');
-  }
-
-  test_mixin_implements() {
-    UnlinkedClass mixin = serializeMixinText(r'''
-class A {}
-class B {}
-mixin M implements A, B {}
-''');
-    expect(mixin.executables, isEmpty);
-    expect(mixin.mixins, isEmpty);
-    expect(mixin.superclassConstraints, isEmpty);
-
-    expect(mixin.interfaces, hasLength(2));
-    checkTypeRef(mixin.interfaces[0], null, 'A');
-    checkTypeRef(mixin.interfaces[1], null, 'B');
-  }
-
-  test_mixin_superclassConstraints() {
-    UnlinkedClass mixin = serializeMixinText(r'''
-class A {}
-class B {}
-class C {}
-class D {}
-mixin M on A, B implements C, D {}
-''');
-    expect(mixin.executables, isEmpty);
-    expect(mixin.mixins, isEmpty);
-
-    expect(mixin.superclassConstraints, hasLength(2));
-    checkTypeRef(mixin.superclassConstraints[0], null, 'A');
-    checkTypeRef(mixin.superclassConstraints[1], null, 'B');
-
-    expect(mixin.interfaces, hasLength(2));
-    checkTypeRef(mixin.interfaces[0], null, 'C');
-    checkTypeRef(mixin.interfaces[1], null, 'D');
-  }
-
-  test_mixin_superInvokedNames_methodInvocation() {
-    UnlinkedClass mixin = serializeMixinText('''
-mixin M {
-  void x() {
-    super.a();
-    super.b().c();
-  }
-}
-''');
-    expect(mixin.superInvokedNames, unorderedEquals(['a', 'b']));
-  }
-
-  test_mixin_superInvokedNames_operator_binary() {
-    UnlinkedClass mixin = serializeMixinText('''
-mixin M {
-  void x() {
-    super + 1;
-    super - 2;
-  }
-}
-''');
-    expect(mixin.superInvokedNames, unorderedEquals(['+', '-']));
-  }
-
-  test_mixin_superInvokedNames_operator_index() {
-    UnlinkedClass mixin = serializeMixinText('''
-mixin M {
-  void x() {
-    super[0];
-  }
-}
-''');
-    expect(mixin.superInvokedNames, unorderedEquals(['[]']));
-  }
-
-  test_mixin_superInvokedNames_operator_index_indexEq() {
-    UnlinkedClass mixin = serializeMixinText('''
-mixin M {
-  void x() {
-    super[0] += 1;
-  }
-}
-''');
-    expect(mixin.superInvokedNames, unorderedEquals(['[]', '[]=']));
-  }
-
-  test_mixin_superInvokedNames_operator_indexEq() {
-    UnlinkedClass mixin = serializeMixinText('''
-mixin M {
-  void x() {
-    super[0] = 1;
-  }
-}
-''');
-    expect(mixin.superInvokedNames, unorderedEquals(['[]=']));
-  }
-
-  test_mixin_superInvokedNames_operator_prefix() {
-    UnlinkedClass mixin = serializeMixinText('''
-mixin M {
-  void x() {
-    ~super;
-    -super;
-  }
-}
-''');
-    expect(mixin.superInvokedNames, unorderedEquals(['~', 'unary-']));
-  }
-
-  test_mixin_superInvokedNames_propertyAccess_get() {
-    UnlinkedClass mixin = serializeMixinText('''
-mixin M {
-  void x() {
-    super.a;
-    super.b.c;
-
-    ~super.e;
-    -super.d;
-  }
-}
-''');
-    expect(mixin.superInvokedNames, unorderedEquals(['a', 'b', 'd', 'e']));
-  }
-
-  test_mixin_superInvokedNames_propertyAccess_get_set() {
-    UnlinkedClass mixin = serializeMixinText('''
-mixin M {
-  void x() {
-    super.a++;
-    --super.b;
-    super.c += 1;
-  }
-}
-''');
-    expect(
-      mixin.superInvokedNames,
-      unorderedEquals(['a', 'b', 'c', 'a=', 'b=', 'c=']),
-    );
-  }
-
-  test_mixin_superInvokedNames_propertyAccess_set() {
-    UnlinkedClass mixin = serializeMixinText('''
-mixin M {
-  void x() {
-    super.a = 1;
-  }
-}
-''');
-    expect(mixin.superInvokedNames, unorderedEquals(['a=']));
-  }
-
-  test_mixin_typeParameters() {
-    UnlinkedClass mixin = serializeMixinText('mixin M<T extends num, U> {}');
-    expect(mixin.typeParameters, hasLength(2));
-
-    expect(mixin.typeParameters[0].name, 'T');
-    checkTypeRef(mixin.typeParameters[0].bound, 'dart:core', 'num');
-
-    expect(mixin.typeParameters[1].name, 'U');
-    expect(mixin.typeParameters[1].bound, isNull);
-  }
-
-  test_nested_generic_functions() {
-    UnlinkedExecutable executable = serializeVariableText('''
-var v = (() {
-  void f<T, U>() {
-    void g<V, W>() {
-      void h<X, Y>(T t, U u, V v W w, X x, Y y) {
-      }
-    }
-  }
-});
-''').initializer.localFunctions[0].localFunctions[0];
-    expect(executable.typeParameters, hasLength(2));
-    expect(executable.localFunctions[0].typeParameters, hasLength(2));
-    expect(executable.localFunctions[0].localFunctions[0].typeParameters,
-        hasLength(2));
-    List<UnlinkedParam> parameters =
-        executable.localFunctions[0].localFunctions[0].parameters;
-    checkParamTypeRef(findParameter(parameters, 't').type, 6);
-    checkParamTypeRef(findParameter(parameters, 'u').type, 5);
-    checkParamTypeRef(findParameter(parameters, 'v').type, 4);
-    checkParamTypeRef(findParameter(parameters, 'w').type, 3);
-    checkParamTypeRef(findParameter(parameters, 'x').type, 2);
-    checkParamTypeRef(findParameter(parameters, 'y').type, 1);
-  }
-
-  test_new_typedef_notSimplyBoundedSlot() {
-    var typedef =
-        serializeTypedefText('typedef F<T extends F> = void Function();');
-    expect(typedef.notSimplyBoundedSlot, isNot(0));
-    if (!skipFullyLinkedData) {
-      expect(linked.units[0].notSimplyBounded,
-          contains(typedef.notSimplyBoundedSlot));
-    }
-  }
-
-  test_new_typedef_notSimplyBoundedSlot_simple_no_bounds() {
-    // If no bounds are specified, then the typedef is simply bounded, however
-    // it still gets a slot because all typedefs are assigned a slot.
-    var typedef = serializeTypedefText('typedef F<T> = void Function();');
-    expect(typedef.notSimplyBoundedSlot, isNot(0));
-    if (!skipFullyLinkedData) {
-      expect(linked.units[0].notSimplyBounded,
-          isNot(contains(typedef.notSimplyBoundedSlot)));
-    }
-  }
-
-  test_new_typedef_notSimplyBoundedSlot_simple_non_generic() {
-    // If no type parameters are specified, then the typedef is simply bounded,
-    // however it still gets a slot because all typedefs are assigned a slot.
-    var typedef = serializeTypedefText('typedef F = void Function();');
-    expect(typedef.notSimplyBoundedSlot, isNot(0));
-    if (!skipFullyLinkedData) {
-      expect(linked.units[0].notSimplyBounded,
-          isNot(contains(typedef.notSimplyBoundedSlot)));
-    }
-  }
-
-  test_old_typedef_notSimplyBoundedSlot() {
-    var typedef = serializeTypedefText('typedef void F<T extends F>();');
-    expect(typedef.notSimplyBoundedSlot, isNot(0));
-    if (!skipFullyLinkedData) {
-      expect(linked.units[0].notSimplyBounded,
-          contains(typedef.notSimplyBoundedSlot));
-    }
-  }
-
-  test_old_typedef_notSimplyBoundedSlot_simple_because_non_generic() {
-    // If no type parameters are specified, then the typedef is simply bounded,
-    // however it still gets a slot because all typedefs are assigned a slot.
-    var typedef = serializeTypedefText('typedef void F();');
-    expect(typedef.notSimplyBoundedSlot, isNot(0));
-    if (!skipFullyLinkedData) {
-      expect(linked.units[0].notSimplyBounded,
-          isNot(contains(typedef.notSimplyBoundedSlot)));
-    }
-  }
-
-  test_old_typedef_notSimplyBoundedSlot_simple_no_bounds() {
-    // If no bounds are specified, then the typedef is simply bounded, however
-    // it still gets a slot because all typedefs are assigned a slot.
-    var typedef = serializeTypedefText('typedef void F<T>();');
-    expect(typedef.notSimplyBoundedSlot, isNot(0));
-    if (!skipFullyLinkedData) {
-      expect(linked.units[0].notSimplyBounded,
-          isNot(contains(typedef.notSimplyBoundedSlot)));
-    }
-  }
-
-  test_parameter_visibleRange_abstractMethod() {
-    UnlinkedExecutable m = findExecutable('m',
-        executables:
-            serializeClassText('abstract class C { m(p); }').executables,
-        failIfAbsent: true);
-    _assertParameterZeroVisibleRange(m.parameters[0]);
-  }
-
-  test_parameter_visibleRange_function_blockBody() {
-    String text = r'''
-var v = (() {
-  f(x) { // 1
-    f2(y) { // 2
-    } // 3
-  } // 4
-});
-''';
-    var closure = serializeVariableText(text).initializer.localFunctions[0];
-    UnlinkedExecutable f = closure.localFunctions[0];
-    UnlinkedExecutable f2 = f.localFunctions[0];
-    _assertParameterVisible(text, f.parameters[0], '{ // 1', '} // 4');
-    _assertParameterVisible(text, f2.parameters[0], '{ // 2', '} // 3');
-  }
-
-  test_parameter_visibleRange_function_emptyBody() {
-    UnlinkedExecutable f = serializeExecutableText('external f(x);');
-    _assertParameterZeroVisibleRange(f.parameters[0]);
-  }
-
-  test_parameter_visibleRange_function_expressionBody() {
-    String text = r'''
-f(x) => 42;
-''';
-    UnlinkedExecutable f = serializeExecutableText(text);
-    _assertParameterVisible(text, f.parameters[0], '=>', ';');
-  }
-
-  test_parameter_visibleRange_inFunctionTypedParameter() {
-    String text = 'f(g(p)) {}';
-    UnlinkedExecutable f = serializeExecutableText(text);
-    UnlinkedParam g = f.parameters[0];
-    UnlinkedParam p = g.parameters[0];
-    expect(g.name, 'g');
-    expect(p.name, 'p');
-    _assertParameterVisible(text, g, '{', '}');
-    _assertParameterZeroVisibleRange(p);
-  }
-
-  test_parameter_visibleRange_invalid_fieldFormalParameter() {
-    UnlinkedExecutable m =
-        findExecutable('m', executables: serializeClassText(r'''
-class C {
-  int foo;
-  void m(this.foo) {}
-}
-''').executables);
-    _assertParameterZeroVisibleRange(m.parameters[0]);
-  }
-
-  test_parameter_visibleRange_typedef() {
-    UnlinkedTypedef type = serializeTypedefText('typedef F(x);');
-    _assertParameterZeroVisibleRange(type.parameters[0]);
-  }
-
-  test_part_declaration() {
-    addNamedSource('/a.dart', 'part of my.lib;');
-    String text = 'library my.lib; part "a.dart"; // <-part';
-    serializeLibraryText(text);
-    expect(unlinkedUnits[0].publicNamespace.parts, hasLength(1));
-    expect(unlinkedUnits[0].publicNamespace.parts[0], 'a.dart');
-    expect(unlinkedUnits[0].parts, hasLength(1));
-    expect(unlinkedUnits[0].parts[0].uriOffset, text.indexOf('"a.dart"'));
-    expect(unlinkedUnits[0].parts[0].uriEnd, text.indexOf('; // <-part'));
-  }
-
-  test_part_declaration_invalidUri_nullStringValue() {
-    addNamedSource('/a.dart', 'part of my.lib;');
-    String text = r'''
-library my.lib;
-part "${'a'}.dart"; // <-part
-''';
-    serializeLibraryText(text);
-    expect(unlinkedUnits[0].publicNamespace.parts, hasLength(1));
-    expect(unlinkedUnits[0].publicNamespace.parts[0], '');
-    expect(unlinkedUnits[0].parts, hasLength(1));
-    expect(unlinkedUnits[0].parts[0].uriOffset, text.indexOf(r'"${'));
-    expect(unlinkedUnits[0].parts[0].uriEnd, text.indexOf('; // <-part'));
-  }
-
-  test_part_isPartOf() {
-    addNamedSource('/a.dart', 'part of foo; class C {}');
-    serializeLibraryText('library foo; part "a.dart";');
-    expect(unlinkedUnits[0].isPartOf, isFalse);
-    expect(unlinkedUnits[1].isPartOf, isTrue);
-  }
-
-  test_part_uri_invalid() {
-    String uriString = ':[invalid uri]';
-    String libraryText = 'part "$uriString";';
-    serializeLibraryText(libraryText);
-    expect(unlinkedUnits[0].publicNamespace.parts, hasLength(1));
-    expect(unlinkedUnits[0].publicNamespace.parts[0], uriString);
-  }
-
-  test_parts_defining_compilation_unit() {
-    serializeLibraryText('');
-    expect(linked.units, hasLength(1));
-    expect(unlinkedUnits[0].publicNamespace.parts, isEmpty);
-  }
-
-  test_parts_included() {
-    addNamedSource('/part1.dart', 'part of my.lib;');
-    String partString = '"part1.dart"';
-    String libraryText = 'library my.lib; part $partString;';
-    serializeLibraryText(libraryText);
-    expect(linked.units, hasLength(2));
-    expect(unlinkedUnits[0].publicNamespace.parts, hasLength(1));
-    expect(unlinkedUnits[0].publicNamespace.parts[0], 'part1.dart');
-  }
-
-  test_public_namespace_of_part() {
-    addNamedSource('/a.dart', 'part of foo; class C {}');
-    serializeLibraryText('library foo; part "a.dart";');
-    expect(unlinkedUnits[0].publicNamespace.names, isEmpty);
-    expect(unlinkedUnits[1].publicNamespace.names, hasLength(1));
-    expect(unlinkedUnits[1].publicNamespace.names[0].name, 'C');
-  }
-
-  test_reference_zero() {
-    // Element zero of the references table should be populated in a standard
-    // way.
-    serializeLibraryText('');
-    UnlinkedReference unlinkedReference0 = unlinkedUnits[0].references[0];
-    expect(unlinkedReference0.name, '');
-    expect(unlinkedReference0.prefixReference, 0);
-    LinkedReference linkedReference0 = linked.units[0].references[0];
-    expect(linkedReference0.containingReference, 0);
-    expect(linkedReference0.dependency, 0);
-    expect(linkedReference0.kind, ReferenceKind.unresolved);
-    expect(linkedReference0.name, '');
-    expect(linkedReference0.numTypeParameters, 0);
-    expect(linkedReference0.unit, 0);
-  }
-
-  test_setter_documented() {
-    String text = '''
-// Extra comment so doc comment offset != 0
-/**
- * Docs
- */
-void set f(value) {}''';
-    UnlinkedExecutable executable =
-        serializeExecutableText(text, executableName: 'f=');
-    expect(executable.documentationComment, isNotNull);
-    checkDocumentationComment(executable.documentationComment, text);
-  }
-
-  test_setter_inferred_type_nonstatic_explicit_param() {
-    UnlinkedExecutable f = serializeClassText(
-            'class C extends D { void set f(num value) {} }'
-            ' abstract class D { void set f(int value); }',
-            className: 'C')
-        .executables[0];
-    expect(f.parameters[0].inferredTypeSlot, 0);
-  }
-
-  test_setter_inferred_type_nonstatic_explicit_return() {
-    UnlinkedExecutable f =
-        serializeClassText('class C { void set f(int value) {} }')
-            .executables[0];
-    expect(f.inferredReturnTypeSlot, 0);
-  }
-
-  test_setter_inferred_type_nonstatic_implicit_param() {
-    UnlinkedExecutable f = serializeClassText(
-            'class C extends D { void set f(value) {} }'
-            ' abstract class D { void set f(int value); }',
-            className: 'C')
-        .executables[0];
-    checkInferredTypeSlot(f.parameters[0].inferredTypeSlot, 'dart:core', 'int');
-  }
-
-  test_setter_inferred_type_nonstatic_implicit_return() {
-    UnlinkedExecutable f =
-        serializeClassText('class C { set f(int value) {} }').executables[0];
-    checkInferredTypeSlot(f.inferredReturnTypeSlot, null, 'void');
-  }
-
-  test_setter_inferred_type_static_implicit_param() {
-    UnlinkedExecutable f = serializeClassText(
-            'class C extends D { static void set f(value) {} }'
-            ' class D { static void set f(int value) {} }',
-            className: 'C')
-        .executables[0];
-    expect(f.parameters[0].inferredTypeSlot, 0);
-  }
-
-  test_setter_inferred_type_static_implicit_return() {
-    UnlinkedExecutable f =
-        serializeClassText('class C { static set f(int value) {} }')
-            .executables[0];
-    expect(f.inferredReturnTypeSlot, 0);
-  }
-
-  test_setter_inferred_type_top_level_implicit_param() {
-    UnlinkedExecutable f =
-        serializeExecutableText('void set f(value) {}', executableName: 'f=');
-    expect(f.parameters[0].inferredTypeSlot, 0);
-  }
-
-  test_setter_inferred_type_top_level_implicit_return() {
-    UnlinkedExecutable f =
-        serializeExecutableText('set f(int value) {}', executableName: 'f=');
-    expect(f.inferredReturnTypeSlot, 0);
-  }
-
-  test_slot_reuse() {
-    // Different compilation units have independent notions of slot id, so slot
-    // ids should be reused.
-    addNamedSource('/a.dart', 'part of foo; final v = 0;');
-    serializeLibraryText('library foo; part "a.dart"; final w = 0;');
-    expect(unlinkedUnits[1].variables[0].inferredTypeSlot,
-        unlinkedUnits[0].variables[0].inferredTypeSlot);
-  }
-
-  test_syntheticFunctionType_genericClosure() {
-    if (skipFullyLinkedData) {
-      return;
-    }
-    // TODO(paulberry): once proper generic method syntax supports generic
-    // closures, rewrite the test below without using generic comment syntax,
-    // and remove this hack.  See dartbug.com/25819
-    UnlinkedVariable variable = serializeVariableText('''
-final v = f() ? /*<T>*/(T t) => 0 : /*<T>*/(T t) => 1;
-bool f() => true;
-''');
-    EntityRef inferredType = getTypeRefForSlot(variable.inferredTypeSlot);
-    checkLinkedTypeRef(inferredType.syntheticReturnType, 'dart:core', 'int');
-    expect(inferredType.syntheticParams, hasLength(1));
-    checkLinkedTypeRef(inferredType.syntheticParams[0].type, null, 'Never');
-  }
-
-  test_syntheticFunctionType_inGenericClass() {
-    if (skipFullyLinkedData) {
-      return;
-    }
-    UnlinkedVariable variable = serializeClassText('''
-class C<T, U> {
-  var v = f() ? (T t, U u) => 0 : (T t, U u) => 1;
-}
-bool f() => false;
-''').fields[0];
-    EntityRef inferredType =
-        getTypeRefForSlot(variable.initializer.inferredReturnTypeSlot);
-    checkLinkedTypeRef(inferredType.syntheticReturnType, 'dart:core', 'int');
-    checkParamTypeRef(inferredType.syntheticParams[0].type, 2);
-    checkParamTypeRef(inferredType.syntheticParams[1].type, 1);
-  }
-
-  test_type_arguments_explicit() {
-    EntityRef typeRef = serializeTypeText('List<int>');
-    checkTypeRef(typeRef, 'dart:core', 'List',
-        numTypeParameters: 1, numTypeArguments: 1);
-    checkTypeRef(typeRef.typeArguments[0], 'dart:core', 'int');
-  }
-
-  test_type_arguments_explicit_dynamic() {
-    EntityRef typeRef = serializeTypeText('List<dynamic>');
-    checkTypeRef(typeRef, 'dart:core', 'List',
-        numTypeParameters: 1, numTypeArguments: 1);
-    checkDynamicTypeRef(typeRef.typeArguments[0]);
-  }
-
-  test_type_arguments_explicit_dynamic_dynamic() {
-    EntityRef typeRef = serializeTypeText('Map<dynamic, dynamic>');
-    checkTypeRef(typeRef, 'dart:core', 'Map',
-        numTypeParameters: 2, numTypeArguments: 2);
-    checkDynamicTypeRef(typeRef.typeArguments[0]);
-    checkDynamicTypeRef(typeRef.typeArguments[1]);
-  }
-
-  test_type_arguments_explicit_dynamic_int() {
-    EntityRef typeRef = serializeTypeText('Map<dynamic, int>');
-    checkTypeRef(typeRef, 'dart:core', 'Map',
-        numTypeParameters: 2, numTypeArguments: 2);
-    checkDynamicTypeRef(typeRef.typeArguments[0]);
-    checkTypeRef(typeRef.typeArguments[1], 'dart:core', 'int');
-  }
-
-  test_type_arguments_explicit_dynamic_typedef() {
-    EntityRef typeRef =
-        serializeTypeText('F<dynamic>', otherDeclarations: 'typedef T F<T>();');
-    checkTypeRef(typeRef, null, 'F',
-        expectedKind: ReferenceKind.typedef,
-        numTypeParameters: 1,
-        numTypeArguments: 1);
-    checkDynamicTypeRef(typeRef.typeArguments[0]);
-  }
-
-  test_type_arguments_explicit_String_dynamic() {
-    EntityRef typeRef = serializeTypeText('Map<String, dynamic>');
-    checkTypeRef(typeRef, 'dart:core', 'Map',
-        numTypeParameters: 2, numTypeArguments: 2);
-    checkTypeRef(typeRef.typeArguments[0], 'dart:core', 'String');
-    checkDynamicTypeRef(typeRef.typeArguments[1]);
-  }
-
-  test_type_arguments_explicit_String_int() {
-    EntityRef typeRef = serializeTypeText('Map<String, int>');
-    checkTypeRef(typeRef, 'dart:core', 'Map',
-        numTypeParameters: 2, numTypeArguments: 2);
-    checkTypeRef(typeRef.typeArguments[0], 'dart:core', 'String');
-    checkTypeRef(typeRef.typeArguments[1], 'dart:core', 'int');
-  }
-
-  test_type_arguments_explicit_typedef() {
-    EntityRef typeRef =
-        serializeTypeText('F<int>', otherDeclarations: 'typedef T F<T>();');
-    checkTypeRef(typeRef, null, 'F',
-        expectedKind: ReferenceKind.typedef,
-        numTypeParameters: 1,
-        numTypeArguments: 1);
-    checkTypeRef(typeRef.typeArguments[0], 'dart:core', 'int');
-  }
-
-  test_type_arguments_implicit() {
-    EntityRef typeRef = serializeTypeText('List');
-    checkTypeRef(typeRef, 'dart:core', 'List', numTypeParameters: 1);
-  }
-
-  test_type_arguments_implicit_typedef() {
-    EntityRef typeRef =
-        serializeTypeText('F', otherDeclarations: 'typedef T F<T>();');
-    checkTypeRef(typeRef, null, 'F',
-        expectedKind: ReferenceKind.typedef, numTypeParameters: 1);
-  }
-
-  test_type_arguments_implicit_typedef_withBound() {
-    EntityRef typeRef = serializeTypeText('F',
-        otherDeclarations: 'typedef T F<T extends num>();');
-    checkTypeRef(typeRef, null, 'F',
-        expectedKind: ReferenceKind.typedef, numTypeParameters: 1);
-  }
-
-  test_type_arguments_order() {
-    EntityRef typeRef = serializeTypeText('Map<int, Object>');
-    checkTypeRef(typeRef, 'dart:core', 'Map',
-        numTypeParameters: 2, numTypeArguments: 2);
-    checkTypeRef(typeRef.typeArguments[0], 'dart:core', 'int');
-    checkTypeRef(typeRef.typeArguments[1], 'dart:core', 'Object');
-  }
-
-  test_type_dynamic() {
-    checkDynamicTypeRef(serializeTypeText('dynamic'));
-  }
-
-  test_type_inference_based_on_type_parameter() {
-    var class_ = serializeClassText('''
-class C<T> {
-  var field = T;
-}
-''');
-    var field = class_.fields[0];
-    checkLinkedTypeSlot(field.inferredTypeSlot, 'dart:core', 'Type');
-  }
-
-  test_type_invalid_typeParameter_asPrefix() {
-    UnlinkedClass c = serializeClassText('''
-class C<T> {
-  m(T.K p) {}
-}
-''');
-    UnlinkedExecutable m = c.executables[0];
-    expect(m.name, 'm');
-    checkTypeRef(m.parameters[0].type, null, 'dynamic');
-  }
-
-  test_type_nullability_suffix_none() {
-    featureSet = enableNnbd;
-    EntityRef typeRef = serializeTypeText('int');
-    checkTypeRef(typeRef, 'dart:core', 'int',
-        nullabilitySuffix: EntityRefNullabilitySuffix.none);
-  }
-
-  test_type_nullability_suffix_question() {
-    featureSet = enableNnbd;
-    EntityRef typeRef = serializeTypeText('int?');
-    checkTypeRef(typeRef, 'dart:core', 'int',
-        nullabilitySuffix: EntityRefNullabilitySuffix.question);
-  }
-
-  test_type_nullability_suffix_star() {
-    featureSet = disableNnbd;
-    EntityRef typeRef = serializeTypeText('int');
-    checkTypeRef(typeRef, 'dart:core', 'int',
-        nullabilitySuffix: EntityRefNullabilitySuffix.starOrIrrelevant);
-  }
-
-  test_type_param_codeRange() {
-    UnlinkedClass cls =
-        serializeClassText('class A {} class C<T extends A> {}');
-    UnlinkedTypeParam typeParameter = cls.typeParameters[0];
-    _assertCodeRange(typeParameter.codeRange, 19, 11);
-  }
-
-  test_type_param_not_shadowed_by_constructor() {
-    UnlinkedClass cls =
-        serializeClassText('class C<D> { D x; C.D(); } class D {}');
-    checkParamTypeRef(cls.fields[0].type, 1);
-  }
-
-  test_type_param_not_shadowed_by_field_in_extends() {
-    UnlinkedClass cls =
-        serializeClassText('class C<T> extends D<T> { T x; } class D<T> {}');
-    checkParamTypeRef(cls.supertype.typeArguments[0], 1);
-  }
-
-  test_type_param_not_shadowed_by_field_in_implements() {
-    UnlinkedClass cls =
-        serializeClassText('class C<T> implements D<T> { T x; } class D<T> {}');
-    checkParamTypeRef(cls.interfaces[0].typeArguments[0], 1);
-  }
-
-  test_type_param_not_shadowed_by_field_in_with() {
-    UnlinkedClass cls = serializeClassText(
-        'class C<T> extends Object with D<T> { T x; } class D<T> {}');
-    checkParamTypeRef(cls.mixins[0].typeArguments[0], 1);
-  }
-
-  test_type_param_not_shadowed_by_method_parameter() {
-    UnlinkedClass cls = serializeClassText('class C<T> { f(int T, T x) {} }');
-    checkParamTypeRef(cls.executables[0].parameters[1].type, 1);
-  }
-
-  test_type_param_not_shadowed_by_setter() {
-    // The code under test should not produce a compile-time error, but it
-    // does.
-    bool workAroundBug25525 = true;
-    UnlinkedClass cls = serializeClassText(
-        'class C<D> { D x; void set D(value) {} } class D {}',
-        allowErrors: workAroundBug25525);
-    checkParamTypeRef(cls.fields[0].type, 1);
-  }
-
-  test_type_param_not_shadowed_by_typedef_parameter() {
-    UnlinkedTypedef typedef =
-        serializeTypedefText('typedef void F<T>(int T, T x);');
-    checkParamTypeRef(typedef.parameters[1].type, 1);
-  }
-
-  test_type_param_shadowed_by_field() {
-    UnlinkedClass cls = serializeClassText(
-        'class C<D> { D x; int D; } class D {}',
-        allowErrors: true);
-    checkDynamicTypeRef(cls.fields[0].type);
-  }
-
-  test_type_param_shadowed_by_getter() {
-    UnlinkedClass cls = serializeClassText(
-        'class C<D> { D x; int get D => null; } class D {}',
-        allowErrors: true);
-    checkDynamicTypeRef(cls.fields[0].type);
-  }
-
-  test_type_param_shadowed_by_method() {
-    UnlinkedClass cls = serializeClassText(
-        'class C<D> { D x; void D() {} } class D {}',
-        allowErrors: true);
-    checkDynamicTypeRef(cls.fields[0].type);
-  }
-
-  test_type_param_shadowed_by_type_param() {
-    UnlinkedClass cls =
-        serializeClassText('class C<T> { T f<T>(T x) => null; }');
-    checkParamTypeRef(cls.executables[0].returnType, 1);
-    checkParamTypeRef(cls.executables[0].parameters[0].type, 1);
-  }
-
-  test_type_reference_from_part() {
-    addNamedSource('/a.dart', 'part of foo; C v;');
-    serializeLibraryText('library foo; part "a.dart"; class C {}');
-    checkTypeRef(findVariable('v', variables: unlinkedUnits[1].variables).type,
-        null, 'C',
-        expectedKind: ReferenceKind.classOrEnum,
-        linkedSourceUnit: linked.units[1],
-        unlinkedSourceUnit: unlinkedUnits[1]);
-  }
-
-  test_type_reference_from_part_withPrefix() {
-    addNamedSource('/a.dart', 'class C {}');
-    addNamedSource('/p.dart', 'part of foo; a.C v;');
-    serializeLibraryText(
-        'library foo; import "a.dart"; import "a.dart" as a; part "p.dart";',
-        allowErrors: true);
-    checkTypeRef(findVariable('v', variables: unlinkedUnits[1].variables).type,
-        absUri('/a.dart'), 'C',
-        expectedPrefix: 'a',
-        linkedSourceUnit: linked.units[1],
-        unlinkedSourceUnit: unlinkedUnits[1]);
-  }
-
-  test_type_reference_to_class_argument() {
-    UnlinkedClass cls = serializeClassText('class C<T, U> { T t; U u; }');
-    {
-      EntityRef typeRef =
-          findVariable('t', variables: cls.fields, failIfAbsent: true).type;
-      checkParamTypeRef(typeRef, 2);
-    }
-    {
-      EntityRef typeRef =
-          findVariable('u', variables: cls.fields, failIfAbsent: true).type;
-      checkParamTypeRef(typeRef, 1);
-    }
-  }
-
-  test_type_reference_to_import_of_export() {
-    addNamedSource('/a.dart', 'library a; export "b.dart";');
-    addNamedSource('/b.dart', 'library b; class C {}');
-    checkTypeRef(serializeTypeText('C', otherDeclarations: 'import "a.dart";'),
-        absUri('/b.dart'), 'C');
-  }
-
-  test_type_reference_to_import_of_export_via_prefix() {
-    addNamedSource('/a.dart', 'library a; export "b.dart";');
-    addNamedSource('/b.dart', 'library b; class C {}');
-    checkTypeRef(
-        serializeTypeText('p.C', otherDeclarations: 'import "a.dart" as p;'),
-        absUri('/b.dart'),
-        'C',
-        expectedPrefix: 'p');
-  }
-
-  test_type_reference_to_imported_part() {
-    addNamedSource('/a.dart', 'library my.lib; part "b.dart";');
-    addNamedSource('/b.dart', 'part of my.lib; class C {}');
-    checkTypeRef(
-        serializeTypeText('C',
-            otherDeclarations: 'library my.lib; import "a.dart";'),
-        absUri('/a.dart'),
-        'C',
-        expectedTargetUnit: 1);
-  }
-
-  test_type_reference_to_imported_part_with_prefix() {
-    addNamedSource('/a.dart', 'library my.lib; part "b.dart";');
-    addNamedSource('/b.dart', 'part of my.lib; class C {}');
-    checkTypeRef(
-        serializeTypeText('p.C',
-            otherDeclarations: 'library my.lib; import "a.dart" as p;'),
-        absUri('/a.dart'),
-        'C',
-        expectedPrefix: 'p',
-        expectedTargetUnit: 1);
-  }
-
-  test_type_reference_to_internal_class() {
-    checkTypeRef(
-        serializeTypeText('C', otherDeclarations: 'class C {}'), null, 'C');
-  }
-
-  test_type_reference_to_internal_class_alias() {
-    checkTypeRef(
-        serializeTypeText('C',
-            otherDeclarations: 'class C = D with E; class D {} class E {}'),
-        null,
-        'C');
-  }
-
-  test_type_reference_to_internal_enum() {
-    checkTypeRef(serializeTypeText('E', otherDeclarations: 'enum E { value }'),
-        null, 'E');
-  }
-
-  test_type_reference_to_local_part() {
-    addNamedSource('/a.dart', 'part of my.lib; class C {}');
-    checkTypeRef(
-        serializeTypeText('C',
-            otherDeclarations: 'library my.lib; part "a.dart";'),
-        null,
-        'C',
-        expectedTargetUnit: 1);
-  }
-
-  test_type_reference_to_nonexistent_file_via_prefix() {
-    allowMissingFiles = true;
-    EntityRef typeRef = serializeTypeText('p.C',
-        otherDeclarations: 'import "foo.dart" as p;', allowErrors: true);
-    checkUnresolvedTypeRef(typeRef, 'p', 'C');
-  }
-
-  test_type_reference_to_part() {
-    addNamedSource('/a.dart', 'part of foo; class C { C(); }');
-    serializeLibraryText('library foo; part "a.dart"; C c;');
-    checkTypeRef(unlinkedUnits[0].variables.single.type, null, 'C',
-        expectedKind: ReferenceKind.classOrEnum, expectedTargetUnit: 1);
-  }
-
-  test_type_reference_to_type_visible_via_multiple_import_prefixes() {
-    addNamedSource('/lib1.dart', 'class C');
-    addNamedSource('/lib2.dart', 'export "lib1.dart";');
-    addNamedSource('/lib3.dart', 'export "lib1.dart";');
-    addNamedSource('/lib4.dart', 'export "lib1.dart";');
-    serializeLibraryText('''
-import 'lib2.dart';
-import 'lib3.dart' as a;
-import 'lib4.dart' as b;
-C c2;
-a.C c3;
-b.C c4;''');
-    // Note: it is important that each reference to class C records the prefix
-    // used to find it; otherwise it's possible that relinking might produce an
-    // incorrect result after a change to lib2.dart, lib3.dart, or lib4.dart.
-    checkTypeRef(findVariable('c2').type, absUri('/lib1.dart'), 'C');
-    checkTypeRef(findVariable('c3').type, absUri('/lib1.dart'), 'C',
-        expectedPrefix: 'a');
-    checkTypeRef(findVariable('c4').type, absUri('/lib1.dart'), 'C',
-        expectedPrefix: 'b');
-  }
-
-  test_type_reference_to_typedef() {
-    checkTypeRef(serializeTypeText('F', otherDeclarations: 'typedef void F();'),
-        null, 'F',
-        expectedKind: ReferenceKind.typedef);
-  }
-
-  test_type_unit_counts_unreferenced_units() {
-    addNamedSource('/a.dart', 'library a; part "b.dart"; part "c.dart";');
-    addNamedSource('/b.dart', 'part of a;');
-    addNamedSource('/c.dart', 'part of a; class C {}');
-    EntityRef typeRef =
-        serializeTypeText('C', otherDeclarations: 'import "a.dart";');
-    // The referenced unit should be 2, since unit 0 is a.dart and unit 1 is
-    // b.dart.  a.dart and b.dart are counted even though nothing is imported
-    // from them.
-    checkTypeRef(typeRef, absUri('/a.dart'), 'C', expectedTargetUnit: 2);
-  }
-
-  test_type_unresolved() {
-    EntityRef typeRef = serializeTypeText('Foo', allowErrors: true);
-    checkUnresolvedTypeRef(typeRef, null, 'Foo');
-  }
-
-  test_typedef_codeRange() {
-    UnlinkedTypedef type = serializeTypedefText('typedef F();');
-    _assertCodeRange(type.codeRange, 0, 12);
-  }
-
-  test_typedef_documented() {
-    String text = '''
-// Extra comment so doc comment offset != 0
-/**
- * Docs
- */
-typedef F();''';
-    UnlinkedTypedef typedef = serializeTypedefText(text);
-    expect(typedef.documentationComment, isNotNull);
-    checkDocumentationComment(typedef.documentationComment, text);
-  }
-
-  test_typedef_genericFunction_reference() {
-    EntityRef typeRef = serializeTypeText('F',
-        otherDeclarations: 'typedef F<S> = S Function<T>(T x);');
-    checkTypeRef(typeRef, null, 'F',
-        numTypeParameters: 1,
-        expectedKind: ReferenceKind.genericFunctionTypedef);
-  }
-
-  test_typedef_genericFunction_typeNames() {
-    UnlinkedTypedef typedef =
-        serializeTypedefText('typedef F<S> = S Function(int x, String y);');
-    expect(typedef.style, TypedefStyle.genericFunctionType);
-    expect(typedef.typeParameters, hasLength(1));
-    expect(typedef.typeParameters[0].name, 'S');
-    expect(typedef.parameters, isEmpty);
-
-    EntityRef genericFunction = typedef.returnType;
-    expect(genericFunction.entityKind, EntityRefKind.genericFunctionType);
-    expect(genericFunction.typeParameters, isEmpty);
-
-    List<UnlinkedParam> functionParameters = genericFunction.syntheticParams;
-    expect(functionParameters, hasLength(2));
-    expect(functionParameters[0].name, 'x');
-    expect(functionParameters[1].name, 'y');
-    checkLinkedTypeRef(functionParameters[0].type, 'dart:core', 'int');
-    checkLinkedTypeRef(functionParameters[1].type, 'dart:core', 'String');
-
-    checkParamTypeRef(genericFunction.syntheticReturnType, 1);
-  }
-
-  test_typedef_genericFunction_typeParameters() {
-    UnlinkedTypedef typedef =
-        serializeTypedefText('typedef F<S> = S Function<T1, T2>(T1 x, T2 y);');
-    expect(typedef.style, TypedefStyle.genericFunctionType);
-    expect(typedef.typeParameters, hasLength(1));
-    expect(typedef.typeParameters[0].name, 'S');
-    expect(typedef.parameters, isEmpty);
-
-    EntityRef genericFunction = typedef.returnType;
-    expect(genericFunction.entityKind, EntityRefKind.genericFunctionType);
-
-    expect(genericFunction.typeParameters, hasLength(2));
-    expect(genericFunction.typeParameters[0].name, 'T1');
-    expect(genericFunction.typeParameters[1].name, 'T2');
-
-    expect(genericFunction.syntheticParams, hasLength(2));
-    expect(genericFunction.syntheticParams[0].name, 'x');
-    expect(genericFunction.syntheticParams[1].name, 'y');
-    checkParamTypeRef(genericFunction.syntheticParams[0].type, 2);
-    checkParamTypeRef(genericFunction.syntheticParams[1].type, 1);
-
-    checkParamTypeRef(genericFunction.syntheticReturnType, 3);
-  }
-
-  test_typedef_name() {
-    String text = 'typedef F();';
-    UnlinkedTypedef type = serializeTypedefText(text);
-    expect(type.name, 'F');
-    expect(type.nameOffset, text.indexOf('F'));
-    expect(unlinkedUnits[0].publicNamespace.names, hasLength(1));
-    expect(
-        unlinkedUnits[0].publicNamespace.names[0].kind, ReferenceKind.typedef);
-    expect(unlinkedUnits[0].publicNamespace.names[0].name, 'F');
-    expect(unlinkedUnits[0].publicNamespace.names[0].numTypeParameters, 0);
-  }
-
-  test_typedef_notSimplyBounded_dependency_via_param_type_new_style_name_included() {
-    // F is considered "not simply bounded" because it expands to a type that
-    // refers to C, which is not simply bounded.
-    UnlinkedTypedef typedef = serializeTypedefText(
-        'typedef F = void Function(C c); class C<T extends C<T>> {}');
-    expect(typedef.notSimplyBoundedSlot, isNot(0));
-    if (!skipFullyLinkedData) {
-      expect(linked.units[0].notSimplyBounded,
-          contains(typedef.notSimplyBoundedSlot));
-    }
-  }
-
-  test_typedef_notSimplyBounded_dependency_via_param_type_new_style_name_omitted() {
-    // F is considered "not simply bounded" because it expands to a type that
-    // refers to C, which is not simply bounded.
-    UnlinkedTypedef typedef = serializeTypedefText(
-        'typedef F = void Function(C); class C<T extends C<T>> {}');
-    expect(typedef.notSimplyBoundedSlot, isNot(0));
-    if (!skipFullyLinkedData) {
-      expect(linked.units[0].notSimplyBounded,
-          contains(typedef.notSimplyBoundedSlot));
-    }
-  }
-
-  test_typedef_notSimplyBounded_dependency_via_param_type_old_style() {
-    // F is considered "not simply bounded" because it expands to a type that
-    // refers to C, which is not simply bounded.
-    UnlinkedTypedef typedef =
-        serializeTypedefText('typedef void F(C c); class C<T extends C<T>> {}');
-    expect(typedef.notSimplyBoundedSlot, isNot(0));
-    if (!skipFullyLinkedData) {
-      expect(linked.units[0].notSimplyBounded,
-          contains(typedef.notSimplyBoundedSlot));
-    }
-  }
-
-  test_typedef_notSimplyBounded_dependency_via_return_type_new_style() {
-    // F is considered "not simply bounded" because it expands to a type that
-    // refers to C, which is not simply bounded.
-    UnlinkedTypedef typedef = serializeTypedefText(
-        'typedef F = C Function(); class C<T extends C<T>> {}');
-    expect(typedef.notSimplyBoundedSlot, isNot(0));
-    if (!skipFullyLinkedData) {
-      expect(linked.units[0].notSimplyBounded,
-          contains(typedef.notSimplyBoundedSlot));
-    }
-  }
-
-  test_typedef_notSimplyBounded_dependency_via_return_type_old_style() {
-    // F is considered "not simply bounded" because it expands to a type that
-    // refers to C, which is not simply bounded.
-    UnlinkedTypedef typedef =
-        serializeTypedefText('typedef C F(); class C<T extends C<T>> {}');
-    expect(typedef.notSimplyBoundedSlot, isNot(0));
-    if (!skipFullyLinkedData) {
-      expect(linked.units[0].notSimplyBounded,
-          contains(typedef.notSimplyBoundedSlot));
-    }
-  }
-
-  test_typedef_param_none() {
-    UnlinkedTypedef type = serializeTypedefText('typedef F();');
-    expect(type.parameters, isEmpty);
-  }
-
-  test_typedef_param_order() {
-    UnlinkedTypedef type = serializeTypedefText('typedef F(x, y);');
-    expect(type.parameters, hasLength(2));
-    expect(type.parameters[0].name, 'x');
-    expect(type.parameters[1].name, 'y');
-  }
-
-  test_typedef_private() {
-    serializeTypedefText('typedef _F();', '_F');
-    expect(unlinkedUnits[0].publicNamespace.names, isEmpty);
-  }
-
-  test_typedef_reference_generic() {
-    EntityRef typeRef =
-        serializeTypeText('F', otherDeclarations: 'typedef void F<A, B>();');
-    checkTypeRef(typeRef, null, 'F',
-        numTypeParameters: 2, expectedKind: ReferenceKind.typedef);
-  }
-
-  test_typedef_reference_generic_imported() {
-    addNamedSource('/lib.dart', 'typedef void F<A, B>();');
-    EntityRef typeRef =
-        serializeTypeText('F', otherDeclarations: 'import "lib.dart";');
-    checkTypeRef(typeRef, absUri('/lib.dart'), 'F',
-        numTypeParameters: 2, expectedKind: ReferenceKind.typedef);
-  }
-
-  test_typedef_return_type_explicit() {
-    UnlinkedTypedef type = serializeTypedefText('typedef int F();');
-    checkTypeRef(type.returnType, 'dart:core', 'int');
-  }
-
-  test_typedef_type_param_in_parameter() {
-    UnlinkedTypedef type = serializeTypedefText('typedef F<T>(T t);');
-    checkParamTypeRef(type.parameters[0].type, 1);
-    expect(unlinkedUnits[0].publicNamespace.names[0].numTypeParameters, 1);
-  }
-
-  test_typedef_type_param_in_return_type() {
-    UnlinkedTypedef type = serializeTypedefText('typedef T F<T>();');
-    checkParamTypeRef(type.returnType, 1);
-  }
-
-  test_typedef_type_param_none() {
-    UnlinkedTypedef type = serializeTypedefText('typedef F();');
-    expect(type.typeParameters, isEmpty);
-  }
-
-  test_typedef_type_param_order() {
-    UnlinkedTypedef type = serializeTypedefText('typedef F<T, U>();');
-    expect(type.typeParameters, hasLength(2));
-    expect(type.typeParameters[0].name, 'T');
-    expect(type.typeParameters[1].name, 'U');
-  }
-
-  test_unit_codeRange() {
-    serializeLibraryText('  int a = 1;  ');
-    UnlinkedUnit unit = unlinkedUnits[0];
-    _assertCodeRange(unit.codeRange, 0, 14);
-  }
-
-  test_unresolved_export() {
-    allowMissingFiles = true;
-    serializeLibraryText("export 'foo.dart';", allowErrors: true);
-    expect(unlinkedUnits[0].publicNamespace.exports, hasLength(1));
-    expect(unlinkedUnits[0].publicNamespace.exports[0].uri, 'foo.dart');
-    expect(linked.exportDependencies, hasLength(1));
-    checkDependency(linked.exportDependencies[0], absUri('/foo.dart'));
-  }
-
-  test_unresolved_import() {
-    allowMissingFiles = true;
-    serializeLibraryText("import 'foo.dart';", allowErrors: true);
-    expect(unlinkedUnits[0].imports, hasLength(2));
-    expect(unlinkedUnits[0].imports[0].uri, 'foo.dart');
-    // Note: imports[1] is the implicit import of dart:core.
-    expect(unlinkedUnits[0].imports[1].isImplicit, true);
-    expect(linked.importDependencies, hasLength(2));
-    checkDependency(linked.importDependencies[0], absUri('/foo.dart'));
-  }
-
-  test_unresolved_part() {
-    allowMissingFiles = true;
-    serializeLibraryText("part 'foo.dart';", allowErrors: true);
-    expect(unlinkedUnits[0].publicNamespace.parts, hasLength(1));
-    expect(unlinkedUnits[0].publicNamespace.parts[0], 'foo.dart');
-  }
-
-  test_unresolved_reference_in_multiple_parts() {
-    addNamedSource('/a.dart', 'part of foo; int x; Unresolved y;');
-    serializeLibraryText('library foo; part "a.dart"; Unresolved z;',
-        allowErrors: true);
-    // The unresolved types in the defining compilation unit and the part
-    // should both work correctly even though they use different reference
-    // indices.
-    checkUnresolvedTypeRef(
-        unlinkedUnits[0].variables[0].type, null, 'Unresolved');
-    checkUnresolvedTypeRef(
-        unlinkedUnits[1].variables[1].type, null, 'Unresolved',
-        linkedSourceUnit: linked.units[1],
-        unlinkedSourceUnit: unlinkedUnits[1]);
-  }
-
-  test_unresolved_reference_shared() {
-    // Both `x` and `y` use unresolved identifier `C` as their type.  Verify
-    // that they both use the same unresolved reference.
-    serializeLibraryText('C x; C y;', allowErrors: true);
-    EntityRef xType = findVariable('x').type;
-    EntityRef yType = findVariable('y').type;
-    expect(xType.reference, yType.reference);
-  }
-
-  test_unused_type_parameter() {
-    if (skipFullyLinkedData) {
-      return;
-    }
-    UnlinkedVariable variable = serializeVariableText('''
-class C<T> {
-  void f() {}
-}
-C<int> c;
-var v = c.f;
-''');
-    EntityRef type =
-        getTypeRefForSlot(variable.initializer.inferredReturnTypeSlot);
-    expect(type.typeArguments, hasLength(1));
-    checkLinkedTypeRef(type.typeArguments[0], 'dart:core', 'int');
-  }
-
-  test_variable() {
-    String text = 'int i;';
-    UnlinkedVariable v = serializeVariableText(text, variableName: 'i');
-    expect(v.nameOffset, text.indexOf('i;'));
-    expect(findExecutable('i'), isNull);
-    expect(findExecutable('i='), isNull);
-    expect(unlinkedUnits[0].publicNamespace.names, hasLength(2));
-    expect(unlinkedUnits[0].publicNamespace.names[0].kind,
-        ReferenceKind.topLevelPropertyAccessor);
-    expect(unlinkedUnits[0].publicNamespace.names[0].name, 'i');
-    expect(unlinkedUnits[0].publicNamespace.names[0].numTypeParameters, 0);
-    expect(unlinkedUnits[0].publicNamespace.names[1].kind,
-        ReferenceKind.topLevelPropertyAccessor);
-    expect(unlinkedUnits[0].publicNamespace.names[1].name, 'i=');
-    expect(unlinkedUnits[0].publicNamespace.names[1].numTypeParameters, 0);
-  }
-
-  test_variable_codeRange() {
-    serializeLibraryText(' int a = 1, b = 22;');
-    List<UnlinkedVariable> variables = unlinkedUnits[0].variables;
-    _assertCodeRange(variables[0].codeRange, 1, 9);
-    _assertCodeRange(variables[1].codeRange, 12, 6);
-  }
-
-  test_variable_const() {
-    UnlinkedVariable variable =
-        serializeVariableText('const int i = 0;', variableName: 'i');
-    expect(variable.isConst, isTrue);
-  }
-
-  test_variable_documented() {
-    String text = '''
-// Extra comment so doc comment offset != 0
-/**
- * Docs
- */
-var v;''';
-    UnlinkedVariable variable = serializeVariableText(text);
-    expect(variable.documentationComment, isNotNull);
-    checkDocumentationComment(variable.documentationComment, text);
-  }
-
-  test_variable_explicit_dynamic() {
-    UnlinkedVariable variable = serializeVariableText('dynamic v;');
-    checkDynamicTypeRef(variable.type);
-  }
-
-  test_variable_implicit_dynamic() {
-    UnlinkedVariable variable = serializeVariableText('var v;');
-    expect(variable.type, isNull);
-  }
-
-  test_variable_inferred_type_explicit_initialized() {
-    UnlinkedVariable v = serializeVariableText('int v = 0;');
-    expect(v.inferredTypeSlot, 0);
-  }
-
-  test_variable_inferred_type_implicit_initialized() {
-    UnlinkedVariable v = serializeVariableText('var v = 0;');
-    checkInferredTypeSlot(v.inferredTypeSlot, 'dart:core', 'int');
-  }
-
-  test_variable_inferred_type_implicit_uninitialized() {
-    UnlinkedVariable v = serializeVariableText('var v;');
-    expect(v.inferredTypeSlot, 0);
-  }
-
-  test_variable_initializer() {
-    UnlinkedVariable variable =
-        serializeVariableText('int i = 0;', variableName: 'i');
-    expect(variable.initializer.bodyExpr, isNull);
-  }
-
-  test_variable_initializer_final() {
-    UnlinkedVariable variable =
-        serializeVariableText('final int i = 0;', variableName: 'i');
-    expect(variable.isFinal, isTrue);
-    expect(variable.initializer.bodyExpr, isNull);
-  }
-
-  test_variable_initializer_final_untyped() {
-    if (skipFullyLinkedData) return;
-    UnlinkedVariable variable = serializeVariableText('final v = 0;');
-    var typeRef = getTypeRefForSlot(variable.inferredTypeSlot);
-    checkLinkedTypeRef(typeRef, 'dart:core', 'int');
-    if (containsNonConstExprs) {
-      expect(variable.initializer.bodyExpr, isNotNull);
-    } else {
-      expect(variable.initializer.bodyExpr, isNull);
-    }
-  }
-
-  test_variable_initializer_literal() {
-    UnlinkedVariable variable = serializeVariableText('var v = 42;');
-    UnlinkedExecutable initializer = variable.initializer;
-    expect(initializer, isNotNull);
-    expect(initializer.nameOffset, 8);
-    expect(initializer.name, isEmpty);
-    expect(initializer.localFunctions, isEmpty);
-  }
-
-  test_variable_initializer_noInitializer() {
-    UnlinkedVariable variable = serializeVariableText('var v;');
-    expect(variable.initializer, isNull);
-  }
-
-  test_variable_initializer_untyped() {
-    if (skipFullyLinkedData) return;
-    UnlinkedVariable variable = serializeVariableText('var v = 0;');
-    var typeRef = getTypeRefForSlot(variable.inferredTypeSlot);
-    checkLinkedTypeRef(typeRef, 'dart:core', 'int');
-    if (containsNonConstExprs) {
-      expect(variable.initializer.bodyExpr, isNotNull);
-    } else {
-      expect(variable.initializer.bodyExpr, isNull);
-    }
-  }
-
-  test_variable_initializer_withLocals() {
-    String text = 'var v = <dynamic, dynamic>{"1": () { f1() {} var v1; }, '
-        '"2": () { f2() {} var v2; }};';
-    UnlinkedVariable variable = serializeVariableText(text);
-    UnlinkedExecutable initializer = variable.initializer;
-    expect(initializer, isNotNull);
-    expect(initializer.nameOffset, text.indexOf('<dynamic, dynamic>{"1'));
-    expect(initializer.name, isEmpty);
-    expect(initializer.localFunctions, hasLength(2));
-    // closure: () { f1() {} var v1; }
-    {
-      UnlinkedExecutable closure = initializer.localFunctions[0];
-      expect(closure.nameOffset, text.indexOf('() { f1()'));
-      expect(closure.name, isEmpty);
-      // closure - f1
-      expect(closure.localFunctions, hasLength(1));
-      expect(closure.localFunctions[0].name, 'f1');
-      expect(closure.localFunctions[0].nameOffset, text.indexOf('f1()'));
-    }
-    // closure: () { f2() {} var v2; }
-    {
-      UnlinkedExecutable closure = initializer.localFunctions[1];
-      expect(closure.nameOffset, text.indexOf('() { f2()'));
-      expect(closure.name, isEmpty);
-      // closure - f1
-      expect(closure.localFunctions, hasLength(1));
-      expect(closure.localFunctions[0].name, 'f2');
-      expect(closure.localFunctions[0].nameOffset, text.indexOf('f2()'));
-    }
-  }
-
-  test_variable_late() {
-    featureSet = enableNnbd;
-    UnlinkedVariable variable =
-        serializeVariableText('late int i;', variableName: 'i');
-    expect(variable.isLate, isTrue);
-    expect(variable.isStatic, isFalse);
-    expect(variable.isConst, isFalse);
-    expect(variable.isFinal, isFalse);
-  }
-
-  test_variable_name() {
-    UnlinkedVariable variable =
-        serializeVariableText('int i;', variableName: 'i');
-    expect(variable.name, 'i');
-  }
-
-  test_variable_no_flags() {
-    UnlinkedVariable variable =
-        serializeVariableText('int i;', variableName: 'i');
-    expect(variable.isLate, isFalse);
-    expect(variable.isStatic, isFalse);
-    expect(variable.isConst, isFalse);
-    expect(variable.isFinal, isFalse);
-  }
-
-  test_variable_non_const() {
-    UnlinkedVariable variable =
-        serializeVariableText('int i = 0;', variableName: 'i');
-    expect(variable.isConst, isFalse);
-  }
-
-  test_variable_non_final() {
-    UnlinkedVariable variable =
-        serializeVariableText('int i;', variableName: 'i');
-    expect(variable.isFinal, isFalse);
-  }
-
-  test_variable_non_static() {
-    UnlinkedVariable variable =
-        serializeClassText('class C { int i; }').fields[0];
-    expect(variable.isLate, isFalse);
-    expect(variable.isStatic, isFalse);
-  }
-
-  test_variable_non_static_top_level() {
-    // Top level variables are considered non-static.
-    UnlinkedVariable variable =
-        serializeVariableText('int i;', variableName: 'i');
-    expect(variable.isLate, isFalse);
-    expect(variable.isStatic, isFalse);
-  }
-
-  test_variable_private() {
-    serializeVariableText('int _i;', variableName: '_i');
-    expect(unlinkedUnits[0].publicNamespace.names, isEmpty);
-  }
-
-  test_variable_static() {
-    UnlinkedVariable variable =
-        serializeClassText('class C { static int i; }').fields[0];
-    expect(variable.isLate, isFalse);
-    expect(variable.isStatic, isTrue);
-  }
-
-  test_variable_type() {
-    UnlinkedVariable variable =
-        serializeVariableText('int i;', variableName: 'i');
-    checkTypeRef(variable.type, 'dart:core', 'int');
-  }
-
-  /// Assert that serializing the given [expr] of form `(a op= 1 + 2) + 3`
-  /// uses the given [expectedAssignOperator].
-  void _assertAssignmentOperator(
-      String expr, UnlinkedExprAssignOperator expectedAssignOperator) {
-    UnlinkedVariable variable = serializeVariableText('''
-int a = 0;
-final v = $expr;
-    ''');
-    assertUnlinkedConst(variable.initializer.bodyExpr, expr,
-        isValidConst: false,
-        operators: [
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.add,
-          UnlinkedExprOperation.assignToRef,
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.add,
-        ],
-        assignmentOperators: [expectedAssignOperator],
-        ints: [1, 2, 3],
-        strings: [],
-        referenceValidators: [
-          (EntityRef r) => checkTypeRef(r, null, 'a',
-              expectedKind: ReferenceKind.topLevelPropertyAccessor)
-        ],
-        forTypeInferenceOnly: true);
-  }
-
-  void _assertCodeRange(CodeRange codeRange, int offset, int length) {
-    expect(codeRange, isNotNull);
-    expect(codeRange.offset, offset);
-    expect(codeRange.length, length);
-  }
-
-  void _assertParameterVisible(
-      String code, UnlinkedParam p, String visibleBegin, String visibleEnd) {
-    int expectedVisibleOffset = code.indexOf(visibleBegin);
-    int expectedVisibleLength =
-        code.indexOf(visibleEnd) - expectedVisibleOffset + 1;
-    expect(p.visibleOffset, expectedVisibleOffset);
-    expect(p.visibleLength, expectedVisibleLength);
-  }
-
-  void _assertParameterZeroVisibleRange(UnlinkedParam p) {
-    expect(p.visibleOffset, isZero);
-    expect(p.visibleLength, isZero);
-  }
-
-  /// Assert that the [expr] of the form `++a + 2` is serialized with the
-  /// [expectedAssignmentOperator].
-  void _assertRefPrefixPostfixIncrementDecrement(
-      String expr, UnlinkedExprAssignOperator expectedAssignmentOperator) {
-    UnlinkedVariable variable = serializeVariableText('''
-int a = 0;
-final v = $expr;
-''');
-    assertUnlinkedConst(variable.initializer.bodyExpr, expr,
-        isValidConst: false,
-        operators: [
-          UnlinkedExprOperation.assignToRef,
-          UnlinkedExprOperation.pushInt,
-          UnlinkedExprOperation.add,
-        ],
-        assignmentOperators: [expectedAssignmentOperator],
-        ints: [2],
-        strings: [],
-        referenceValidators: [
-          (EntityRef r) => checkTypeRef(r, null, 'a',
-              expectedKind: ReferenceKind.topLevelPropertyAccessor)
-        ],
-        forTypeInferenceOnly: true);
-  }
-
-  String _normalizeTokenString(String tokenString) {
-    // Note: to normalize the token string it's not sufficient to tokenize it
-    // and then pass the tokens to `tokensToString`; we also need to parse it
-    // because parsing modifies the token stream (splitting up `[]`, `>>`, and
-    // `>>>` tokens when circumstances warrant).
-    //
-    // We wrap the expression in "f() async => ...;" to ensure that the await
-    // keyword is properly parsed.
-    var sourceText = 'f() async => $tokenString;';
-    var errorListener = AnalysisErrorListener.NULL_LISTENER;
-    var reader = new CharSequenceReader(sourceText);
-    var stringSource = new StringSource(sourceText, null);
-    var scanner = new Scanner(stringSource, reader, errorListener)
-      ..configureFeatures(featureSet);
-    var startToken = scanner.tokenize();
-    var parser =
-        new Parser(stringSource, errorListener, featureSet: featureSet);
-    var compilationUnit = parser.parseCompilationUnit(startToken);
-    var f = compilationUnit.declarations[0] as FunctionDeclaration;
-    var body = f.functionExpression.body as ExpressionFunctionBody;
-    var expression = body.expression;
-    return tokensToString(expression.beginToken, expression.endToken);
-  }
-}
-
-/// Description of expectations for a prelinked prefix reference.
-class _PrefixExpectation {
-  final ReferenceKind kind;
-  final String name;
-  final String absoluteUri;
-  final int numTypeParameters;
-
-  _PrefixExpectation(this.kind, this.name,
-      {this.absoluteUri, this.numTypeParameters: 0});
-}
diff --git a/pkg/analyzer/test/src/summary/test_all.dart b/pkg/analyzer/test/src/summary/test_all.dart
index 184c0e7..40dd736 100644
--- a/pkg/analyzer/test/src/summary/test_all.dart
+++ b/pkg/analyzer/test/src/summary/test_all.dart
@@ -6,32 +6,22 @@
 
 import 'api_signature_test.dart' as api_signature;
 import 'dependency_walker_test.dart' as dependency_walker;
-import 'expr_builder_test.dart' as expr_builder;
 import 'flat_buffers_test.dart' as flat_buffers;
 import 'in_summary_source_test.dart' as in_summary_source;
-import 'linker_test.dart' as linker;
 import 'name_filter_test.dart' as name_filter;
 import 'package_bundle_reader_test.dart' as package_bundle_reader;
-import 'prelinker_test.dart' as prelinker;
 import 'resynthesize_ast2_test.dart' as resynthesize_ast2;
-import 'resynthesize_ast_test.dart' as resynthesize_ast;
-import 'summarize_ast_strong_test.dart' as summarize_ast_strong;
 import 'top_level_inference_test.dart' as top_level_inference;
 
 main() {
   defineReflectiveSuite(() {
     api_signature.main();
     dependency_walker.main();
-    expr_builder.main();
     flat_buffers.main();
     in_summary_source.main();
-    linker.main();
     name_filter.main();
     package_bundle_reader.main();
-    prelinker.main();
     resynthesize_ast2.main();
-    resynthesize_ast.main();
-    summarize_ast_strong.main();
     top_level_inference.main();
   }, name: 'summary');
 }
diff --git a/pkg/analyzer/test/src/summary/test_strategies.dart b/pkg/analyzer/test/src/summary/test_strategies.dart
index 7f0aa49..83e49ed 100644
--- a/pkg/analyzer/test/src/summary/test_strategies.dart
+++ b/pkg/analyzer/test/src/summary/test_strategies.dart
@@ -8,33 +8,17 @@
 import 'package:analyzer/dart/ast/token.dart';
 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';
 import 'package:analyzer/src/generated/parser.dart';
 import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/generated/utilities_dart.dart';
 import 'package:analyzer/src/summary/format.dart';
 import 'package:analyzer/src/summary/idl.dart';
-import 'package:analyzer/src/summary/link.dart';
-import 'package:analyzer/src/summary/package_bundle_reader.dart';
-import 'package:analyzer/src/summary/prelink.dart';
-import 'package:analyzer/src/summary/summarize_ast.dart';
 import 'package:analyzer/src/summary/summarize_elements.dart';
 import 'package:analyzer/src/test_utilities/mock_sdk.dart';
-import 'package:path/path.dart' show posix;
-import 'package:test/test.dart';
 
 import 'resynthesize_common.dart';
 
-/// Convert the given Posix style file [path] to the corresponding absolute URI.
-String absUri(String path) {
-  String absolutePath = posix.absolute(path);
-  return posix.toUri(absolutePath).toString();
-}
-
 CompilationUnit parseText(
   String text,
   FeatureSet featureSet,
@@ -56,40 +40,6 @@
   return unit;
 }
 
-/// Verify invariants of the given [linkedLibrary].
-void _validateLinkedLibrary(LinkedLibrary linkedLibrary) {
-  for (LinkedUnit unit in linkedLibrary.units) {
-    for (LinkedReference reference in unit.references) {
-      switch (reference.kind) {
-        case ReferenceKind.classOrEnum:
-        case ReferenceKind.topLevelPropertyAccessor:
-        case ReferenceKind.topLevelFunction:
-        case ReferenceKind.typedef:
-          // This reference can have either a zero or a nonzero dependency,
-          // since it refers to top level element which might or might not be
-          // imported from another library.
-          break;
-        case ReferenceKind.prefix:
-          // Prefixes should have a dependency of 0, since they come from the
-          // current library.
-          expect(reference.dependency, 0,
-              reason: 'Nonzero dependency for prefix');
-          break;
-        case ReferenceKind.unresolved:
-          // Unresolved references always have a dependency of 0.
-          expect(reference.dependency, 0,
-              reason: 'Nonzero dependency for undefined');
-          break;
-        default:
-          // This reference should have a dependency of 0, since it refers to
-          // an element that is contained within some other element.
-          expect(reference.dependency, 0,
-              reason: 'Nonzero dependency for ${reference.kind}');
-      }
-    }
-  }
-}
-
 /// Abstract base class for tests of summary resynthesis.
 ///
 /// Test classes should not extend this class directly; they should extend a
@@ -119,14 +69,9 @@
   Source addSource(String path, String contents);
 
   Source addTestSource(String code, [Uri uri]);
-
-  void checkMinimalResynthesisWork(TestSummaryResynthesizer resynthesizer,
-      Uri expectedLibraryUri, List<Uri> expectedUnitUriList);
-
-  TestSummaryResynthesizer encodeLibrary(Source source);
 }
 
-/// Implementation of [SummaryBlackBoxTestStrategy] that drives summary
+/// Implementation of [ResynthesizeTestStrategy] that drives summary
 /// generation using the old two-phase API.
 class ResynthesizeTestStrategyTwoPhase extends AbstractResynthesizeTest
     implements ResynthesizeTestStrategy {
@@ -142,129 +87,6 @@
 
   @override
   bool get isAstBasedSummary => false;
-
-  TestSummaryResynthesizer encodeLibrary(Source source) {
-    _serializeLibrary(source);
-
-    PackageBundle bundle =
-        new PackageBundle.fromBuffer(bundleAssembler.assemble().toBuffer());
-
-    Map<String, UnlinkedUnit> unlinkedSummaries = <String, UnlinkedUnit>{};
-    for (int i = 0; i < bundle.unlinkedUnitUris.length; i++) {
-      String uri = bundle.unlinkedUnitUris[i];
-      unlinkedSummaries[uri] = bundle.unlinkedUnits[i];
-    }
-
-    LinkedLibrary getDependency(String absoluteUri) {
-      Map<String, LinkedLibrary> sdkLibraries =
-          SerializedMockSdk.instance.uriToLinkedLibrary;
-      LinkedLibrary linkedLibrary = sdkLibraries[absoluteUri];
-      if (linkedLibrary == null && !allowMissingFiles) {
-        fail('Linker unexpectedly requested LinkedLibrary for "$absoluteUri".'
-            '  Libraries available: ${sdkLibraries.keys}');
-      }
-      return linkedLibrary;
-    }
-
-    UnlinkedUnit getUnit(String absoluteUri) {
-      UnlinkedUnit unit = uriToUnit[absoluteUri] ??
-          SerializedMockSdk.instance.uriToUnlinkedUnit[absoluteUri];
-      if (unit == null && !allowMissingFiles) {
-        fail('Linker unexpectedly requested unit for "$absoluteUri".');
-      }
-      return unit;
-    }
-
-    Set<String> nonSdkLibraryUris = serializedSources
-        .where((Source source) => !source.isInSystemLibrary)
-        .map((Source source) => source.uri.toString())
-        .toSet();
-
-    var analysisOptions = AnalysisOptionsImpl()..contextFeatures = featureSet;
-
-    Map<String, LinkedLibrary> linkedSummaries = link(nonSdkLibraryUris,
-        getDependency, getUnit, declaredVariables, analysisOptions);
-
-    var synchronousSession =
-        SynchronousSession(analysisOptions, declaredVariables);
-    var analysisContext = RestrictedAnalysisContext(
-      synchronousSession,
-      sourceFactory,
-    );
-
-    return new TestSummaryResynthesizer(
-        analysisContext,
-        new Map<String, UnlinkedUnit>()
-          ..addAll(SerializedMockSdk.instance.uriToUnlinkedUnit)
-          ..addAll(unlinkedSummaries),
-        new Map<String, LinkedLibrary>()
-          ..addAll(SerializedMockSdk.instance.uriToLinkedLibrary)
-          ..addAll(linkedSummaries),
-        allowMissingFiles);
-  }
-
-  UnlinkedUnit _getUnlinkedUnit(Source source) {
-    if (source == null) {
-      return new UnlinkedUnitBuilder();
-    }
-
-    String uriStr = source.uri.toString();
-    {
-      UnlinkedUnit unlinkedUnitInSdk =
-          SerializedMockSdk.instance.uriToUnlinkedUnit[uriStr];
-      if (unlinkedUnitInSdk != null) {
-        return unlinkedUnitInSdk;
-      }
-    }
-    return uriToUnit.putIfAbsent(uriStr, () {
-      var file = getFile(source.fullName);
-
-      String contents;
-      if (file.exists) {
-        contents = file.readAsStringSync();
-      } else {
-        // Source does not exist.
-        if (!allowMissingFiles) {
-          fail('Unexpectedly tried to get unlinked summary for $source');
-        }
-        contents = '';
-      }
-
-      CompilationUnit unit = parseText(contents, featureSet);
-
-      UnlinkedUnitBuilder unlinkedUnit = serializeAstUnlinked(unit);
-      bundleAssembler.addUnlinkedUnit(source, unlinkedUnit);
-      return unlinkedUnit;
-    });
-  }
-
-  void _serializeLibrary(Source librarySource) {
-    if (librarySource == null || librarySource.isInSystemLibrary) {
-      return;
-    }
-    if (!serializedSources.add(librarySource)) {
-      return;
-    }
-
-    UnlinkedUnit getPart(String absoluteUri) {
-      Source source = sourceFactory.forUri(absoluteUri);
-      return _getUnlinkedUnit(source);
-    }
-
-    UnlinkedPublicNamespace getImport(String relativeUri) {
-      return getPart(relativeUri)?.publicNamespace;
-    }
-
-    UnlinkedUnit definingUnit = _getUnlinkedUnit(librarySource);
-    if (definingUnit != null) {
-      LinkedLibraryBuilder linkedLibrary = prelink(librarySource.uri.toString(),
-          definingUnit, getPart, getImport, declaredVariables);
-      linkedLibrary.dependencies.skip(1).forEach((LinkedDependency d) {
-        Source source = sourceFactory.forUri(d.uri);
-        _serializeLibrary(source);
-      });
-    }
-  }
 }
 
 /// [SerializedMockSdk] is a singleton class representing the result of
@@ -303,355 +125,3 @@
     }
   }
 }
-
-/// Abstract base class for tests involving summaries.
-///
-/// Test classes should not extend this class directly; they should extend a
-/// class that implements this class with methods that drive summary generation.
-/// The tests themselves can then be provided via mixin, allowing summaries to
-/// be tested in a variety of ways.
-abstract class SummaryBaseTestStrategy {
-  /// The set of features enabled in this test.
-  FeatureSet featureSet;
-
-  /// Add the given package bundle as a dependency so that it may be referenced
-  /// by the files under test.
-  void addBundle(String path, PackageBundle bundle);
-
-  /// Add the given source file so that it may be referenced by the file under
-  /// test.
-  void addNamedSource(String filePath, String contents);
-
-  /// Link together the given file, along with any other files passed to
-  /// [addNamedSource], to form a package bundle.  Reset the state of the
-  /// buffers accumulated by [addNamedSource] and [addBundle] so that further
-  /// bundles can be created.
-  PackageBundleBuilder createPackageBundle(String text,
-      {String path: '/test.dart', String uri});
-}
-
-/// Abstract base class for black-box tests of summaries.
-///
-/// Test classes should not extend this class directly; they should extend a
-/// class that implements this class with methods that drive summary generation.
-/// The tests themselves can then be provided via mixin, allowing summaries to
-/// be tested in a variety of ways.
-abstract class SummaryBlackBoxTestStrategy extends SummaryBaseTestStrategy {
-  /// A test will set this to `true` if it contains `import`, `export`, or
-  /// `part` declarations that deliberately refer to non-existent files.
-  void set allowMissingFiles(bool value);
-
-  /// Indicates whether the summary contains expressions for non-const fields.
-  ///
-  /// When one-phase summarization is in use, only const field initializer
-  /// expressions are stored in the summary.
-  bool get containsNonConstExprs;
-
-  /// Get access to the linked summary that results from serializing and
-  /// then deserializing the library under test.
-  LinkedLibrary get linked;
-
-  /// `true` if the linked portion of the summary only contains prelinked data.
-  /// This happens because we don't yet have a full linker; only a prelinker.
-  bool get skipFullyLinkedData;
-
-  /// Get access to the unlinked compilation unit summaries that result from
-  /// serializing and deserializing the library under test.
-  List<UnlinkedUnit> get unlinkedUnits;
-
-  /// Serialize the given library [text], then deserialize it and store its
-  /// summary in [lib].
-  void serializeLibraryText(String text, {bool allowErrors: false});
-}
-
-/// Implementation of [SummaryBlackBoxTestStrategy] that drives summary
-/// generation using the old two-phase API, and exercises the pre-linker only.
-class SummaryBlackBoxTestStrategyPrelink
-    extends _SummaryBlackBoxTestStrategyTwoPhase
-    implements SummaryBlackBoxTestStrategy {
-  @override
-  bool get skipFullyLinkedData => true;
-
-  @override
-  void serializeLibraryText(String text, {bool allowErrors: false}) {
-    super.serializeLibraryText(text, allowErrors: allowErrors);
-
-    UnlinkedUnit getPart(String absoluteUri) {
-      return _linkerInputs.getUnit(absoluteUri);
-    }
-
-    UnlinkedPublicNamespace getImport(String absoluteUri) {
-      return getPart(absoluteUri)?.publicNamespace;
-    }
-
-    linked = new LinkedLibrary.fromBuffer(prelink(
-            _linkerInputs._testDartUri.toString(),
-            _linkerInputs._unlinkedDefiningUnit,
-            getPart,
-            getImport,
-            DeclaredVariables())
-        .toBuffer());
-    _validateLinkedLibrary(linked);
-  }
-}
-
-/// Implementation of [SummaryBlackBoxTestStrategy] that drives summary
-/// generation using the old two-phase API, and exercises full summary
-/// generation.
-class SummaryBlackBoxTestStrategyTwoPhase
-    extends _SummaryBlackBoxTestStrategyTwoPhase
-    implements SummaryBlackBoxTestStrategy {
-  @override
-  bool get skipFullyLinkedData => false;
-}
-
-/// Abstract base class for unit tests of the summary linker.
-///
-/// Test classes should not extend this class directly; they should extend a
-/// class that implements this class with methods that drive summary generation.
-/// The tests themselves can then be provided via mixin, allowing summaries to
-/// be tested in a variety of ways.
-abstract class SummaryLinkerTestStrategy extends SummaryBaseTestStrategy {
-  Linker get linker;
-
-  /// Gets the URI of the main library under test.
-  ///
-  /// May only be called after [createLinker].
-  Uri get testDartUri;
-
-  LibraryElementInBuildUnit get testLibrary;
-
-  void createLinker(String text, {String path: '/test.dart'});
-}
-
-/// Implementation of [SummaryLinkerTestStrategy] that drives summary generation
-/// using the old two-phase API.
-class SummaryLinkerTestStrategyTwoPhase extends _SummaryBaseTestStrategyTwoPhase
-    implements SummaryLinkerTestStrategy {
-  LibraryElementInBuildUnit _testLibrary;
-
-  @override
-  Linker linker;
-
-  @override
-  Uri get testDartUri => _linkerInputs._testDartUri;
-
-  @override
-  LibraryElementInBuildUnit get testLibrary =>
-      _testLibrary ??= linker.getLibrary(_linkerInputs._testDartUri)
-          as LibraryElementInBuildUnit;
-
-  @override
-  bool get _allowMissingFiles => false;
-
-  @override
-  void createLinker(String text, {String path: '/test.dart'}) {
-    _linkerInputs = _createLinkerInputs(text, path: path);
-    Map<String, LinkedLibraryBuilder> linkedLibraries = setupForLink(
-        _linkerInputs.linkedLibraries,
-        _linkerInputs.getUnit,
-        _linkerInputs.declaredVariables);
-    linker = new Linker(linkedLibraries, _linkerInputs.getDependency,
-        _linkerInputs.getUnit, null, analysisOptions);
-  }
-}
-
-/// [_FilesToLink] stores information about a set of files to be linked
-/// together.  This information is grouped into a class to allow it to be reset
-/// easily when [_SummaryBaseTestStrategyTwoPhase._createLinkerInputs] is
-/// called.
-///
-/// The generic parameter [U] is the type of information stored for each
-/// compilation unit.
-class _FilesToLink<U> {
-  /// Map from absolute URI to the [U] for each compilation unit passed to
-  /// [addNamedSource].
-  Map<String, U> uriToUnit = <String, U>{};
-
-  /// Information about summaries to be included in the link process.
-  SummaryDataStore summaryDataStore = new SummaryDataStore([]);
-}
-
-/// Instances of the class [_LinkerInputs] encapsulate the necessary information
-/// to pass to the summary linker.
-class _LinkerInputs {
-  final bool _allowMissingFiles;
-  final Map<String, UnlinkedUnit> _uriToUnit;
-  final Uri _testDartUri;
-  final UnlinkedUnit _unlinkedDefiningUnit;
-  final Map<String, LinkedLibrary> _dependentLinkedLibraries;
-  final Map<String, UnlinkedUnit> _dependentUnlinkedUnits;
-
-  _LinkerInputs(
-      this._allowMissingFiles,
-      this._uriToUnit,
-      this._testDartUri,
-      this._unlinkedDefiningUnit,
-      this._dependentLinkedLibraries,
-      this._dependentUnlinkedUnits);
-
-  DeclaredVariables get declaredVariables => DeclaredVariables();
-
-  Set<String> get linkedLibraries => _uriToUnit.keys.toSet();
-
-  LinkedLibrary getDependency(String absoluteUri) {
-    Map<String, LinkedLibrary> sdkLibraries =
-        SerializedMockSdk.instance.uriToLinkedLibrary;
-    LinkedLibrary linkedLibrary =
-        sdkLibraries[absoluteUri] ?? _dependentLinkedLibraries[absoluteUri];
-    if (linkedLibrary == null && !_allowMissingFiles) {
-      Set<String> librariesAvailable = sdkLibraries.keys.toSet();
-      librariesAvailable.addAll(_dependentLinkedLibraries.keys);
-      fail('Linker unexpectedly requested LinkedLibrary for "$absoluteUri".'
-          '  Libraries available: ${librariesAvailable.toList()}');
-    }
-    return linkedLibrary;
-  }
-
-  UnlinkedUnit getUnit(String absoluteUri) {
-    if (absoluteUri == null) {
-      return null;
-    }
-    UnlinkedUnit unit = _uriToUnit[absoluteUri] ??
-        SerializedMockSdk.instance.uriToUnlinkedUnit[absoluteUri] ??
-        _dependentUnlinkedUnits[absoluteUri];
-    if (unit == null && !_allowMissingFiles) {
-      fail('Linker unexpectedly requested unit for "$absoluteUri".');
-    }
-    return unit;
-  }
-}
-
-/// Implementation of [SummaryBaseTestStrategy] that drives summary generation
-/// using the old two-phase API.
-abstract class _SummaryBaseTestStrategyTwoPhase
-    implements SummaryBaseTestStrategy {
-  /// Information about the files to be linked.
-  _FilesToLink<UnlinkedUnitBuilder> _filesToLink =
-      new _FilesToLink<UnlinkedUnitBuilder>();
-
-  @override
-  FeatureSet featureSet = FeatureSet.forTesting();
-
-  _LinkerInputs _linkerInputs;
-
-  AnalysisOptions get analysisOptions =>
-      AnalysisOptionsImpl()..contextFeatures = featureSet;
-
-  bool get _allowMissingFiles;
-
-  @override
-  void addBundle(String path, PackageBundle bundle) {
-    _filesToLink.summaryDataStore.addBundle(path, bundle);
-  }
-
-  @override
-  void addNamedSource(String filePath, String contents) {
-    CompilationUnit unit = parseText(contents, featureSet);
-    UnlinkedUnitBuilder unlinkedUnit = serializeAstUnlinked(unit);
-    _filesToLink.uriToUnit[absUri(filePath)] = unlinkedUnit;
-  }
-
-  @override
-  PackageBundleBuilder createPackageBundle(String text,
-      {String path: '/test.dart', String uri}) {
-    PackageBundleAssembler assembler = new PackageBundleAssembler();
-    _LinkerInputs linkerInputs =
-        _createLinkerInputs(text, path: path, uri: uri);
-    Map<String, LinkedLibraryBuilder> linkedLibraries = link(
-        linkerInputs.linkedLibraries,
-        linkerInputs.getDependency,
-        linkerInputs.getUnit,
-        linkerInputs.declaredVariables,
-        analysisOptions);
-    linkedLibraries.forEach(assembler.addLinkedLibrary);
-    linkerInputs._uriToUnit.forEach((String uri, UnlinkedUnit unit) {
-      assembler.addUnlinkedUnitViaUri(uri, unit);
-    });
-    return assembler.assemble();
-  }
-
-  UnlinkedUnitBuilder createUnlinkedSummary(Uri uri, String text) =>
-      serializeAstUnlinked(parseText(text, featureSet));
-
-  _LinkerInputs _createLinkerInputs(String text,
-      {String path: '/test.dart', String uri}) {
-    uri ??= absUri(path);
-    Uri testDartUri = Uri.parse(uri);
-    UnlinkedUnitBuilder unlinkedDefiningUnit =
-        createUnlinkedSummary(testDartUri, text);
-    _filesToLink.uriToUnit[testDartUri.toString()] = unlinkedDefiningUnit;
-    _LinkerInputs linkerInputs = new _LinkerInputs(
-        _allowMissingFiles,
-        _filesToLink.uriToUnit,
-        testDartUri,
-        unlinkedDefiningUnit,
-        _filesToLink.summaryDataStore.linkedMap,
-        _filesToLink.summaryDataStore.unlinkedMap);
-    // Reset _filesToLink in case the test needs to start a new package bundle.
-    _filesToLink = new _FilesToLink<UnlinkedUnitBuilder>();
-    return linkerInputs;
-  }
-}
-
-/// Implementation of [SummaryBlackBoxTestStrategy] that drives summary
-/// generation using the old two-phase API.
-///
-/// Not intended to be used directly; instead use a derived class that either
-/// exercises the full summary algorithm or just pre-linking.
-abstract class _SummaryBlackBoxTestStrategyTwoPhase
-    extends _SummaryBaseTestStrategyTwoPhase
-    implements SummaryBlackBoxTestStrategy {
-  @override
-  List<UnlinkedUnit> unlinkedUnits;
-
-  @override
-  LinkedLibrary linked;
-
-  @override
-  bool _allowMissingFiles = false;
-
-  @override
-  void set allowMissingFiles(bool value) {
-    _allowMissingFiles = value;
-  }
-
-  @override
-  bool get containsNonConstExprs => true;
-
-  @override
-  void serializeLibraryText(String text, {bool allowErrors: false}) {
-    Map<String, UnlinkedUnitBuilder> uriToUnit = this._filesToLink.uriToUnit;
-    _linkerInputs = _createLinkerInputs(text);
-    linked = link(
-        _linkerInputs.linkedLibraries,
-        _linkerInputs.getDependency,
-        _linkerInputs.getUnit,
-        DeclaredVariables(),
-        analysisOptions)[_linkerInputs._testDartUri.toString()];
-    expect(linked, isNotNull);
-    _validateLinkedLibrary(linked);
-    unlinkedUnits = <UnlinkedUnit>[_linkerInputs._unlinkedDefiningUnit];
-    for (String relativeUriStr
-        in _linkerInputs._unlinkedDefiningUnit.publicNamespace.parts) {
-      Uri relativeUri;
-      try {
-        relativeUri = Uri.parse(relativeUriStr);
-      } on FormatException {
-        unlinkedUnits.add(new UnlinkedUnitBuilder());
-        continue;
-      }
-
-      UnlinkedUnit unit = uriToUnit[
-          resolveRelativeUri(_linkerInputs._testDartUri, relativeUri)
-              .toString()];
-      if (unit == null) {
-        if (!_allowMissingFiles) {
-          fail('Test referred to unknown unit $relativeUriStr');
-        }
-      } else {
-        unlinkedUnits.add(unit);
-      }
-    }
-  }
-}
diff --git a/pkg/analyzer/test/src/summary/top_level_inference_test.dart b/pkg/analyzer/test/src/summary/top_level_inference_test.dart
index f738485..6a7ed96 100644
--- a/pkg/analyzer/test/src/summary/top_level_inference_test.dart
+++ b/pkg/analyzer/test/src/summary/top_level_inference_test.dart
@@ -6,7 +6,6 @@
 
 import 'package:analyzer/dart/analysis/results.dart';
 import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/src/dart/analysis/driver.dart';
 import 'package:analyzer/src/dart/analysis/experiments.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -719,17 +718,10 @@
 import 'a.dart';
 var x = new C().f;
 ''');
-    if (AnalysisDriver.useSummary2) {
-      checkElementText(library, r'''
+    checkElementText(library, r'''
 import 'a.dart';
 int x;
 ''');
-    } else {
-      checkElementText(library, r'''
-import 'a.dart';
-dynamic x;
-''');
-    }
   }
 
   test_initializer_extractProperty_implicitlyTyped_sameLibrary() async {
diff --git a/pkg/analyzer/test/src/task/strong/inferred_type_test.dart b/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
index db5ceab..2158740 100644
--- a/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
+++ b/pkg/analyzer/test/src/task/strong/inferred_type_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:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -367,11 +366,7 @@
 ''');
     var v = mainUnit.topLevelVariables[0];
     expect(v.type.toString(), 'dynamic');
-    if (AnalysisDriver.useSummary2) {
-      expect(v.initializer.type.toString(), 'dynamic Function()');
-    } else {
-      expect(v.initializer.type.toString(), 'Null Function()');
-    }
+    expect(v.initializer.type.toString(), 'dynamic Function()');
   }
 
   test_bottom_inClosure() async {
@@ -2416,8 +2411,7 @@
   }
 
   test_infer_use_of_void() async {
-    if (AnalysisDriver.useSummary2) {
-      await checkFileElement('''
+    await checkFileElement('''
 class B {
   void f() {}
 }
@@ -2426,17 +2420,6 @@
 }
 var x = /*error:TOP_LEVEL_INSTANCE_METHOD*/new C().f();
 ''');
-    } else {
-      await checkFileElement('''
-class B {
-  void f() {}
-}
-class C extends B {
-  f() {}
-}
-var x = /*error:TOP_LEVEL_INSTANCE_METHOD*/new C()./*error:USE_OF_VOID_RESULT*/f();
-''');
-    }
   }
 
   test_inferConstsTransitively() async {
diff --git a/pkg/analyzer/tool/experiments/generate.dart b/pkg/analyzer/tool/experiments/generate.dart
index 4846520..ac968f5 100644
--- a/pkg/analyzer/tool/experiments/generate.dart
+++ b/pkg/analyzer/tool/experiments/generate.dart
@@ -9,16 +9,16 @@
 import 'package:path/path.dart';
 import 'package:yaml/yaml.dart' show YamlMap, loadYaml;
 
-import '../../test/utils/package_root.dart' as pkgRoot;
+import '../../test/utils/package_root.dart' as pkg_root;
 
 main() async {
   await GeneratedContent.generateAll(
-      normalize(join(pkgRoot.packageRoot, 'analyzer')), allTargets);
+      normalize(join(pkg_root.packageRoot, 'analyzer')), allTargets);
 }
 
 List<GeneratedContent> get allTargets {
   Map<dynamic, dynamic> experimentsYaml = loadYaml(new File(join(
-          normalize(join(pkgRoot.packageRoot, '../tools')),
+          normalize(join(pkg_root.packageRoot, '../tools')),
           'experimental_features.yaml'))
       .readAsStringSync());
 
diff --git a/pkg/analyzer/tool/messages/generate.dart b/pkg/analyzer/tool/messages/generate.dart
index e35adc8..1a20e92 100644
--- a/pkg/analyzer/tool/messages/generate.dart
+++ b/pkg/analyzer/tool/messages/generate.dart
@@ -14,18 +14,18 @@
  */
 import 'dart:io';
 
-import 'package:analyzer/error/error.dart';
 import 'package:analysis_tool/tools.dart';
+import 'package:analyzer/error/error.dart';
 import 'package:analyzer/src/dart/error/syntactic_errors.dart';
 import 'package:front_end/src/fasta/scanner.dart';
 import 'package:path/path.dart';
 import 'package:yaml/yaml.dart' show loadYaml;
 
-import '../../test/utils/package_root.dart' as pkgRoot;
+import '../../test/utils/package_root.dart' as pkg_root;
 
 main() async {
-  String analyzerPkgPath = normalize(join(pkgRoot.packageRoot, 'analyzer'));
-  String frontEndPkgPath = normalize(join(pkgRoot.packageRoot, 'front_end'));
+  String analyzerPkgPath = normalize(join(pkg_root.packageRoot, 'analyzer'));
+  String frontEndPkgPath = normalize(join(pkg_root.packageRoot, 'front_end'));
 
   Map<dynamic, dynamic> messagesYaml = loadYaml(
       new File(join(frontEndPkgPath, 'messages.yaml')).readAsStringSync());
@@ -179,6 +179,10 @@
       if (tip is String) {
         out.writeln(',correction: "$tip"');
       }
+      final hasPublishedDocs = entry['hasPublishedDocs'];
+      if (hasPublishedDocs is bool && hasPublishedDocs) {
+        out.writeln(',hasPublishedDocs:true');
+      }
       out.writeln(');');
     }
   }
diff --git a/pkg/analyzer/tool/summary/dump_inferred_types.dart b/pkg/analyzer/tool/summary/dump_inferred_types.dart
deleted file mode 100644
index ee6bb64..0000000
--- a/pkg/analyzer/tool/summary/dump_inferred_types.dart
+++ /dev/null
@@ -1,341 +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:convert';
-
-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/engine.dart';
-import 'package:analyzer/src/generated/utilities_dart.dart';
-import 'package:analyzer/src/summary/base.dart';
-import 'package:analyzer/src/summary/idl.dart';
-import 'package:analyzer/src/summary/link.dart';
-import 'package:analyzer/src/summary/package_bundle_reader.dart';
-
-/**
- * Collect the inferred types from all the summary files listed in [args] and
- * print them in alphabetical order.
- */
-main(List<String> args) {
-  SummaryDataStore summaryDataStore = new SummaryDataStore(args);
-  InferredTypeCollector collector = new InferredTypeCollector(
-      (String uri) => summaryDataStore.linkedMap[uri],
-      (String uri) => summaryDataStore.unlinkedMap[uri]);
-  collector.visitSummaryDataStore(summaryDataStore);
-  collector.dumpCollectedTypes();
-}
-
-/**
- * Visitor class that visits the contents of a summary file and collects the
- * inferred types in it.
- */
-class InferredTypeCollector {
-  UnlinkedUnit unlinkedUnit;
-  LinkedUnit linkedUnit;
-  CompilationUnitElementForLink unitForLink;
-  final Map<String, String> inferredTypes = <String, String>{};
-  List<String> typeParamsInScope = <String>[];
-  final Linker _linker;
-
-  InferredTypeCollector(
-      GetDependencyCallback getDependency, GetUnitCallback getUnit)
-      : _linker =
-            new Linker({}, getDependency, getUnit, null, AnalysisOptionsImpl());
-
-  /**
-   * If an inferred type exists matching the given [slot], record that it is the
-   * type of the entity reachable via [path].
-   */
-  void collectInferredType(int slot, String path) {
-    for (EntityRef type in linkedUnit.types) {
-      if (type.slot == slot) {
-        inferredTypes[path] = formatType(type);
-        return;
-      }
-    }
-  }
-
-  /**
-   * Collect the inferred type in summary object [obj] (if any), which is
-   * reachable via [path].
-   *
-   * This method may modify [properties] in order to affect how sub-elements
-   * are visited.
-   */
-  void collectInferredTypes(
-      SummaryClass obj, Map<String, Object> properties, String path) {
-    if (obj is UnlinkedVariable) {
-      collectInferredType(obj.inferredTypeSlot, path);
-      // As a temporary measure, prevent recursion into the variable's
-      // initializer, since AST-based type inference doesn't infer its type
-      // correctly yet.  TODO(paulberry): fix.
-      properties.remove('initializer');
-    } else if (obj is UnlinkedExecutable) {
-      collectInferredType(obj.inferredReturnTypeSlot, path);
-      // As a temporary measure, prevent recursion into the executable's local
-      // variables and local functions, since AST-based type inference doesn't
-      // infer locals correctly yet.  TODO(paulberry): fix if necessary.
-      properties.remove('localFunctions');
-      properties.remove('localVariables');
-    } else if (obj is UnlinkedParam) {
-      collectInferredType(obj.inferredTypeSlot, path);
-      // As a temporary measure, prevent recursion into the parameter's
-      // initializer, since AST-based type inference doesn't infer its type
-      // correctly yet.  TODO(paulberry): fix.
-      properties.remove('initializer');
-    }
-  }
-
-  /**
-   * Print out all the inferred types collected so far, in alphabetical order.
-   */
-  void dumpCollectedTypes() {
-    print('Collected types (${inferredTypes.length}):');
-    List<String> paths = inferredTypes.keys.toList();
-    paths.sort();
-    for (String path in paths) {
-      print('$path -> ${inferredTypes[path]}');
-    }
-  }
-
-  /**
-   * Format the given [type] as a string.  Unlike the type's [toString] method,
-   * this formats types using their complete URI to avoid ambiguity.
-   */
-  String formatDartType(DartType type) {
-    if (type is FunctionType) {
-      List<String> argStrings =
-          type.normalParameterTypes.map(formatDartType).toList();
-      List<DartType> optionalParameterTypes = type.optionalParameterTypes;
-      if (optionalParameterTypes.isNotEmpty) {
-        List<String> optionalArgStrings =
-            optionalParameterTypes.map(formatDartType).toList();
-        argStrings.add('[${optionalArgStrings.join(', ')}]');
-      }
-      Map<String, DartType> namedParameterTypes = type.namedParameterTypes;
-      if (namedParameterTypes.isNotEmpty) {
-        List<String> namedArgStrings = <String>[];
-        namedParameterTypes.forEach((String name, DartType type) {
-          namedArgStrings.add('$name: ${formatDartType(type)}');
-        });
-        argStrings.add('{${namedArgStrings.join(', ')}}');
-      }
-      return '(${argStrings.join(', ')}) → ${formatDartType(type.returnType)}';
-    } else if (type is InterfaceType) {
-      if (type.typeArguments.isNotEmpty) {
-        // TODO(paulberry): implement.
-        throw new UnimplementedError('type args');
-      }
-      return formatElement(type.element);
-    } else if (type is DynamicTypeImpl) {
-      return type.toString();
-    } else {
-      // TODO(paulberry): implement.
-      throw new UnimplementedError(
-          "Don't know how to format type of type ${type.runtimeType}");
-    }
-  }
-
-  /**
-   * Format the given [element] as a string, assuming it represents a type.
-   * Unlike the element's [toString] method, this formats elements using their
-   * complete URI to avoid ambiguity.
-   */
-  String formatElement(Element element) {
-    if (element is ClassElementForLink_Class ||
-        element is MethodElementForLink ||
-        element is ClassElementForLink_Enum ||
-        element is SpecialTypeElementForLink ||
-        element is FunctionTypeAliasElementForLink ||
-        element is TopLevelFunctionElementForLink) {
-      return element.toString();
-    } else if (element is FunctionElementForLink_Local_NonSynthetic) {
-      return formatDartType(element.type);
-    } else if (element is UndefinedElementForLink) {
-      return '???';
-    } else {
-      throw new UnimplementedError(
-          "Don't know how to format reference of type ${element.runtimeType}");
-    }
-  }
-
-  /**
-   * Interpret the given [param] as a parameter in a synthetic typedef, and
-   * format it as a string.
-   */
-  String formatParam(UnlinkedParam param) {
-    if (param.isFunctionTyped) {
-      // TODO(paulberry): fix this case.
-      return 'BAD(${json.encode(param)})';
-    }
-    String result;
-    if (param.type != null) {
-      result = '${formatType(param.type)} ${param.name}';
-    } else {
-      result = param.name;
-    }
-    if (param.kind == UnlinkedParamKind.optionalNamed) {
-      result = '{$result}';
-    } else if (param.kind == UnlinkedParamKind.optionalPositional) {
-      result = '[$result]';
-    }
-    return result;
-  }
-
-  /**
-   * Convert the reference with index [index] into a string.  If [typeOf] is
-   * `true`, the reference is being used in the context of naming a type, so
-   * if the entity being referenced is not a type, it will be enclosed in
-   * `typeof()` for clarity.
-   */
-  String formatReference(int index, {bool typeOf: false}) {
-    ReferenceableElementForLink element = unitForLink.resolveRef(index);
-    return formatElement(element);
-  }
-
-  /**
-   * Interpret the given [entityRef] as a reference to a type, and format it as
-   * a string.
-   */
-  String formatType(EntityRef entityRef) {
-    List<int> implicitFunctionTypeIndices =
-        entityRef.implicitFunctionTypeIndices;
-    if (entityRef.syntheticReturnType != null) {
-      String params = entityRef.syntheticParams.map(formatParam).join(', ');
-      String retType = formatType(entityRef.syntheticReturnType);
-      return '($params) -> $retType';
-    }
-    if (entityRef.paramReference != 0) {
-      return typeParamsInScope[
-          typeParamsInScope.length - entityRef.paramReference];
-    }
-    String result = formatReference(entityRef.reference, typeOf: true);
-    List<EntityRef> typeArguments = entityRef.typeArguments.toList();
-    while (typeArguments.isNotEmpty && isDynamic(typeArguments.last)) {
-      typeArguments.removeLast();
-    }
-    if (typeArguments.isNotEmpty) {
-      result += '<${typeArguments.map(formatType).join(', ')}>';
-    }
-    if (implicitFunctionTypeIndices.isNotEmpty) {
-      result =
-          'parameterOf($result, ${implicitFunctionTypeIndices.join(', ')})';
-    }
-    return result;
-  }
-
-  /**
-   * Determine if the given [entityRef] represents the pseudo-type `dynamic`.
-   */
-  bool isDynamic(EntityRef entityRef) {
-    if (entityRef.syntheticReturnType != null ||
-        entityRef.paramReference != 0) {
-      return false;
-    }
-    return formatReference(entityRef.reference, typeOf: true) == 'dynamic';
-  }
-
-  /**
-   * Collect all the inferred types contained in [obj], which is reachable via
-   * [path].  [properties] is the result of calling `obj.toMap()`, and may be
-   * modified before returning.
-   */
-  void visit(SummaryClass obj, Map<String, Object> properties, String path) {
-    List<String> oldTypeParamsInScope = typeParamsInScope;
-    Object newTypeParams = properties['typeParameters'];
-    if (newTypeParams is List && newTypeParams.isNotEmpty) {
-      typeParamsInScope = typeParamsInScope.toList();
-      for (Object typeParam in newTypeParams) {
-        if (typeParam is UnlinkedTypeParam) {
-          typeParamsInScope.add(typeParam.name);
-        } else {
-          throw new StateError(
-              'Unexpected type param type: ${typeParam.runtimeType}');
-        }
-      }
-    }
-    collectInferredTypes(obj, properties, path);
-    properties.forEach((String key, Object value) {
-      if (value is SummaryClass) {
-        visit(value, value.toMap(), '$path.$key');
-      } else if (value is List) {
-        for (int i = 0; i < value.length; i++) {
-          Object item = value[i];
-          if (item is SummaryClass) {
-            Map<String, Object> itemProperties = item.toMap();
-            String indexOrName = itemProperties['name'] ?? i.toString();
-            visit(item, itemProperties, '$path.$key[$indexOrName]');
-          }
-        }
-      }
-    });
-    typeParamsInScope = oldTypeParamsInScope;
-  }
-
-  /**
-   * Collect all the inferred types contained in [summaryDataStore].
-   */
-  void visitSummaryDataStore(SummaryDataStore summaryDataStore) {
-    // Figure out which unlinked units are a part of another library so we won't
-    // visit them redundantly.
-    Set<String> partOfUris = new Set<String>();
-    summaryDataStore.unlinkedMap
-        .forEach((String unitUriString, UnlinkedUnit unlinkedUnit) {
-      Uri unitUri = Uri.parse(unitUriString);
-      for (String relativePartUriString in unlinkedUnit.publicNamespace.parts) {
-        partOfUris.add(
-            resolveRelativeUri(unitUri, Uri.parse(relativePartUriString))
-                .toString());
-      }
-    });
-    summaryDataStore.linkedMap
-        .forEach((String libraryUriString, LinkedLibrary linkedLibrary) {
-      if (partOfUris.contains(libraryUriString)) {
-        return;
-      }
-      if (libraryUriString.startsWith('dart:')) {
-        // Don't bother dumping inferred types from the SDK.
-        return;
-      }
-      Uri libraryUri = Uri.parse(libraryUriString);
-      UnlinkedUnit definingUnlinkedUnit =
-          summaryDataStore.unlinkedMap[libraryUriString];
-      if (definingUnlinkedUnit != null) {
-        visitUnit(
-            definingUnlinkedUnit, linkedLibrary.units[0], libraryUriString, 0);
-        for (int i = 0;
-            i < definingUnlinkedUnit.publicNamespace.parts.length;
-            i++) {
-          Uri relativePartUri =
-              Uri.parse(definingUnlinkedUnit.publicNamespace.parts[i]);
-          String unitUriString =
-              resolveRelativeUri(libraryUri, relativePartUri).toString();
-          UnlinkedUnit unlinkedUnit =
-              summaryDataStore.unlinkedMap[unitUriString];
-          if (unlinkedUnit != null) {
-            visitUnit(unlinkedUnit, linkedLibrary.units[i + 1],
-                libraryUriString, i + 1);
-          }
-        }
-      }
-    });
-  }
-
-  /**
-   * Collect all the inferred types contained in the compilation unit described
-   * by [unlinkedUnit] and [linkedUnit], which has URI [libraryUriString].
-   */
-  void visitUnit(UnlinkedUnit unlinkedUnit, LinkedUnit linkedUnit,
-      String libraryUriString, int unitNum) {
-    this.unlinkedUnit = unlinkedUnit;
-    this.linkedUnit = linkedUnit;
-    this.unitForLink =
-        _linker.getLibrary(Uri.parse(libraryUriString)).units[unitNum];
-    visit(unlinkedUnit, unlinkedUnit.toMap(), libraryUriString);
-    this.unlinkedUnit = null;
-    this.linkedUnit = null;
-    this.unitForLink = null;
-  }
-}
diff --git a/pkg/analyzer/tool/summary/generate.dart b/pkg/analyzer/tool/summary/generate.dart
index 5d6ad0b..dd44327 100644
--- a/pkg/analyzer/tool/summary/generate.dart
+++ b/pkg/analyzer/tool/summary/generate.dart
@@ -22,7 +22,7 @@
 import 'package:front_end/src/fasta/scanner.dart';
 import 'package:front_end/src/scanner/token.dart' show Token;
 
-import 'idl_model.dart' as idlModel;
+import 'idl_model.dart' as idl_model;
 import 'mini_ast.dart';
 
 main(List<String> args) async {
@@ -59,7 +59,7 @@
       "throw new UnimplementedError('attempt to access deprecated field')";
 
   /// Semantic model of the "IDL" input file.
-  final idlModel.Idl _idl;
+  final idl_model.Idl _idl;
 
   /// Buffer in which generated code is accumulated.
   final StringBuffer _outBuffer;
@@ -74,11 +74,11 @@
   ///
   /// If [builder] is `true`, the returned type should be appropriate for use in
   /// a builder class.
-  String defaultValue(idlModel.FieldType type, bool builder) {
+  String defaultValue(idl_model.FieldType type, bool builder) {
     if (type.isList) {
       if (builder) {
-        idlModel.FieldType elementType =
-            new idlModel.FieldType(type.typeName, false);
+        idl_model.FieldType elementType =
+            new idl_model.FieldType(type.typeName, false);
         return '<${encodedType(elementType)}>[]';
       } else {
         return 'const <${idlPrefix(type.typeName)}>[]';
@@ -101,7 +101,7 @@
 
   /// Generate a string representing the Dart type which should be used to
   /// represent [type] while building a serialized data structure.
-  String encodedType(idlModel.FieldType type) {
+  String encodedType(idl_model.FieldType type) {
     String typeStr;
     if (_idl.classes.containsKey(type.typeName)) {
       typeStr = '${type.typeName}Builder';
@@ -161,7 +161,7 @@
     return json.encode(s);
   }
 
-  List<String> _computeVariants(idlModel.ClassDeclaration cls) {
+  List<String> _computeVariants(idl_model.ClassDeclaration cls) {
     var allVariants = Set<String>();
     for (var field in cls.fields) {
       var logicalFields = field.logicalProperties?.values;
@@ -175,8 +175,8 @@
   }
 
   String _variantAssertStatement(
-    idlModel.ClassDeclaration class_,
-    idlModel.LogicalProperty property,
+    idl_model.ClassDeclaration class_,
+    idl_model.LogicalProperty property,
   ) {
     var assertCondition = property.variants
         ?.map((key) => '${class_.variantField} == idl.$key')
@@ -186,10 +186,10 @@
 }
 
 class _BuilderGenerator extends _BaseGenerator {
-  final idlModel.ClassDeclaration cls;
+  final idl_model.ClassDeclaration cls;
   List<String> constructorParams = <String>[];
 
-  _BuilderGenerator(idlModel.Idl idl, StringBuffer outBuffer, this.cls)
+  _BuilderGenerator(idl_model.Idl idl, StringBuffer outBuffer, this.cls)
       : super(idl, outBuffer);
 
   String get builderName => name + 'Builder';
@@ -218,7 +218,7 @@
     out('/// Accumulate non-[informative] data into [signature].');
     out('void collectApiSignature(api_sig.ApiSignature signature) {');
 
-    void writeField(String name, idlModel.FieldType type, bool isInformative) {
+    void writeField(String name, idl_model.FieldType type, bool isInformative) {
       if (isInformative) {
         return;
       }
@@ -244,8 +244,8 @@
     }
 
     indent(() {
-      List<idlModel.FieldDeclaration> sortedFields = cls.fields.toList()
-        ..sort((idlModel.FieldDeclaration a, idlModel.FieldDeclaration b) =>
+      List<idl_model.FieldDeclaration> sortedFields = cls.fields.toList()
+        ..sort((idl_model.FieldDeclaration a, idl_model.FieldDeclaration b) =>
             a.id.compareTo(b.id));
       if (cls.variantField != null) {
         var firstVariant = true;
@@ -278,7 +278,7 @@
           out('}');
         }
       } else {
-        for (idlModel.FieldDeclaration field in sortedFields) {
+        for (idl_model.FieldDeclaration field in sortedFields) {
           writeField('_${field.name}', field.type, field.isInformative);
         }
       }
@@ -326,9 +326,9 @@
       }
     } else {
       out('$builderName({${constructorParams.join(', ')}})');
-      List<idlModel.FieldDeclaration> fields = cls.fields.toList();
+      List<idl_model.FieldDeclaration> fields = cls.fields.toList();
       for (int i = 0; i < fields.length; i++) {
-        idlModel.FieldDeclaration field = fields[i];
+        idl_model.FieldDeclaration field = fields[i];
         String prefix = i == 0 ? '  : ' : '    ';
         String suffix = i == fields.length - 1 ? ';' : ',';
         out('${prefix}_${field.name} = ${field.name}$suffix');
@@ -337,9 +337,9 @@
   }
 
   void _generateFields() {
-    for (idlModel.FieldDeclaration field in cls.fields) {
+    for (idl_model.FieldDeclaration field in cls.fields) {
       String fieldName = field.name;
-      idlModel.FieldType type = field.type;
+      idl_model.FieldType type = field.type;
       String typeStr = encodedType(type);
       out('$typeStr _$fieldName;');
     }
@@ -350,8 +350,8 @@
     out('fb.Offset finish(fb.Builder fbBuilder) {');
     indent(() {
       // Write objects and remember Offset(s).
-      for (idlModel.FieldDeclaration field in cls.fields) {
-        idlModel.FieldType fieldType = field.type;
+      for (idl_model.FieldDeclaration field in cls.fields) {
+        idl_model.FieldType fieldType = field.type;
         String offsetName = 'offset_' + field.name;
         if (fieldType.isList ||
             fieldType.typeName == 'String' ||
@@ -360,8 +360,8 @@
         }
       }
 
-      for (idlModel.FieldDeclaration field in cls.fields) {
-        idlModel.FieldType fieldType = field.type;
+      for (idl_model.FieldDeclaration field in cls.fields) {
+        idl_model.FieldType fieldType = field.type;
         String valueName = '_' + field.name;
         String offsetName = 'offset_' + field.name;
         String condition;
@@ -408,9 +408,9 @@
 
       // Write the table.
       out('fbBuilder.startTable();');
-      for (idlModel.FieldDeclaration field in cls.fields) {
+      for (idl_model.FieldDeclaration field in cls.fields) {
         int index = field.id;
-        idlModel.FieldType fieldType = field.type;
+        idl_model.FieldType fieldType = field.type;
         String valueName = '_' + field.name;
         String condition = '$valueName != null';
         String writeCode;
@@ -452,7 +452,7 @@
     out('/// Flush [informative] data recursively.');
     out('void flushInformative() {');
 
-    void writeField(String name, idlModel.FieldType type, bool isInformative) {
+    void writeField(String name, idl_model.FieldType type, bool isInformative) {
       if (isInformative) {
         out('$name = null;');
       } else if (_idl.classes.containsKey(type.typeName)) {
@@ -496,7 +496,7 @@
           out('}');
         }
       } else {
-        for (idlModel.FieldDeclaration field in cls.fields) {
+        for (idl_model.FieldDeclaration field in cls.fields) {
           writeField('_${field.name}', field.type, field.isInformative);
         }
       }
@@ -505,9 +505,9 @@
   }
 
   void _generateGettersSetters() {
-    for (idlModel.FieldDeclaration field in cls.allFields) {
+    for (idl_model.FieldDeclaration field in cls.allFields) {
       String fieldName = field.name;
-      idlModel.FieldType fieldType = field.type;
+      idl_model.FieldType fieldType = field.type;
       String typeStr = encodedType(fieldType);
       String def = defaultValue(fieldType, true);
       String defSuffix = def == null ? '' : ' ??= $def';
@@ -562,7 +562,7 @@
     }
   }
 
-  void _generateNonNegativeInt(idlModel.FieldType fieldType) {
+  void _generateNonNegativeInt(idl_model.FieldType fieldType) {
     if (fieldType.typeName == 'int') {
       if (!fieldType.isList) {
         out('assert(value == null || value >= 0);');
@@ -640,7 +640,7 @@
   final StringBuffer _outBuffer = new StringBuffer();
 
   /// Semantic model of the "IDL" input file.
-  idlModel.Idl _idl;
+  idl_model.Idl _idl;
 
   _CodeGenerator(String idlPath) {
     // Parse the input "IDL" file.
@@ -659,7 +659,7 @@
   /// Perform basic sanity checking of the IDL (over and above that done by
   /// [extractIdl]).
   void checkIdl() {
-    _idl.classes.forEach((String name, idlModel.ClassDeclaration cls) {
+    _idl.classes.forEach((String name, idl_model.ClassDeclaration cls) {
       if (cls.fileIdentifier != null) {
         if (cls.fileIdentifier.length != 4) {
           throw new Exception('$name: file identifier must be 4 characters');
@@ -672,9 +672,9 @@
         }
       }
       Map<int, String> idsUsed = <int, String>{};
-      for (idlModel.FieldDeclaration field in cls.allFields) {
+      for (idl_model.FieldDeclaration field in cls.allFields) {
         String fieldName = field.name;
-        idlModel.FieldType type = field.type;
+        idl_model.FieldType type = field.type;
         if (type.isList) {
           if (_idl.classes.containsKey(type.typeName)) {
             // List of classes is ok
@@ -710,7 +710,7 @@
   /// Process the AST in [idlParsed] and store the resulting semantic model in
   /// [_idl].  Also perform some error checking.
   void extractIdl(CompilationUnit idlParsed) {
-    _idl = new idlModel.Idl();
+    _idl = new idl_model.Idl();
     for (CompilationUnitMember decl in idlParsed.declarations) {
       if (decl is ClassDeclaration) {
         bool isTopLevel = false;
@@ -759,7 +759,7 @@
             }
           }
         }
-        idlModel.ClassDeclaration cls = new idlModel.ClassDeclaration(
+        idl_model.ClassDeclaration cls = new idl_model.ClassDeclaration(
           documentation: _getNodeDoc(decl),
           name: clsName,
           isTopLevel: isTopLevel,
@@ -786,13 +786,13 @@
         }
       } else if (decl is EnumDeclaration) {
         String doc = _getNodeDoc(decl);
-        idlModel.EnumDeclaration enm =
-            new idlModel.EnumDeclaration(doc, decl.name);
+        idl_model.EnumDeclaration enm =
+            new idl_model.EnumDeclaration(doc, decl.name);
         _idl.enums[enm.name] = enm;
         for (EnumConstantDeclaration constDecl in decl.constants) {
           String doc = _getNodeDoc(constDecl);
           enm.values
-              .add(new idlModel.EnumValueDeclaration(doc, constDecl.name));
+              .add(new idl_model.EnumValueDeclaration(doc, constDecl.name));
         }
       } else {
         throw new Exception('Unexpected declaration `$decl`');
@@ -818,11 +818,11 @@
     out();
     out("import 'idl.dart' as idl;");
     out();
-    for (idlModel.EnumDeclaration enum_ in _idl.enums.values) {
+    for (idl_model.EnumDeclaration enum_ in _idl.enums.values) {
       _EnumReaderGenerator(_idl, _outBuffer, enum_).generate();
       out();
     }
-    for (idlModel.ClassDeclaration cls in _idl.classes.values) {
+    for (idl_model.ClassDeclaration cls in _idl.classes.values) {
       if (!cls.isDeprecated) {
         _BuilderGenerator(_idl, _outBuffer, cls).generate();
         out();
@@ -860,7 +860,7 @@
   }
 
   void _addFieldForGetter(
-    idlModel.ClassDeclaration cls,
+    idl_model.ClassDeclaration cls,
     MethodDeclaration getter,
   ) {
     var desc = '${cls.name}.${getter.name}';
@@ -964,10 +964,10 @@
       throw new Exception('Missing @id annotation ($desc)');
     }
 
-    var fieldType = new idlModel.FieldType(type.name, isList);
+    var fieldType = new idl_model.FieldType(type.name, isList);
 
     String name = getter.name;
-    Map<String, idlModel.LogicalProperty> logicalProperties;
+    Map<String, idl_model.LogicalProperty> logicalProperties;
     if (variants != null) {
       var fieldsWithSameId =
           cls.allFields.where((field) => field.id == id).toList();
@@ -999,7 +999,7 @@
           );
         }
 
-        map[getter.name] = idlModel.LogicalProperty(
+        map[getter.name] = idl_model.LogicalProperty(
           isDeprecated: isDeprecated,
           isInformative: isInformative,
           variants: variants,
@@ -1007,8 +1007,8 @@
         return;
       } else {
         name = 'variantField_$id';
-        logicalProperties = <String, idlModel.LogicalProperty>{
-          getter.name: idlModel.LogicalProperty(
+        logicalProperties = <String, idl_model.LogicalProperty>{
+          getter.name: idl_model.LogicalProperty(
             isDeprecated: isDeprecated,
             isInformative: isInformative,
             variants: variants,
@@ -1018,7 +1018,7 @@
     }
 
     cls.allFields.add(
-      idlModel.FieldDeclaration(
+      idl_model.FieldDeclaration(
         documentation: _getNodeDoc(getter),
         name: name,
         type: fieldType,
@@ -1055,9 +1055,9 @@
 }
 
 class _EnumReaderGenerator extends _BaseGenerator {
-  final idlModel.EnumDeclaration enum_;
+  final idl_model.EnumDeclaration enum_;
 
-  _EnumReaderGenerator(idlModel.Idl idl, StringBuffer outBuffer, this.enum_)
+  _EnumReaderGenerator(idl_model.Idl idl, StringBuffer outBuffer, this.enum_)
       : super(idl, outBuffer);
 
   void generate() {
@@ -1085,17 +1085,17 @@
 }
 
 class _FlatBufferSchemaGenerator extends _BaseGenerator {
-  _FlatBufferSchemaGenerator(idlModel.Idl idl, StringBuffer outBuffer)
+  _FlatBufferSchemaGenerator(idl_model.Idl idl, StringBuffer outBuffer)
       : super(idl, outBuffer);
 
   void generate() {
-    for (idlModel.EnumDeclaration enm in _idl.enums.values) {
+    for (idl_model.EnumDeclaration enm in _idl.enums.values) {
       out();
       outDoc(enm.documentation);
       out('enum ${enm.name} : byte {');
       indent(() {
         for (int i = 0; i < enm.values.length; i++) {
-          idlModel.EnumValueDeclaration value = enm.values[i];
+          idl_model.EnumValueDeclaration value = enm.values[i];
           if (i != 0) {
             out();
           }
@@ -1106,13 +1106,13 @@
       });
       out('}');
     }
-    for (idlModel.ClassDeclaration cls in _idl.classes.values) {
+    for (idl_model.ClassDeclaration cls in _idl.classes.values) {
       out();
       outDoc(cls.documentation);
       out('table ${cls.name} {');
       indent(() {
         for (int i = 0; i < cls.allFields.length; i++) {
-          idlModel.FieldDeclaration field = cls.allFields[i];
+          idl_model.FieldDeclaration field = cls.allFields[i];
           if (i != 0) {
             out();
           }
@@ -1131,7 +1131,7 @@
     // Standard flatbuffers only support one root type.  We support multiple
     // root types.  For now work around this by forcing PackageBundle to be the
     // root type.  TODO(paulberry): come up with a better solution.
-    idlModel.ClassDeclaration rootType = _idl.classes['PackageBundle'];
+    idl_model.ClassDeclaration rootType = _idl.classes['PackageBundle'];
     out('root_type ${rootType.name};');
     if (rootType.fileIdentifier != null) {
       out();
@@ -1141,7 +1141,7 @@
 
   /// Generate a string representing the FlatBuffer schema type which should be
   /// used to represent [type].
-  String _fbsType(idlModel.FieldType type) {
+  String _fbsType(idl_model.FieldType type) {
     String typeStr;
     switch (type.typeName) {
       case 'bool':
@@ -1175,9 +1175,9 @@
 }
 
 class _ImplGenerator extends _BaseGenerator {
-  final idlModel.ClassDeclaration cls;
+  final idl_model.ClassDeclaration cls;
 
-  _ImplGenerator(idlModel.Idl idl, StringBuffer outBuffer, this.cls)
+  _ImplGenerator(idl_model.Idl idl, StringBuffer outBuffer, this.cls)
       : super(idl, outBuffer);
 
   void generate() {
@@ -1193,16 +1193,16 @@
       out('$implName(this._bc, this._bcOffset);');
       out();
       // Write cache fields.
-      for (idlModel.FieldDeclaration field in cls.fields) {
+      for (idl_model.FieldDeclaration field in cls.fields) {
         String returnType = _dartType(field.type);
         String fieldName = field.name;
         out('$returnType _$fieldName;');
       }
       // Write getters.
-      for (idlModel.FieldDeclaration field in cls.allFields) {
+      for (idl_model.FieldDeclaration field in cls.allFields) {
         int index = field.id;
         String fieldName = field.name;
-        idlModel.FieldType type = field.type;
+        idl_model.FieldType type = field.type;
         String typeName = type.typeName;
         // Prepare "readCode" + "def"
         String readCode;
@@ -1280,7 +1280,7 @@
 
   /// Generate a string representing the Dart type which should be used to
   /// represent [type] when deserialized.
-  String _dartType(idlModel.FieldType type) {
+  String _dartType(idl_model.FieldType type) {
     String baseType = idlPrefix(type.typeName);
     if (type.isList) {
       return 'List<$baseType>';
@@ -1291,9 +1291,9 @@
 }
 
 class _MixinGenerator extends _BaseGenerator {
-  final idlModel.ClassDeclaration cls;
+  final idl_model.ClassDeclaration cls;
 
-  _MixinGenerator(idlModel.Idl idl, StringBuffer outBuffer, this.cls)
+  _MixinGenerator(idl_model.Idl idl, StringBuffer outBuffer, this.cls)
       : super(idl, outBuffer);
 
   void generate() {
@@ -1301,7 +1301,7 @@
     String mixinName = '_${name}Mixin';
     out('abstract class $mixinName implements ${idlPrefix(name)} {');
     indent(() {
-      String jsonCondition(idlModel.FieldType type, String name) {
+      String jsonCondition(idl_model.FieldType type, String name) {
         if (type.isList) {
           return '$name.isNotEmpty';
         } else {
@@ -1309,7 +1309,7 @@
         }
       }
 
-      String jsonStore(idlModel.FieldType type, String name) {
+      String jsonStore(idl_model.FieldType type, String name) {
         _StringToString convertItem;
         if (_idl.classes.containsKey(type.typeName)) {
           convertItem = (String name) => '$name.toJson()';
@@ -1341,7 +1341,7 @@
 
         if (cls.variantField != null) {
           indent(() {
-            for (idlModel.FieldDeclaration field in cls.fields) {
+            for (idl_model.FieldDeclaration field in cls.fields) {
               if (field.logicalProperties == null) {
                 var condition = jsonCondition(field.type, field.name);
                 var storeField = jsonStore(field.type, field.name);
@@ -1351,7 +1351,7 @@
             for (var variant in _computeVariants(cls)) {
               out('if (${cls.variantField} == idl.$variant) {');
               indent(() {
-                for (idlModel.FieldDeclaration field in cls.fields) {
+                for (idl_model.FieldDeclaration field in cls.fields) {
                   var logicalProperties = field.logicalProperties;
                   if (logicalProperties != null) {
                     for (var logicalName in logicalProperties.keys) {
@@ -1370,7 +1370,7 @@
           });
         } else {
           indent(() {
-            for (idlModel.FieldDeclaration field in cls.fields) {
+            for (idl_model.FieldDeclaration field in cls.fields) {
               String condition = jsonCondition(field.type, field.name);
               String storeField = jsonStore(field.type, field.name);
               out('if ($condition) $storeField;');
@@ -1391,7 +1391,7 @@
           out('if (${cls.variantField} == idl.$variant) {');
           indent(() {
             out('return {');
-            for (idlModel.FieldDeclaration field in cls.fields) {
+            for (idl_model.FieldDeclaration field in cls.fields) {
               if (field.logicalProperties != null) {
                 for (var logicalName in field.logicalProperties.keys) {
                   var logicalProperty = field.logicalProperties[logicalName];
@@ -1413,7 +1413,7 @@
       } else {
         out('Map<String, Object> toMap() => {');
         indent(() {
-          for (idlModel.FieldDeclaration field in cls.fields) {
+          for (idl_model.FieldDeclaration field in cls.fields) {
             String fieldName = field.name;
             out('${quoted(fieldName)}: $fieldName,');
           }
@@ -1430,9 +1430,9 @@
 }
 
 class _ReaderGenerator extends _BaseGenerator {
-  final idlModel.ClassDeclaration cls;
+  final idl_model.ClassDeclaration cls;
 
-  _ReaderGenerator(idlModel.Idl idl, StringBuffer outBuffer, this.cls)
+  _ReaderGenerator(idl_model.Idl idl, StringBuffer outBuffer, this.cls)
       : super(idl, outBuffer);
 
   void generateReader() {
diff --git a/pkg/analyzer_cli/analysis_options.yaml b/pkg/analyzer_cli/analysis_options.yaml
index 4341996..87f2d3b 100644
--- a/pkg/analyzer_cli/analysis_options.yaml
+++ b/pkg/analyzer_cli/analysis_options.yaml
@@ -1,6 +1,9 @@
 analyzer:
   strong-mode:
     implicit-casts: false
+  errors:
+    # Increase the severity of the unused_import hint.
+    unused_import: warning
   exclude:
     - test/data/**
 linter:
diff --git a/pkg/analyzer_cli/lib/src/build_mode.dart b/pkg/analyzer_cli/lib/src/build_mode.dart
index a4363fc..57bedb4 100644
--- a/pkg/analyzer_cli/lib/src/build_mode.dart
+++ b/pkg/analyzer_cli/lib/src/build_mode.dart
@@ -27,9 +27,7 @@
 import 'package:analyzer/src/source/source_resource.dart';
 import 'package:analyzer/src/summary/format.dart';
 import 'package:analyzer/src/summary/idl.dart';
-import 'package:analyzer/src/summary/link.dart';
 import 'package:analyzer/src/summary/package_bundle_reader.dart';
-import 'package:analyzer/src/summary/summarize_ast.dart';
 import 'package:analyzer/src/summary/summarize_elements.dart';
 import 'package:analyzer/src/summary/summary_sdk.dart' show SummaryBasedDartSdk;
 import 'package:analyzer/src/summary2/link.dart' as summary2;
@@ -193,7 +191,6 @@
   AnalysisDriver analysisDriver;
 
   PackageBundleAssembler assembler;
-  final Map<String, UnlinkedUnit> uriToUnit = <String, UnlinkedUnit>{};
 
   final Map<String, ParsedUnitResult> inputParsedUnitResults = {};
   summary2.LinkedElementFactory elementFactory;
@@ -270,27 +267,12 @@
           // Prepare all unlinked units.
           await logger.runAsync('Prepare unlinked units', () async {
             for (var src in explicitSources) {
-              await _prepareUnlinkedUnit('${src.uri}');
+              await _prepareUnit('${src.uri}');
             }
           });
 
           // Build and assemble linked libraries.
-          if (AnalysisDriver.useSummary2) {
-            _computeLinkedLibraries2();
-          } else {
-            if (!options.buildSummaryOnlyUnlinked) {
-              // Prepare URIs of unlinked units that should be linked.
-              var unlinkedUris = new Set<String>();
-              for (var bundle in unlinkedBundles) {
-                unlinkedUris.addAll(bundle.unlinkedUnitUris);
-              }
-              for (var src in explicitSources) {
-                unlinkedUris.add('${src.uri}');
-              }
-              // Perform linking.
-              _computeLinkedLibraries(unlinkedUris);
-            }
-          }
+          _computeLinkedLibraries2();
 
           // Write the whole package bundle.
           PackageBundleBuilder bundle = assembler.assemble();
@@ -332,43 +314,6 @@
   }
 
   /**
-   * Compute linked libraries for the given [libraryUris] using the linked
-   * libraries of the [summaryDataStore] and unlinked units in [uriToUnit], and
-   * add them to  the [assembler].
-   */
-  void _computeLinkedLibraries(Set<String> libraryUris) {
-    logger.run('Link output summary', () {
-      void trackDependency(String absoluteUri) {
-        if (dependencyTracker != null) {
-          var summaryUri = summaryDataStore.uriToSummaryPath[absoluteUri];
-          if (summaryUri != null) {
-            dependencyTracker.record(summaryUri);
-          }
-        }
-      }
-
-      LinkedLibrary getDependency(String absoluteUri) {
-        trackDependency(absoluteUri);
-        return summaryDataStore.linkedMap[absoluteUri];
-      }
-
-      UnlinkedUnit getUnit(String absoluteUri) {
-        trackDependency(absoluteUri);
-        return summaryDataStore.unlinkedMap[absoluteUri] ??
-            uriToUnit[absoluteUri];
-      }
-
-      Map<String, LinkedLibraryBuilder> linkResult = link(
-          libraryUris,
-          getDependency,
-          getUnit,
-          analysisDriver.declaredVariables,
-          analysisOptions);
-      linkResult.forEach(assembler.addLinkedLibrary);
-    });
-  }
-
-  /**
    * Use [elementFactory] filled with input summaries, and link prepared
    * [inputParsedUnitResults] to produce linked libraries in [assembler].
    */
@@ -539,9 +484,7 @@
     declaredVariables = new DeclaredVariables.fromMap(options.definedVariables);
     analysisDriver.declaredVariables = declaredVariables;
 
-    if (AnalysisDriver.useSummary2) {
-      _createLinkedElementFactory();
-    }
+    _createLinkedElementFactory();
 
     scheduler.start();
   }
@@ -590,13 +533,11 @@
   }
 
   /**
-   * Ensure that the [UnlinkedUnit] for [absoluteUri] is available.
+   * Ensure that the parsed unit for [absoluteUri] is available.
    *
    * If the unit is in the input [summaryDataStore], do nothing.
-   *
-   * Otherwise compute it and store into the [uriToUnit] and [assembler].
    */
-  Future<void> _prepareUnlinkedUnit(String absoluteUri) async {
+  Future<void> _prepareUnit(String absoluteUri) async {
     // Maybe an input package contains the source.
     if (summaryDataStore.unlinkedMap[absoluteUri] != null) {
       return;
@@ -610,13 +551,7 @@
       return;
     }
     var result = await analysisDriver.parseFile(source.fullName);
-    if (AnalysisDriver.useSummary2) {
-      inputParsedUnitResults[result.path] = result;
-    } else {
-      UnlinkedUnitBuilder unlinkedUnit = serializeAstUnlinked(result.unit);
-      uriToUnit[absoluteUri] = unlinkedUnit;
-      assembler.addUnlinkedUnit(source, unlinkedUnit);
-    }
+    inputParsedUnitResults[result.path] = result;
   }
 
   /**
diff --git a/pkg/analyzer_cli/lib/src/options.dart b/pkg/analyzer_cli/lib/src/options.dart
index 526bc26..931c9ad 100644
--- a/pkg/analyzer_cli/lib/src/options.dart
+++ b/pkg/analyzer_cli/lib/src/options.dart
@@ -7,7 +7,6 @@
 import 'package:analyzer/file_system/physical_file_system.dart';
 import 'package:analyzer/src/command_line/arguments.dart';
 import 'package:analyzer/src/context/builder.dart';
-import 'package:analyzer/src/dart/analysis/driver.dart';
 import 'package:analyzer/src/dart/analysis/experiments.dart';
 import 'package:analyzer/src/util/sdk.dart';
 import 'package:analyzer_cli/src/ansi.dart' as ansi;
@@ -270,23 +269,8 @@
     }
 
     if (options.buildSummaryOnlyUnlinked) {
-      if (AnalysisDriver.useSummary2) {
-        printAndFail('The option --build-summary-only-unlinked can not be used '
-            'together with summary2.');
-        return null; // Only reachable in testing.
-      }
-      if (!options.buildSummaryOnly) {
-        printAndFail(
-            'The option --build-summary-only-unlinked can be used only '
-            'together with --build-summary-only.');
-        return null; // Only reachable in testing.
-      }
-      if (options.buildSummaryInputs.isNotEmpty ||
-          options.buildSummaryUnlinkedInputs.isNotEmpty) {
-        printAndFail('No summaries should be provided in combination with '
-            '--build-summary-only-unlinked, they aren\'t needed.');
-        return null; // Only reachable in testing.
-      }
+      printAndFail('The option --build-summary-only-unlinked is deprecated.');
+      return null; // Only reachable in testing.
     }
 
     return options;
diff --git a/pkg/analyzer_cli/test/driver_test.dart b/pkg/analyzer_cli/test/driver_test.dart
index 705be26..4232985 100644
--- a/pkg/analyzer_cli/test/driver_test.dart
+++ b/pkg/analyzer_cli/test/driver_test.dart
@@ -8,7 +8,6 @@
 import 'package:analyzer/error/error.dart';
 import 'package:analyzer/source/error_processor.dart';
 import 'package:analyzer/src/analysis_options/analysis_options_provider.dart';
-import 'package:analyzer/src/dart/analysis/driver.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/source.dart';
@@ -489,122 +488,18 @@
       PackageBundle bundle =
           new PackageBundle.fromBuffer(await output.readAsBytes());
       var testFileUri = 'file:///test_file.dart';
-      if (AnalysisDriver.useSummary2) {
-        var bundle2 = bundle.bundle2;
-        expect(_linkedLibraryUriList(bundle2), [testFileUri]);
-        expect(
-          _linkedLibraryUnitUriList(bundle2, testFileUri),
-          [testFileUri],
-        );
-      } else {
-        expect(bundle.unlinkedUnitUris, equals([testFileUri]));
-        expect(bundle.linkedLibraryUris, equals([testFileUri]));
-      }
+
+      var bundle2 = bundle.bundle2;
+      expect(_linkedLibraryUriList(bundle2), [testFileUri]);
+      expect(
+        _linkedLibraryUnitUriList(bundle2, testFileUri),
+        [testFileUri],
+      );
+
       expect(exitCode, 0);
     });
   }
 
-  test_buildLinked_buildSummaryOutputSemantic() async {
-    // All informative data is stored separately when summary2.
-    if (AnalysisDriver.useSummary2) {
-      return;
-    }
-
-    await withTempDirAsync((tempDir) async {
-      var testDart = path.join(tempDir, 'test.dart');
-      var testSumFull = path.join(tempDir, 'test.sum.full');
-      var testSumSemantic = path.join(tempDir, 'test.sum.sem');
-
-      new File(testDart).writeAsStringSync('var v = 42;');
-
-      await _doDrive(testDart, additionalArgs: [
-        '--build-summary-only',
-        '--build-summary-output=$testSumFull',
-        '--build-summary-output-semantic=$testSumSemantic',
-      ]);
-      expect(exitCode, 0);
-
-      // The full summary is produced.
-      {
-        var file = new File(testSumFull);
-        expect(file.existsSync(), isTrue);
-        var bytes = file.readAsBytesSync();
-        var bundle = new PackageBundle.fromBuffer(bytes);
-        var v = bundle.unlinkedUnits[0].variables[0];
-        expect(v.name, 'v');
-        expect(v.nameOffset, 4);
-      }
-
-      // The semantic summary is produced.
-      {
-        var file = new File(testSumSemantic);
-        expect(file.existsSync(), isTrue);
-        var bytes = file.readAsBytesSync();
-        var bundle = new PackageBundle.fromBuffer(bytes);
-        var v = bundle.unlinkedUnits[0].variables[0];
-        expect(v.name, 'v');
-        expect(v.nameOffset, 0);
-      }
-    });
-  }
-
-  test_buildLinked_fromUnlinked() async {
-    // We don't use unlinked units with summary2.
-    if (AnalysisDriver.useSummary2) {
-      return;
-    }
-
-    await withTempDirAsync((tempDir) async {
-      var aDart = path.join(tempDir, 'a.dart');
-      var bDart = path.join(tempDir, 'b.dart');
-
-      var aUri = 'package:aaa/a.dart';
-      var bUri = 'package:bbb/b.dart';
-
-      var aUnlinked = path.join(tempDir, 'a.unlinked');
-      var bUnlinked = path.join(tempDir, 'b.unlinked');
-      var abLinked = path.join(tempDir, 'ab.linked');
-
-      new File(aDart).writeAsStringSync('var a = 1;');
-      new File(bDart).writeAsStringSync('''
-import 'package:aaa/a.dart';
-var b = a;
-''');
-
-      Future<void> buildUnlinked(String uri, String path, String output) async {
-        await _doDrive(path, uri: uri, additionalArgs: [
-          '--build-summary-only',
-          '--build-summary-only-unlinked',
-          '--build-summary-output=$output'
-        ]);
-        expect(exitCode, 0);
-        expect(new File(output).existsSync(), isTrue);
-      }
-
-      await buildUnlinked(aUri, aDart, aUnlinked);
-      await buildUnlinked(bUri, bDart, bUnlinked);
-
-      await new Driver(isTesting: true).start([
-        '--dart-sdk',
-        _findSdkDirForSummaries(),
-        '--build-mode',
-        '--build-summary-unlinked-input=$aUnlinked,$bUnlinked',
-        '--build-summary-output=$abLinked'
-      ]);
-      expect(exitCode, 0);
-      var bytes = new File(abLinked).readAsBytesSync();
-      var bundle = new PackageBundle.fromBuffer(bytes);
-
-      // Only linked information.
-      expect(bundle.unlinkedUnitUris, isEmpty);
-      expect(bundle.linkedLibraryUris, unorderedEquals([aUri, bUri]));
-
-      // Strong mode type inference was performed.
-      expect(bundle.linkedLibraries[0].units[0].types, isNotEmpty);
-      expect(bundle.linkedLibraries[1].units[0].types, isNotEmpty);
-    });
-  }
-
   test_buildLinked_invalidPartUri() async {
     await withTempDirAsync((tempDir) async {
       var aDart = path.join(tempDir, 'a.dart');
@@ -622,14 +517,9 @@
       expect(exitCode, ErrorSeverity.ERROR.ordinal);
       var bytes = new File(aSum).readAsBytesSync();
       var bundle = new PackageBundle.fromBuffer(bytes);
-      if (AnalysisDriver.useSummary2) {
-        var bundle2 = bundle.bundle2;
-        expect(_linkedLibraryUriList(bundle2), [aUri]);
-        expect(_linkedLibraryUnitUriList(bundle2, aUri), [aUri, '']);
-      } else {
-        expect(bundle.unlinkedUnitUris, equals([aUri]));
-        expect(bundle.linkedLibraryUris, equals([aUri]));
-      }
+      var bundle2 = bundle.bundle2;
+      expect(_linkedLibraryUriList(bundle2), [aUri]);
+      expect(_linkedLibraryUnitUriList(bundle2, aUri), [aUri, '']);
     });
   }
 
@@ -645,31 +535,6 @@
     expect(exitCode, 0);
   }
 
-  test_buildUnlinked() async {
-    // We don't use unlinked units with summary2.
-    if (AnalysisDriver.useSummary2) {
-      return;
-    }
-
-    await withTempDirAsync((tempDir) async {
-      var outputPath = path.join(tempDir, 'test_file.dart.sum');
-      await _doDrive(path.join('data', 'test_file.dart'), additionalArgs: [
-        '--build-summary-only',
-        '--build-summary-only-unlinked',
-        '--build-summary-output=$outputPath'
-      ]);
-      var output = new File(outputPath);
-      expect(output.existsSync(), isTrue);
-      PackageBundle bundle =
-          new PackageBundle.fromBuffer(await output.readAsBytes());
-      var testFileUri = 'file:///test_file.dart';
-      expect(bundle.unlinkedUnits.length, 1);
-      expect(bundle.unlinkedUnitUris, equals([testFileUri]));
-      expect(bundle.linkedLibraryUris, isEmpty);
-      expect(exitCode, 0);
-    });
-  }
-
   test_consumeLinked() async {
     await withTempDirAsync((tempDir) async {
       var aDart = path.join(tempDir, 'a.dart');
@@ -702,14 +567,9 @@
         expect(exitCode, 0);
         var bytes = new File(aSum).readAsBytesSync();
         var bundle = new PackageBundle.fromBuffer(bytes);
-        if (AnalysisDriver.useSummary2) {
-          var bundle2 = bundle.bundle2;
-          expect(_linkedLibraryUriList(bundle2), [aUri]);
-          expect(_linkedLibraryUnitUriList(bundle2, aUri), [aUri]);
-        } else {
-          expect(bundle.unlinkedUnitUris, equals([aUri]));
-          expect(bundle.linkedLibraryUris, equals([aUri]));
-        }
+        var bundle2 = bundle.bundle2;
+        expect(_linkedLibraryUriList(bundle2), [aUri]);
+        expect(_linkedLibraryUnitUriList(bundle2, aUri), [aUri]);
       }
 
       // Analyze package:bbb/b.dart and compute summary.
@@ -721,14 +581,9 @@
         expect(exitCode, 0);
         var bytes = new File(bSum).readAsBytesSync();
         var bundle = new PackageBundle.fromBuffer(bytes);
-        if (AnalysisDriver.useSummary2) {
-          var bundle2 = bundle.bundle2;
-          expect(_linkedLibraryUriList(bundle2), [bUri]);
-          expect(_linkedLibraryUnitUriList(bundle2, bUri), [bUri]);
-        } else {
-          expect(bundle.unlinkedUnitUris, equals([bUri]));
-          expect(bundle.linkedLibraryUris, equals([bUri]));
-        }
+        var bundle2 = bundle.bundle2;
+        expect(_linkedLibraryUriList(bundle2), [bUri]);
+        expect(_linkedLibraryUnitUriList(bundle2, bUri), [bUri]);
       }
 
       // Analyze package:ccc/c.dart and compute summary.
@@ -740,14 +595,9 @@
         expect(exitCode, 0);
         var bytes = new File(cSum).readAsBytesSync();
         var bundle = new PackageBundle.fromBuffer(bytes);
-        if (AnalysisDriver.useSummary2) {
-          var bundle2 = bundle.bundle2;
-          expect(_linkedLibraryUriList(bundle2), [cUri]);
-          expect(_linkedLibraryUnitUriList(bundle2, cUri), [cUri]);
-        } else {
-          expect(bundle.unlinkedUnitUris, equals([cUri]));
-          expect(bundle.linkedLibraryUris, equals([cUri]));
-        }
+        var bundle2 = bundle.bundle2;
+        expect(_linkedLibraryUriList(bundle2), [cUri]);
+        expect(_linkedLibraryUnitUriList(bundle2, cUri), [cUri]);
       }
     });
   }
@@ -774,47 +624,6 @@
     });
   }
 
-  test_error_linkedAsUnlinked() async {
-    // We don't use unlinked units with summary2.
-    if (AnalysisDriver.useSummary2) {
-      return;
-    }
-
-    await withTempDirAsync((tempDir) async {
-      var aDart = path.join(tempDir, 'a.dart');
-      var bDart = path.join(tempDir, 'b.dart');
-
-      var aUri = 'package:aaa/a.dart';
-      var bUri = 'package:bbb/b.dart';
-
-      var aSum = path.join(tempDir, 'a.sum');
-      var bSum = path.join(tempDir, 'b.sum');
-
-      new File(aDart).writeAsStringSync('class A {}');
-
-      // Build linked a.sum
-      await _doDrive(aDart, uri: aUri, additionalArgs: [
-        '--build-summary-only',
-        '--build-summary-output=$aSum'
-      ]);
-      expect(new File(aSum).existsSync(), isTrue);
-
-      // Try to consume linked a.sum as unlinked.
-      try {
-        await _doDrive(bDart, uri: bUri, additionalArgs: [
-          '--build-summary-unlinked-input=$aSum',
-          '--build-summary-output=$bSum'
-        ]);
-        fail('ArgumentError expected.');
-      } on ArgumentError catch (e) {
-        expect(
-            e.message,
-            contains(
-                'Got a linked summary for --build-summary-input-unlinked'));
-      }
-    });
-  }
-
   test_error_notUriPipePath() async {
     await withTempDirAsync((tempDir) async {
       var testDart = path.join(tempDir, 'test.dart');
@@ -826,46 +635,6 @@
     });
   }
 
-  test_error_unlinkedAsLinked() async {
-    // We don't use unlinked units with summary2.
-    if (AnalysisDriver.useSummary2) {
-      return;
-    }
-
-    await withTempDirAsync((tempDir) async {
-      var aDart = path.join(tempDir, 'a.dart');
-      var bDart = path.join(tempDir, 'b.dart');
-
-      var aUri = 'package:aaa/a.dart';
-      var bUri = 'package:bbb/b.dart';
-
-      var aSum = path.join(tempDir, 'a.sum');
-      var bSum = path.join(tempDir, 'b.sum');
-
-      new File(aDart).writeAsStringSync('class A {}');
-
-      // Build unlinked a.sum
-      await _doDrive(aDart, uri: aUri, additionalArgs: [
-        '--build-summary-only',
-        '--build-summary-only-unlinked',
-        '--build-summary-output=$aSum'
-      ]);
-      expect(new File(aSum).existsSync(), isTrue);
-
-      // Try to consume unlinked a.sum as linked.
-      try {
-        await _doDrive(bDart, uri: bUri, additionalArgs: [
-          '--build-summary-input=$aSum',
-          '--build-summary-output=$bSum'
-        ]);
-        fail('ArgumentError expected.');
-      } on ArgumentError catch (e) {
-        expect(e.message,
-            contains('Got an unlinked summary for --build-summary-input'));
-      }
-    });
-  }
-
   test_fail_whenHasError() async {
     await _doDrive(path.join('data', 'file_with_error.dart'));
     expect(exitCode, isNot(0));
diff --git a/pkg/analyzer_cli/test/options_test.dart b/pkg/analyzer_cli/test/options_test.dart
index ea5d4d4..040710e 100644
--- a/pkg/analyzer_cli/test/options_test.dart
+++ b/pkg/analyzer_cli/test/options_test.dart
@@ -7,7 +7,6 @@
 import 'package:analyzer/src/dart/analysis/experiments.dart';
 import 'package:analyzer/src/dart/analysis/experiments_impl.dart'
     show overrideKnownFeatures;
-import 'package:analyzer/src/dart/analysis/driver.dart';
 import 'package:analyzer_cli/src/driver.dart';
 import 'package:analyzer_cli/src/options.dart';
 import 'package:telemetry/telemetry.dart' as telemetry;
@@ -419,19 +418,12 @@
       '--build-summary-only-unlinked',
       'package:p/foo.dart|/path/to/p/lib/foo.dart'
     ]);
-    if (AnalysisDriver.useSummary2) {
-      expect(
-        errorStringBuffer.toString(),
-        contains(
-          'The option --build-summary-only-unlinked can not be used '
-          'together with summary2.',
-        ),
-      );
-    } else {
-      expect(options.buildMode, isTrue);
-      expect(options.buildSummaryOnly, isTrue);
-      expect(options.buildSummaryOnlyUnlinked, isTrue);
-    }
+    expect(
+      errorStringBuffer.toString(),
+      contains(
+        'The option --build-summary-only-unlinked is deprecated.',
+      ),
+    );
   }
 
   test_buildSummaryOutput() {
diff --git a/pkg/analyzer_plugin/pubspec.yaml b/pkg/analyzer_plugin/pubspec.yaml
index b7b473f..0fe28a95 100644
--- a/pkg/analyzer_plugin/pubspec.yaml
+++ b/pkg/analyzer_plugin/pubspec.yaml
@@ -8,7 +8,7 @@
   sdk: '>=2.0.0 <3.0.0'
 
 dependencies:
-  analyzer: '>=0.35.3 <0.38.0'
+  analyzer: '>=0.35.3 <0.39.0'
   charcode: '^1.1.0'
   dart_style: '^1.2.0'
   html: '>=0.13.1 <0.15.0'
diff --git a/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_dart_test.dart b/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_dart_test.dart
index 5b4985f..64cba71 100644
--- a/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_dart_test.dart
+++ b/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_dart_test.dart
@@ -9,7 +9,6 @@
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/nullability_suffix.dart';
 import 'package:analyzer/dart/element/type.dart';
-import 'package:analyzer/src/dart/analysis/driver.dart';
 import 'package:analyzer/src/dart/element/inheritance_manager3.dart';
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/source.dart';
@@ -1238,9 +1237,6 @@
   }
 
   test_writeType_function_generic() async {
-    // TODO(scheglov) Fails because T/U are considered invisible.
-    if (!AnalysisDriver.useSummary2) return;
-
     await _assertWriteType('T Function<T, U>(T a, U b)');
   }
 
diff --git a/pkg/compiler/lib/src/js_backend/runtime_types_new.dart b/pkg/compiler/lib/src/js_backend/runtime_types_new.dart
index ecb9b52..02c690d 100644
--- a/pkg/compiler/lib/src/js_backend/runtime_types_new.dart
+++ b/pkg/compiler/lib/src/js_backend/runtime_types_new.dart
@@ -46,8 +46,9 @@
   /// Returns a [jsAst.Literal] representing [supertypeArgument] to be evaluated
   /// against a [FullTypeEnvironmentStructure] representing [declaringType]. Any
   /// [TypeVariableType]s appearing in [supertypeArgument] which are declared by
-  /// [declaringType] are always encoded as indices.
-  jsAst.Literal encodeDirectSupertypeRecipe(ModularEmitter emitter,
+  /// [declaringType] are always encoded as indices and type variables are
+  /// assumed to never be erased.
+  jsAst.Literal encodeMetadataRecipe(ModularEmitter emitter,
       InterfaceType declaringType, DartType supertypeArgument);
 
   /// Converts a recipe into a fragment of code that accesses the evaluated
@@ -94,14 +95,14 @@
   }
 
   @override
-  jsAst.Literal encodeDirectSupertypeRecipe(ModularEmitter emitter,
+  jsAst.Literal encodeMetadataRecipe(ModularEmitter emitter,
       InterfaceType declaringType, DartType supertypeArgument) {
     return _RecipeGenerator(
             this,
             emitter,
             FullTypeEnvironmentStructure(classType: declaringType),
             TypeExpressionRecipe(supertypeArgument),
-            indexTypeVariablesOnDeclaringClass: true)
+            metadata: true)
         .run()
         .recipe;
   }
@@ -130,7 +131,7 @@
   final ModularEmitter _emitter;
   final TypeEnvironmentStructure _environment;
   final TypeRecipe _recipe;
-  final bool indexTypeVariablesOnDeclaringClass;
+  final bool metadata;
   final bool hackTypeVariablesToAny;
 
   final List<FunctionTypeVariable> functionTypeVariables = [];
@@ -140,10 +141,11 @@
   final List<jsAst.Literal> _fragments = [];
   final List<int> _codes = [];
 
+  RuntimeTypesNeed get _rtiNeed => _encoder._rtiNeed;
+
   _RecipeGenerator(
       this._encoder, this._emitter, this._environment, this._recipe,
-      {this.indexTypeVariablesOnDeclaringClass = false,
-      this.hackTypeVariablesToAny = false});
+      {this.metadata = false, this.hackTypeVariablesToAny = false});
 
   JClosedWorld get _closedWorld => _encoder._closedWorld;
   NativeBasicData get _nativeData => _encoder._nativeData;
@@ -268,6 +270,11 @@
 
       int index = _indexIntoClassTypeVariables(type);
       if (index != null) {
+        // We should only observe erased type arguments if we're generating
+        // subtype metadata.
+        assert(metadata ||
+            _rtiNeed.classNeedsTypeArguments(environment.classType.element));
+
         // Indexed class type variables come after the bound function type
         // variables.
         _emitInteger(1 + environment.bindings.length + index);
@@ -287,7 +294,7 @@
     TypeVariableEntity element = variable.element;
     ClassEntity cls = element.typeDeclaration;
 
-    if (indexTypeVariablesOnDeclaringClass) {
+    if (metadata) {
       TypeEnvironmentStructure environment = _environment;
       if (environment is FullTypeEnvironmentStructure) {
         if (identical(environment.classType.element, cls)) {
@@ -486,12 +493,17 @@
 }
 
 class Ruleset {
+  Map<ClassEntity, ClassEntity> _redirections;
   Map<InterfaceType, _RulesetEntry> _entries;
 
-  Ruleset(this._entries);
-  Ruleset.empty() : this({});
+  Ruleset(this._redirections, this._entries);
+  Ruleset.empty() : this({}, {});
 
-  void add(InterfaceType targetType, Iterable<InterfaceType> supertypes,
+  void addRedirection(ClassEntity targetClass, ClassEntity redirection) {
+    _redirections[targetClass] = redirection;
+  }
+
+  void addEntry(InterfaceType targetType, Iterable<InterfaceType> supertypes,
       Map<TypeVariableType, DartType> typeVariables) {
     _RulesetEntry entry = _entries[targetType] ??= _RulesetEntry();
     entry.addAll(supertypes, typeVariables);
@@ -518,6 +530,8 @@
 
   bool _isObject(InterfaceType type) => identical(type.element, _objectClass);
 
+  bool _isSyntheticClosure(InterfaceType type) => type.element.isClosure;
+
   void _preprocessEntry(InterfaceType targetType, _RulesetEntry entry) {
     entry._supertypes.removeWhere((InterfaceType supertype) =>
         _isObject(supertype) ||
@@ -525,8 +539,8 @@
   }
 
   void _preprocessRuleset(Ruleset ruleset) {
-    ruleset._entries
-        .removeWhere((InterfaceType targetType, _) => _isObject(targetType));
+    ruleset._entries.removeWhere((InterfaceType targetType, _) =>
+        _isObject(targetType) || _isSyntheticClosure(targetType));
     ruleset._entries.forEach(_preprocessEntry);
     ruleset._entries.removeWhere((_, _RulesetEntry entry) => entry.isEmpty);
   }
@@ -543,11 +557,22 @@
       js.concatenateStrings([
         _quote,
         _leftBrace,
-        ...js.joinLiterals(ruleset._entries.entries.map(_encodeEntry), _comma),
+        ...js.joinLiterals([
+          ...ruleset._redirections.entries.map(_encodeRedirection),
+          ...ruleset._entries.entries.map(_encodeEntry),
+        ], _comma),
         _rightBrace,
         _quote,
       ]);
 
+  jsAst.StringConcatenation _encodeRedirection(
+          MapEntry<ClassEntity, ClassEntity> redirection) =>
+      js.concatenateStrings([
+        js.quoteName(_emitter.typeAccessNewRti(redirection.key)),
+        _colon,
+        js.quoteName(_emitter.typeAccessNewRti(redirection.value)),
+      ]);
+
   jsAst.StringConcatenation _encodeEntry(
           MapEntry<InterfaceType, _RulesetEntry> entry) =>
       js.concatenateStrings([
@@ -586,6 +611,6 @@
 
   jsAst.Literal _encodeSupertypeArgument(
           InterfaceType targetType, DartType supertypeArgument) =>
-      _recipeEncoder.encodeDirectSupertypeRecipe(
+      _recipeEncoder.encodeMetadataRecipe(
           _emitter, targetType, supertypeArgument);
 }
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 871cdd2..91d8954 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
@@ -988,12 +988,23 @@
 
   js.Expression _generateFunctionType(ClassEntity /*?*/ enclosingClass,
       FunctionType type, OutputUnit outputUnit) {
+    InterfaceType enclosingType;
+    if (enclosingClass != null && type.containsTypeVariables) {
+      enclosingType = _elementEnvironment.getThisType(enclosingClass);
+      if (!_rtiNeed.classNeedsTypeArguments(enclosingClass)) {
+        // Erase type arguments.
+        List<DartType> typeArguments = enclosingType.typeArguments;
+        type = type.subst(
+            List<DartType>.filled(typeArguments.length, const DynamicType()),
+            typeArguments);
+      }
+    }
+
     if (type.containsTypeVariables) {
       if (_options.experimentNewRti) {
         RecipeEncoding encoding = _rtiRecipeEncoder.encodeRecipe(
             _task.emitter,
-            FullTypeEnvironmentStructure(
-                classType: _elementEnvironment.getThisType(enclosingClass)),
+            FullTypeEnvironmentStructure(classType: enclosingType),
             TypeExpressionRecipe(type));
         _lateNamedTypeVariablesNewRti.addAll(encoding.typeVariables);
         return encoding.recipe;
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 288e35b..aaea216 100644
--- a/pkg/compiler/lib/src/js_emitter/runtime_type_generator.dart
+++ b/pkg/compiler/lib/src/js_emitter/runtime_type_generator.dart
@@ -17,6 +17,7 @@
 import '../js_backend/runtime_types_codegen.dart'
     show ClassChecks, ClassFunctionType, Substitution, TypeCheck;
 import '../js_emitter/sorter.dart';
+import '../options.dart';
 import '../util/util.dart' show Setlet;
 
 import 'code_emitter_task.dart' show CodeEmitterTask, Emitter;
@@ -93,6 +94,8 @@
   final RuntimeTypesEncoder _rtiEncoder;
   final _TypeContainedInOutputUnitVisitor _outputUnitVisitor;
 
+  CompilerOptions get _options => emitterTask.options;
+
   RuntimeTypeGenerator(this._commonElements, this._outputUnitData,
       this.emitterTask, this._namer, this._rtiChecks, this._rtiEncoder)
       : _outputUnitVisitor = new _TypeContainedInOutputUnitVisitor(
@@ -181,7 +184,7 @@
             checkedClass, _namer.operatorIs(checkedClass), js('1'));
       }
       Substitution substitution = check.substitution;
-      if (substitution != null) {
+      if (substitution != null && !_options.experimentNewRti) {
         jsAst.Expression body =
             _getSubstitutionCode(emitterTask.emitter, substitution);
         result.addSubstitution(
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 17d454c..441ab87 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
@@ -1945,6 +1945,10 @@
   js.Statement emitTypeRules(Fragment fragment) {
     if (!_options.experimentNewRti) return js.EmptyStatement();
 
+    bool addJsObjectRedirections = false;
+    ClassEntity jsObjectClass = _commonElements.jsJavaScriptObjectClass;
+    InterfaceType jsObjectType = _elementEnvironment.getThisType(jsObjectClass);
+
     Ruleset ruleset = Ruleset.empty();
     Iterable<Class> classes =
         fragment.libraries.expand((Library library) => library.classes);
@@ -1971,17 +1975,21 @@
       }
 
       if (isInterop) {
-        _classHierarchy
-            .subtypesOf(_commonElements.jsJavaScriptObjectClass)
-            .forEach((ClassEntity interceptor) {
-          ruleset.add(_elementEnvironment.getThisType(interceptor), supertypes,
-              typeVariables);
-        });
+        ruleset.addEntry(jsObjectType, supertypes, typeVariables);
+        addJsObjectRedirections = true;
       } else {
-        ruleset.add(targetType, supertypes, typeVariables);
+        ruleset.addEntry(targetType, supertypes, typeVariables);
       }
     });
 
+    if (addJsObjectRedirections) {
+      _classHierarchy
+          .strictSubtypesOf(jsObjectClass)
+          .forEach((ClassEntity subtype) {
+        ruleset.addRedirection(subtype, jsObjectClass);
+      });
+    }
+
     FunctionEntity method = _closedWorld.commonElements.rtiAddRulesMethod;
     return js.js.statement('#(init.#,JSON.parse(#));', [
       _emitter.staticFunctionAccess(method),
diff --git a/pkg/dartfix/analysis_options.yaml b/pkg/dartfix/analysis_options.yaml
index 1d96fdd..0012141 100644
--- a/pkg/dartfix/analysis_options.yaml
+++ b/pkg/dartfix/analysis_options.yaml
@@ -3,6 +3,9 @@
 analyzer:
   strong-mode:
     implicit-casts: false
+  errors:
+    # Increase the severity of the unused_import hint.
+    unused_import: warning
 
 linter:
   rules:
diff --git a/pkg/dev_compiler/lib/src/analyzer/driver.dart b/pkg/dev_compiler/lib/src/analyzer/driver.dart
index bea1563..ad3e479 100644
--- a/pkg/dev_compiler/lib/src/analyzer/driver.dart
+++ b/pkg/dev_compiler/lib/src/analyzer/driver.dart
@@ -19,7 +19,6 @@
 import 'package:analyzer/src/generated/sdk.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/summary/package_bundle_reader.dart';
-import 'package:analyzer/src/summary/resynthesize.dart';
 import 'package:analyzer/src/summary2/linked_element_factory.dart';
 import 'package:meta/meta.dart';
 
@@ -56,18 +55,6 @@
 
   ExtensionTypeSet _extensionTypes;
 
-  CompilerAnalysisDriver._(this.dartSdk, this._summaryPaths, this.summaryData,
-      this.analysisOptions, this._resourceProvider, this._dartSdkSummaryPath) {
-    var bundle = dartSdk.getLinkedBundle();
-    if (bundle != null) summaryData.addBundle(null, bundle);
-  }
-
-  /// Information about native extension types.
-  ///
-  /// This will be `null` until [linkLibraries] has been called (because we
-  /// could be compiling the Dart SDK, so it would not be available yet).
-  ExtensionTypeSet get extensionTypes => _extensionTypes;
-
   factory CompilerAnalysisDriver(AnalyzerOptions options,
       {SummaryDataStore summaryData,
       List<String> summaryPaths = const [],
@@ -93,6 +80,18 @@
         analysisOptions, resourceProvider, options.dartSdkSummaryPath);
   }
 
+  CompilerAnalysisDriver._(this.dartSdk, this._summaryPaths, this.summaryData,
+      this.analysisOptions, this._resourceProvider, this._dartSdkSummaryPath) {
+    var bundle = dartSdk.getLinkedBundle();
+    if (bundle != null) summaryData.addBundle(null, bundle);
+  }
+
+  /// Information about native extension types.
+  ///
+  /// This will be `null` until [linkLibraries] has been called (because we
+  /// could be compiling the Dart SDK, so it would not be available yet).
+  ExtensionTypeSet get extensionTypes => _extensionTypes;
+
   /// Whether this driver can be reused for the given [dartSdkSummaryPath] and
   /// [summaryPaths].
   bool isCompatibleWith(AnalyzerOptions options, List<String> summaryPaths) {
@@ -130,13 +129,11 @@
 
     _extensionTypes ??= ExtensionTypeSet(
       resynthesizerBuilder.context.typeProvider,
-      resynthesizerBuilder.resynthesizer,
       resynthesizerBuilder.elementFactory,
     );
 
     return LinkedAnalysisDriver(
       analysisOptions,
-      resynthesizerBuilder.resynthesizer,
       resynthesizerBuilder.elementFactory,
       sourceFactory,
       resynthesizerBuilder.libraryUris,
@@ -175,7 +172,6 @@
 /// sources, produced by [CompilerAnalysisDriver.linkLibraries].
 class LinkedAnalysisDriver {
   final AnalysisOptions analysisOptions;
-  final SummaryResynthesizer resynthesizer;
   final LinkedElementFactory elementFactory;
   final SourceFactory sourceFactory;
   final List<String> libraryUris;
@@ -190,7 +186,6 @@
 
   LinkedAnalysisDriver(
       this.analysisOptions,
-      this.resynthesizer,
       this.elementFactory,
       this.sourceFactory,
       this.libraryUris,
@@ -200,21 +195,7 @@
       this._resourceProvider);
 
   TypeProvider get typeProvider {
-    if (resynthesizer != null) {
-      return resynthesizer.typeProvider;
-    } else {
-      return elementFactory.analysisContext.typeProvider;
-    }
-  }
-
-  /// True if [uri] refers to a Dart library (i.e. a Dart source file exists
-  /// with this uri, and it is not a part file).
-  bool _isLibraryUri(String uri) {
-    if (resynthesizer != null) {
-      return resynthesizer.hasLibrarySummary(uri);
-    } else {
-      return elementFactory.isLibraryUri(uri);
-    }
+    return elementFactory.analysisContext.typeProvider;
   }
 
   /// Analyzes the library at [uri] and returns the results of analysis for all
@@ -224,13 +205,7 @@
       throw ArgumentError('"$libraryUri" is not a library');
     }
 
-    AnalysisContext analysisContext;
-    if (resynthesizer != null) {
-      analysisContext = resynthesizer.context;
-    } else {
-      analysisContext = elementFactory.analysisContext;
-    }
-
+    var analysisContext = elementFactory.analysisContext;
     var libraryFile = _fsState.getFileForUri(Uri.parse(libraryUri));
     var analyzer = LibraryAnalyzer(
         analysisOptions as AnalysisOptionsImpl,
@@ -238,7 +213,6 @@
         sourceFactory,
         (uri) => _isLibraryUri('$uri'),
         analysisContext,
-        resynthesizer,
         elementFactory,
         InheritanceManager3(analysisContext.typeSystem),
         libraryFile,
@@ -256,10 +230,12 @@
   }
 
   LibraryElement getLibrary(String uri) {
-    if (resynthesizer != null) {
-      return resynthesizer.getLibraryElement(uri);
-    } else {
-      return elementFactory.libraryOfUri(uri);
-    }
+    return elementFactory.libraryOfUri(uri);
+  }
+
+  /// True if [uri] refers to a Dart library (i.e. a Dart source file exists
+  /// with this uri, and it is not a part file).
+  bool _isLibraryUri(String uri) {
+    return elementFactory.isLibraryUri(uri);
   }
 }
diff --git a/pkg/dev_compiler/lib/src/analyzer/extension_types.dart b/pkg/dev_compiler/lib/src/analyzer/extension_types.dart
index 0175913..9f3399e 100644
--- a/pkg/dev_compiler/lib/src/analyzer/extension_types.dart
+++ b/pkg/dev_compiler/lib/src/analyzer/extension_types.dart
@@ -8,7 +8,6 @@
     show ClassElement, CompilationUnitElement, Element, LibraryElement;
 import 'package:analyzer/dart/element/type.dart' show DartType, InterfaceType;
 import 'package:analyzer/src/generated/resolver.dart' show TypeProvider;
-import 'package:analyzer/src/summary/resynthesize.dart';
 import 'package:analyzer/src/summary2/linked_element_factory.dart';
 
 import 'element_helpers.dart' show getAnnotationName, isBuiltinAnnotation;
@@ -32,7 +31,6 @@
 /// This will provide the [Iterable.first] property, without needing to add
 /// `first` to the `Array.prototype`.
 class ExtensionTypeSet {
-  final SummaryResynthesizer _resynthesizer;
   final LinkedElementFactory _elementFactory;
 
   // Abstract types that may be implemented by both native and non-native
@@ -43,8 +41,7 @@
   final _nativeTypes = HashSet<ClassElement>();
   final _pendingLibraries = HashSet<String>();
 
-  ExtensionTypeSet(
-      TypeProvider types, this._resynthesizer, this._elementFactory) {
+  ExtensionTypeSet(TypeProvider types, this._elementFactory) {
     // TODO(vsm): Eventually, we want to make this extensible - i.e., find
     // annotations in user code as well.  It would need to be summarized in
     // the element model - not searched this way on every compile.  To make this
@@ -75,25 +72,30 @@
     _addPendingExtensionTypes('dart:web_sql');
   }
 
-  void _visitCompilationUnit(CompilationUnitElement unit) {
-    unit.types.forEach(_visitClass);
+  /// Gets the JS peer for this Dart type if any, otherwise null.
+  ///
+  /// For example for dart:_interceptors `JSArray` this will return "Array",
+  /// referring to the JavaScript built-in `Array` type.
+  List<String> getNativePeers(ClassElement classElem) {
+    if (classElem.isDartCoreObject) return ['Object'];
+    var names = getAnnotationName(
+        classElem,
+        (a) =>
+            isBuiltinAnnotation(a, '_js_helper', 'JsPeerInterface') ||
+            isBuiltinAnnotation(a, '_js_helper', 'Native'));
+    if (names == null) return [];
+
+    // Omit the special name "!nonleaf" and any future hacks starting with "!"
+    return names.split(',').where((peer) => !peer.startsWith("!")).toList();
   }
 
-  void _visitClass(ClassElement element) {
-    if (_isNative(element)) {
-      _addExtensionType(getLegacyRawClassType(element), true);
-    }
-  }
+  bool hasNativeSubtype(DartType type) =>
+      isNativeInterface(type.element) || isNativeClass(type.element);
 
-  bool _isNative(ClassElement element) {
-    for (var metadata in element.metadata) {
-      var e = metadata.element?.enclosingElement;
-      if (e.name == 'Native' || e.name == 'JsPeerInterface') {
-        if (e.source.isInSystemLibrary) return true;
-      }
-    }
-    return false;
-  }
+  bool isNativeClass(Element element) => _setContains(_nativeTypes, element);
+
+  bool isNativeInterface(Element element) =>
+      _setContains(_extensibleTypes, element);
 
   void _addExtensionType(InterfaceType t, [bool mustBeNative = false]) {
     if (t.isObject) return;
@@ -113,6 +115,12 @@
     if (supertype != null) _addExtensionType(element.supertype);
   }
 
+  void _addExtensionTypes(String libraryUri) {
+    var library = _getLibraryByUri(libraryUri);
+    _visitCompilationUnit(library.definingCompilationUnit);
+    library.parts.forEach(_visitCompilationUnit);
+  }
+
   void _addExtensionTypesForLibrary(String libraryUri, List<String> typeNames) {
     var library = _getLibraryByUri(libraryUri);
     for (var typeName in typeNames) {
@@ -120,22 +128,22 @@
     }
   }
 
-  void _addExtensionTypes(String libraryUri) {
-    var library = _getLibraryByUri(libraryUri);
-    _visitCompilationUnit(library.definingCompilationUnit);
-    library.parts.forEach(_visitCompilationUnit);
-  }
-
   void _addPendingExtensionTypes(String libraryUri) {
     _pendingLibraries.add(libraryUri);
   }
 
   LibraryElement _getLibraryByUri(String uriStr) {
-    if (_resynthesizer != null) {
-      return _resynthesizer.getLibraryElement(uriStr);
-    } else {
-      return _elementFactory.libraryOfUri(uriStr);
+    return _elementFactory.libraryOfUri(uriStr);
+  }
+
+  bool _isNative(ClassElement element) {
+    for (var metadata in element.metadata) {
+      var e = metadata.element?.enclosingElement;
+      if (e.name == 'Native' || e.name == 'JsPeerInterface') {
+        if (e.source.isInSystemLibrary) return true;
+      }
     }
+    return false;
   }
 
   bool _processPending(Element element) {
@@ -157,28 +165,13 @@
         _processPending(element) && set.contains(element);
   }
 
-  bool isNativeClass(Element element) => _setContains(_nativeTypes, element);
+  void _visitClass(ClassElement element) {
+    if (_isNative(element)) {
+      _addExtensionType(getLegacyRawClassType(element), true);
+    }
+  }
 
-  bool isNativeInterface(Element element) =>
-      _setContains(_extensibleTypes, element);
-
-  bool hasNativeSubtype(DartType type) =>
-      isNativeInterface(type.element) || isNativeClass(type.element);
-
-  /// Gets the JS peer for this Dart type if any, otherwise null.
-  ///
-  /// For example for dart:_interceptors `JSArray` this will return "Array",
-  /// referring to the JavaScript built-in `Array` type.
-  List<String> getNativePeers(ClassElement classElem) {
-    if (classElem.isDartCoreObject) return ['Object'];
-    var names = getAnnotationName(
-        classElem,
-        (a) =>
-            isBuiltinAnnotation(a, '_js_helper', 'JsPeerInterface') ||
-            isBuiltinAnnotation(a, '_js_helper', 'Native'));
-    if (names == null) return [];
-
-    // Omit the special name "!nonleaf" and any future hacks starting with "!"
-    return names.split(',').where((peer) => !peer.startsWith("!")).toList();
+  void _visitCompilationUnit(CompilationUnitElement unit) {
+    unit.types.forEach(_visitClass);
   }
 }
diff --git a/pkg/dev_compiler/lib/src/compiler/js_names.dart b/pkg/dev_compiler/lib/src/compiler/js_names.dart
index ba120a3..54c1f23 100644
--- a/pkg/dev_compiler/lib/src/compiler/js_names.dart
+++ b/pkg/dev_compiler/lib/src/compiler/js_names.dart
@@ -405,3 +405,32 @@
   '[]=': '_set',
   'unary-': '_negate',
 };
+
+// Invalid characters for identifiers, which would need to be escaped.
+final _invalidCharInIdentifier = RegExp(r'[^A-Za-z_$0-9]');
+
+/// Escape [name] to make it into a valid identifier.
+String toJSIdentifier(String name) {
+  if (name.isEmpty) return r'$';
+
+  // Escape any invalid characters
+  StringBuffer buffer;
+  for (int i = 0; i < name.length; i++) {
+    var ch = name[i];
+    var needsEscape = ch == r'$' || _invalidCharInIdentifier.hasMatch(ch);
+    if (needsEscape && buffer == null) {
+      buffer = StringBuffer(name.substring(0, i));
+    }
+    if (buffer != null) {
+      buffer.write(needsEscape ? '\$${ch.codeUnits.join("")}' : ch);
+    }
+  }
+
+  var result = buffer != null ? '$buffer' : name;
+  // Ensure the identifier first character is not numeric and that the whole
+  // identifier is not a keyword.
+  if (result.startsWith(RegExp('[0-9]')) || invalidVariableName(result)) {
+    return '\$$result';
+  }
+  return result;
+}
diff --git a/pkg/dev_compiler/lib/src/compiler/module_builder.dart b/pkg/dev_compiler/lib/src/compiler/module_builder.dart
index 208ca81..ec1ea4a 100644
--- a/pkg/dev_compiler/lib/src/compiler/module_builder.dart
+++ b/pkg/dev_compiler/lib/src/compiler/module_builder.dart
@@ -359,34 +359,5 @@
       .replaceAll('-', '_'));
 }
 
-/// Escape [name] to make it into a valid identifier.
-String toJSIdentifier(String name) {
-  if (name.isEmpty) return r'$';
-
-  // Escape any invalid characters
-  StringBuffer buffer;
-  for (int i = 0; i < name.length; i++) {
-    var ch = name[i];
-    var needsEscape = ch == r'$' || _invalidCharInIdentifier.hasMatch(ch);
-    if (needsEscape && buffer == null) {
-      buffer = StringBuffer(name.substring(0, i));
-    }
-    if (buffer != null) {
-      buffer.write(needsEscape ? '\$${ch.codeUnits.join("")}' : ch);
-    }
-  }
-
-  var result = buffer != null ? '$buffer' : name;
-  // Ensure the identifier first character is not numeric and that the whole
-  // identifier is not a keyword.
-  if (result.startsWith(RegExp('[0-9]')) || invalidVariableName(result)) {
-    return '\$$result';
-  }
-  return result;
-}
-
-// Invalid characters for identifiers, which would need to be escaped.
-final _invalidCharInIdentifier = RegExp(r'[^A-Za-z_$0-9]');
-
 // Replacement string for path separators (i.e., '/', '\', '..').
 final encodedSeparator = "__";
diff --git a/pkg/dev_compiler/lib/src/compiler/shared_command.dart b/pkg/dev_compiler/lib/src/compiler/shared_command.dart
index e75a067..be32b50 100644
--- a/pkg/dev_compiler/lib/src/compiler/shared_command.dart
+++ b/pkg/dev_compiler/lib/src/compiler/shared_command.dart
@@ -503,7 +503,7 @@
   /// Preprocess arguments to determine whether DDK is used in batch mode or as a
   /// persistent worker.
   ///
-  /// When used in batch mode, we expect a `--batch` parameter last.
+  /// When used in batch mode, we expect a `--batch` parameter.
   ///
   /// When used as a persistent bazel worker, the `--persistent_worker` might be
   /// present, and an argument of the form `@path/to/file` might be provided. The
@@ -518,19 +518,19 @@
     bool isKernel = false;
     bool reuseResult = false;
     bool useIncrementalCompiler = false;
-    var len = args.length;
-    for (int i = 0; i < len; i++) {
-      var arg = args[i];
-      var isLastArg = i == len - 1;
-      if (isLastArg && arg.startsWith('@')) {
-        var extra = _readLines(arg.substring(1)).toList();
-        if (extra.remove('--kernel') || extra.remove('-k')) {
-          isKernel = true;
-        }
-        newArgs.addAll(extra);
-      } else if (arg == '--persistent_worker') {
+
+    Iterable<String> argsToParse = args;
+
+    // Expand `@path/to/file`
+    if (args.last.startsWith('@')) {
+      var extra = _readLines(args.last.substring(1));
+      argsToParse = args.take(args.length - 1).followedBy(extra);
+    }
+
+    for (var arg in argsToParse) {
+      if (arg == '--persistent_worker') {
         isWorker = true;
-      } else if (isLastArg && arg == '--batch') {
+      } else if (arg == '--batch') {
         isBatch = true;
       } else if (arg == '--kernel' || arg == '-k') {
         isKernel = true;
diff --git a/pkg/dev_compiler/lib/src/kernel/analyzer_to_kernel.dart b/pkg/dev_compiler/lib/src/kernel/analyzer_to_kernel.dart
index 7b9408a..87caa77 100644
--- a/pkg/dev_compiler/lib/src/kernel/analyzer_to_kernel.dart
+++ b/pkg/dev_compiler/lib/src/kernel/analyzer_to_kernel.dart
@@ -9,6 +9,8 @@
 import 'package:analyzer/dart/element/type.dart' as a;
 import 'package:analyzer/file_system/physical_file_system.dart' as a;
 import 'package:analyzer/src/context/context.dart' as a;
+import 'package:analyzer/src/dart/analysis/restricted_analysis_context.dart'
+    as a;
 import 'package:analyzer/src/dart/element/element.dart' as a;
 import 'package:analyzer/src/dart/element/member.dart' as a;
 import 'package:analyzer/src/dart/element/type.dart' as a;
@@ -21,6 +23,9 @@
 import 'package:analyzer/src/summary/idl.dart' as a;
 import 'package:analyzer/src/summary/package_bundle_reader.dart' as a;
 import 'package:analyzer/src/summary/summary_sdk.dart' as a;
+import 'package:analyzer/src/summary2/linked_bundle_context.dart' as a;
+import 'package:analyzer/src/summary2/linked_element_factory.dart' as a;
+import 'package:analyzer/src/summary2/reference.dart' as a;
 import 'package:front_end/src/api_unstable/ddc.dart'
     show RedirectingFactoryBody;
 import 'package:kernel/kernel.dart';
@@ -72,7 +77,7 @@
 /// Analyzer and modify it to resynthesize directly into Kernel trees, if we
 /// ever need to support a mix of Kernel and Analyzer summary files.
 class AnalyzerToKernel {
-  final a.StoreBasedSummaryResynthesizer _resynth;
+  final a.LinkedElementFactory _resynth;
   final a.SummaryDataStore _summaryData;
   final a.TypeProvider types;
   final a.Dart2TypeSystem rules;
@@ -82,8 +87,8 @@
   final _namespaceBuilder = a.NamespaceBuilder();
 
   AnalyzerToKernel._(this._resynth, this._summaryData)
-      : types = _resynth.typeProvider,
-        rules = _resynth.typeSystem as a.Dart2TypeSystem;
+      : types = _resynth.analysisContext.typeProvider,
+        rules = _resynth.analysisContext.typeSystem as a.Dart2TypeSystem;
 
   /// Create an Analyzer summary to Kernel tree converter, using the provided
   /// [analyzerSdkSummary] and [summaryPaths].
@@ -155,13 +160,12 @@
     }
 
     for (var uri in bundle.unlinkedUnitUris) {
-      var unitInfo = _resynth.getUnlinkedSummary(uri);
-      if (unitInfo.isPartOf) {
+      if (_summaryData.isPartUnit(uri)) {
         // Library parts are handled by their corresponding library.
         continue;
       }
 
-      var element = _resynth.getLibraryElement(uri);
+      var element = _resynth.libraryOfUri(uri);
       libraries.add(visitLibraryElement(element));
       addCompilationUnit(element.definingCompilationUnit);
       element.parts.forEach(addCompilationUnit);
@@ -872,14 +876,23 @@
       : (e.isAsynchronous ? AsyncMarker.Async : AsyncMarker.Sync);
 }
 
-a.StoreBasedSummaryResynthesizer _createSummaryResynthesizer(
+a.LinkedElementFactory _createSummaryResynthesizer(
     a.SummaryDataStore summaryData, String dartSdkPath) {
   var context = _createContextForSummaries(summaryData, dartSdkPath);
-  var resynthesizer = a.StoreBasedSummaryResynthesizer(
-      context, null, context.sourceFactory, /*strongMode*/ true, summaryData);
-  resynthesizer.finishCoreAsyncLibraries();
-  context.typeProvider = resynthesizer.typeProvider;
-  return resynthesizer;
+
+  var elementFactory = a.LinkedElementFactory(
+    context,
+    null,
+    a.Reference.root(),
+  );
+
+  for (var bundle in summaryData.bundles) {
+    elementFactory.addBundle(
+      a.LinkedBundleContext(elementFactory, bundle.bundle2),
+    );
+  }
+
+  return elementFactory;
 }
 
 /// Creates a dummy Analyzer context so we can use summary resynthesizer.
diff --git a/pkg/dev_compiler/lib/src/kernel/compiler.dart b/pkg/dev_compiler/lib/src/kernel/compiler.dart
index 2539d4a..57b2fe0 100644
--- a/pkg/dev_compiler/lib/src/kernel/compiler.dart
+++ b/pkg/dev_compiler/lib/src/kernel/compiler.dart
@@ -505,10 +505,10 @@
   }
 
   static js_ast.Identifier _emitIdentifier(String name) =>
-      js_ast.Identifier(escapeIdentifier(name));
+      js_ast.Identifier(js_ast.toJSIdentifier(name));
 
   static js_ast.TemporaryId _emitTemporaryId(String name) =>
-      js_ast.TemporaryId(escapeIdentifier(name));
+      js_ast.TemporaryId(js_ast.toJSIdentifier(name));
 
   js_ast.Statement _emitClassDeclaration(Class c) {
     // Mixins are unrolled in _defineClass.
diff --git a/pkg/dev_compiler/test/modular_ddc_suite.dart b/pkg/dev_compiler/test/modular_ddc_suite.dart
index f537492..fac2975 100644
--- a/pkg/dev_compiler/test/modular_ddc_suite.dart
+++ b/pkg/dev_compiler/test/modular_ddc_suite.dart
@@ -19,12 +19,12 @@
 String _test_package = 'ddc_modular_test';
 
 Uri sdkRoot = Platform.script.resolve("../../../");
-bool _nnbd = false;
 Options _options;
 String _dartdevcScript;
 String _buildSdkScript;
 String _patchSdkScript;
 String _sdkDevRuntime;
+String _sdkDevRuntimeNnbd;
 
 main(List<String> args) async {
   _options = Options.parse(args);
@@ -69,8 +69,8 @@
 
     ProcessResult result;
 
-    _nnbd = flags.contains('non-nullable');
-    bool allowErrors = _nnbd && _nnbdOptOut.contains(module.name);
+    bool nnbd = flags.contains('non-nullable');
+    bool allowErrors = nnbd && _nnbdOptOut.contains(module.name);
 
     if (module.isSdk) {
       assert(transitiveDependencies.isEmpty);
@@ -81,9 +81,9 @@
           [
             _patchSdkScript,
             sdkRoot.toFilePath(),
-            _sdkDevRuntime,
+            if (nnbd) _sdkDevRuntimeNnbd else _sdkDevRuntime,
             'patched_sdk',
-            if (_nnbd) 'sdk_nnbd'
+            if (nnbd) 'sdk_nnbd'
           ],
           root.toFilePath());
       _checkExitCode(result, this, module);
@@ -310,8 +310,6 @@
       'pkg/dev_compiler/bin/dartdevc.dart', 'snapshots/dartdevc.dart.snapshot');
   _buildSdkScript = await resolve('pkg/dev_compiler/tool/build_sdk.dart');
   _patchSdkScript = await resolve('pkg/dev_compiler/tool/patch_sdk.dart');
-  _sdkDevRuntime = await resolve(_nnbd
-      ? 'sdk_nnbd'
-      : 'sdk'
-          '/lib/_internal/js_dev_runtime');
+  _sdkDevRuntime = await resolve('sdk/lib/_internal/js_dev_runtime');
+  _sdkDevRuntimeNnbd = await resolve('sdk_nnbd/lib/_internal/js_dev_runtime');
 }
diff --git a/pkg/front_end/analysis_options_no_lints.yaml b/pkg/front_end/analysis_options_no_lints.yaml
index 63c5c24..5317b91 100644
--- a/pkg/front_end/analysis_options_no_lints.yaml
+++ b/pkg/front_end/analysis_options_no_lints.yaml
@@ -9,6 +9,7 @@
     - test/flow_analysis/nullability/data/**
     - test/flow_analysis/reachability/data/**
     - test/flow_analysis/type_promotion/data/**
+    - parser_testcases/**
     - testcases/**
     - test/id_testing/data/**
     - test/language_versioning/data/**
diff --git a/pkg/front_end/lib/src/base/errors.dart b/pkg/front_end/lib/src/base/errors.dart
index 735fa5d..feda572 100644
--- a/pkg/front_end/lib/src/base/errors.dart
+++ b/pkg/front_end/lib/src/base/errors.dart
@@ -76,7 +76,12 @@
    * Return a URL that can be used to access documentation for diagnostics with
    * this code, or `null` if there is no published documentation.
    */
-  String get url => null;
+  String get url {
+    if (hasPublishedDocs) {
+      return 'https://dart.dev/tools/diagnostic-messages#${name.toLowerCase()}';
+    }
+    return null;
+  }
 
   @override
   String toString() => uniqueName;
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 3f1df47..ad6ebd4 100644
--- a/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
+++ b/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
@@ -1395,7 +1395,7 @@
             _constant)> templateConstEvalInvalidMethodInvocation = const Template<
         Message Function(String string, Constant _constant)>(
     messageTemplate:
-        r"""The method '#string' can't be invoked on '#constant' within a const context.""",
+        r"""The method '#string' can't be invoked on '#constant' in a constant expression.""",
     withArguments: _withArgumentsConstEvalInvalidMethodInvocation);
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
@@ -1415,7 +1415,7 @@
   String constant = constantParts.join();
   return new Message(codeConstEvalInvalidMethodInvocation,
       message:
-          """The method '${string}' can't be invoked on '${constant}' within a const context.""" +
+          """The method '${string}' can't be invoked on '${constant}' in a constant expression.""" +
               labeler.originMessages,
       arguments: {'string': string, 'constant': _constant});
 }
@@ -1428,7 +1428,7 @@
             _constant)> templateConstEvalInvalidPropertyGet = const Template<
         Message Function(String string, Constant _constant)>(
     messageTemplate:
-        r"""The property '#string' can't be accessed on '#constant' within a const context.""",
+        r"""The property '#string' can't be accessed on '#constant' in a constant expression.""",
     withArguments: _withArgumentsConstEvalInvalidPropertyGet);
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
@@ -1447,7 +1447,7 @@
   String constant = constantParts.join();
   return new Message(codeConstEvalInvalidPropertyGet,
       message:
-          """The property '${string}' can't be accessed on '${constant}' within a const context.""" +
+          """The property '${string}' can't be accessed on '${constant}' in a constant expression.""" +
               labeler.originMessages,
       arguments: {'string': string, 'constant': _constant});
 }
@@ -1459,7 +1459,7 @@
             name)> templateConstEvalInvalidStaticInvocation = const Template<
         Message Function(String name)>(
     messageTemplate:
-        r"""The invocation of '#name' is not allowed within a const context.""",
+        r"""The invocation of '#name' is not allowed in a constant expression.""",
     withArguments: _withArgumentsConstEvalInvalidStaticInvocation);
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
@@ -1475,7 +1475,7 @@
   name = demangleMixinApplicationName(name);
   return new Message(codeConstEvalInvalidStaticInvocation,
       message:
-          """The invocation of '${name}' is not allowed within a const context.""",
+          """The invocation of '${name}' is not allowed in a constant expression.""",
       arguments: {'name': name});
 }
 
@@ -1484,7 +1484,8 @@
     templateConstEvalInvalidStringInterpolationOperand =
     const Template<Message Function(Constant _constant)>(
         messageTemplate:
-            r"""The '#constant' can't be used as part of a string interpolation within a const context, only values of type 'null', 'bool', 'int', 'double', or 'String' can be used.""",
+            r"""The constant value '#constant' can't be used as part of a string interpolation in a constant expression.
+Only values of type 'null', 'bool', 'int', 'double', or 'String' can be used.""",
         withArguments:
             _withArgumentsConstEvalInvalidStringInterpolationOperand);
 
@@ -1504,7 +1505,8 @@
   String constant = constantParts.join();
   return new Message(codeConstEvalInvalidStringInterpolationOperand,
       message:
-          """The '${constant}' can't be used as part of a string interpolation within a const context, only values of type 'null', 'bool', 'int', 'double', or 'String' can be used.""" +
+          """The constant value '${constant}' can't be used as part of a string interpolation in a constant expression.
+Only values of type 'null', 'bool', 'int', 'double', or 'String' can be used.""" +
               labeler.originMessages,
       arguments: {'constant': _constant});
 }
@@ -1641,31 +1643,6 @@
 const Template<
     Message Function(
         String
-            string)> templateConstEvalNonConstantLiteral = const Template<
-        Message Function(String string)>(
-    messageTemplate:
-        r"""Can't have a non-constant #string literal within a const context.""",
-    withArguments: _withArgumentsConstEvalNonConstantLiteral);
-
-// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-const Code<Message Function(String string)> codeConstEvalNonConstantLiteral =
-    const Code<Message Function(String string)>(
-        "ConstEvalNonConstantLiteral", templateConstEvalNonConstantLiteral,
-        analyzerCodes: <String>["NON_CONSTANT_DEFAULT_VALUE"]);
-
-// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-Message _withArgumentsConstEvalNonConstantLiteral(String string) {
-  if (string.isEmpty) throw 'No string provided';
-  return new Message(codeConstEvalNonConstantLiteral,
-      message:
-          """Can't have a non-constant ${string} literal within a const context.""",
-      arguments: {'string': string});
-}
-
-// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-const Template<
-    Message Function(
-        String
             string)> templateConstEvalNonConstantVariableGet = const Template<
         Message Function(String string)>(
     messageTemplate:
diff --git a/pkg/front_end/lib/src/fasta/flow_analysis/flow_analysis.dart b/pkg/front_end/lib/src/fasta/flow_analysis/flow_analysis.dart
index aa2b361..765b78e 100644
--- a/pkg/front_end/lib/src/fasta/flow_analysis/flow_analysis.dart
+++ b/pkg/front_end/lib/src/fasta/flow_analysis/flow_analysis.dart
@@ -130,12 +130,6 @@
 }
 
 class FlowAnalysis<Statement, Expression, Variable, Type> {
-  static bool get _assertionsEnabled {
-    bool result = false;
-    assert(result = true);
-    return result;
-  }
-
   /// The [NodeOperations], used to manipulate expressions.
   final NodeOperations<Expression> nodeOperations;
 
@@ -154,9 +148,6 @@
   /// states.
   final Map<Statement, int> _statementToStackIndex = {};
 
-  /// List of all variables passed to [add].
-  final List<Variable> _addedVariables = [];
-
   FlowModel<Variable, Type> _current;
 
   /// The last boolean condition, for [_conditionTrue] and [_conditionFalse].
@@ -168,19 +159,6 @@
   /// The state when [_condition] evaluates to `false`.
   FlowModel<Variable, Type> _conditionFalse;
 
-  /// If assertions are enabled, keeps track of all variables that have been
-  /// passed into the API (other than through a call to [add]).  The [finish]
-  /// method uses this to verify that the caller doesn't forget to pass a
-  /// variable to [add].
-  ///
-  /// Note: the reason we have to keep track of this set (rather than simply
-  /// checking each variable at the time it is passed into the API) is because
-  /// the client doesn't call `add` until a variable is declared, and in
-  /// erroneous code, it's possible that a variable might be used before its
-  /// declaration.
-  final Set<Variable> _referencedVariables =
-      _assertionsEnabled ? new Set<Variable>() : null;
-
   factory FlowAnalysis(
     NodeOperations<Expression> nodeOperations,
     TypeOperations<Variable, Type> typeOperations,
@@ -196,12 +174,6 @@
   /// Return `true` if the current state is reachable.
   bool get isReachable => _current.reachable;
 
-  /// Add a new [variable], which might be already [assigned].
-  void add(Variable variable, {bool assigned: false}) {
-    _addedVariables.add(variable);
-    _current = _current.add(variable, assigned: assigned);
-  }
-
   void booleanLiteral(Expression expression, bool value) {
     _condition = expression;
     if (value) {
@@ -260,7 +232,6 @@
   /// `null`.
   void conditionEqNull(Expression binaryExpression, Variable variable,
       {bool notEqual: false}) {
-    _variableReferenced(variable);
     if (functionBody.isPotentiallyMutatedInClosure(variable)) {
       return;
     }
@@ -279,7 +250,7 @@
 
   void doStatement_bodyBegin(
       Statement doStatement, Iterable<Variable> loopAssigned) {
-    _current = _current.removePromotedAll(loopAssigned, _referencedVariables);
+    _current = _current.removePromotedAll(loopAssigned);
 
     _statementToStackIndex[doStatement] = _stack.length;
     _stack.add(null); // break
@@ -308,13 +279,6 @@
   /// level function or method.  Performs assertion checks.
   void finish() {
     assert(_stack.isEmpty);
-    assert(() {
-      Set<Variable> variablesNotAdded = _referencedVariables
-          .difference(new Set<Variable>.from(_addedVariables));
-      assert(variablesNotAdded.isEmpty,
-          'Variables not passed to add: $variablesNotAdded');
-      return true;
-    }());
   }
 
   /// Call this method just before visiting the body of a conventional "for"
@@ -373,7 +337,7 @@
   /// [loopAssigned] should be the set of variables that are assigned anywhere
   /// in the loop's condition, updaters, or body.
   void for_conditionBegin(Set<Variable> loopAssigned) {
-    _current = _current.removePromotedAll(loopAssigned, _referencedVariables);
+    _current = _current.removePromotedAll(loopAssigned);
   }
 
   /// Call this method just after visiting the updaters of a conventional "for"
@@ -411,10 +375,10 @@
   /// local variable, or `null` otherwise.
   void forEach_bodyBegin(Set<Variable> loopAssigned, Variable loopVariable) {
     _stack.add(_current);
-    _current = _current.removePromotedAll(loopAssigned, _referencedVariables);
+    _current = _current.removePromotedAll(loopAssigned);
     if (loopVariable != null) {
       assert(loopAssigned.contains(loopVariable));
-      _current = _current.write(typeOperations, loopVariable);
+      _current = _current.write(loopVariable);
     }
   }
 
@@ -440,7 +404,7 @@
     }
 
     if (notPromoted.isNotEmpty) {
-      _current = _current.removePromotedAll(notPromoted, null);
+      _current = _current.removePromotedAll(notPromoted);
     }
   }
 
@@ -510,22 +474,11 @@
 
   /// Return whether the [variable] is definitely assigned in the current state.
   bool isAssigned(Variable variable) {
-    _variableReferenced(variable);
-    VariableModel<Type> variableInfo = _current.variableInfo[variable];
-    if (variableInfo == null) {
-      // In error-free code, variables should always be registered with flow
-      // analysis before they're used.  But this can't be relied on when the
-      // analyzer is doing error recovery.  So if we encounter a variable that
-      // hasn't been registered with flow analysis yet, assume it's unassigned.
-      return false;
-    } else {
-      return variableInfo.assigned;
-    }
+    return _current.infoFor(variable).assigned;
   }
 
   void isExpression_end(
       Expression isExpression, Variable variable, bool isNot, Type type) {
-    _variableReferenced(variable);
     if (functionBody.isPotentiallyMutatedInClosure(variable)) {
       return;
     }
@@ -597,8 +550,7 @@
   /// Retrieves the type that the [variable] is promoted to, if the [variable]
   /// is currently promoted.  Otherwise returns `null`.
   Type promotedType(Variable variable) {
-    _variableReferenced(variable);
-    return _current.variableInfo[variable]?.promotedType;
+    return _current.infoFor(variable).promotedType;
   }
 
   /// Call this method just before visiting one of the cases in the body of a
@@ -611,8 +563,7 @@
   void switchStatement_beginCase(
       bool hasLabel, Iterable<Variable> notPromoted) {
     if (hasLabel) {
-      _current =
-          _stack.last.removePromotedAll(notPromoted, _referencedVariables);
+      _current = _stack.last.removePromotedAll(notPromoted);
     } else {
       _current = _stack.last;
     }
@@ -663,7 +614,7 @@
   void tryCatchStatement_bodyEnd(Iterable<Variable> assignedInBody) {
     FlowModel<Variable, Type> beforeBody = _stack.removeLast();
     FlowModel<Variable, Type> beforeCatch =
-        beforeBody.removePromotedAll(assignedInBody, _referencedVariables);
+        beforeBody.removePromotedAll(assignedInBody);
     _stack.add(beforeCatch);
     _stack.add(_current); // afterBodyAndCatches
     // Tail of the stack: beforeCatch, afterBodyAndCatches
@@ -690,7 +641,6 @@
   }
 
   void tryFinallyStatement_end(Set<Variable> assignedInFinally) {
-    _variablesReferenced(assignedInFinally);
     FlowModel<Variable, Type> afterBody = _stack.removeLast();
     _current = _current.restrict(typeOperations, afterBody, assignedInFinally);
   }
@@ -699,8 +649,7 @@
     FlowModel<Variable, Type> beforeTry = _stack.removeLast();
     FlowModel<Variable, Type> afterBody = _current;
     _stack.add(afterBody);
-    _current = _join(afterBody,
-        beforeTry.removePromotedAll(assignedInBody, _referencedVariables));
+    _current = _join(afterBody, beforeTry.removePromotedAll(assignedInBody));
   }
 
   void whileStatement_bodyBegin(
@@ -718,7 +667,7 @@
   }
 
   void whileStatement_conditionBegin(Iterable<Variable> loopAssigned) {
-    _current = _current.removePromotedAll(loopAssigned, _referencedVariables);
+    _current = _current.removePromotedAll(loopAssigned);
   }
 
   void whileStatement_end() {
@@ -731,8 +680,7 @@
 
   /// Register write of the given [variable] in the current state.
   void write(Variable variable) {
-    _variableReferenced(variable);
-    _current = _current.write(typeOperations, variable);
+    _current = _current.write(variable);
   }
 
   void _conditionalEnd(Expression condition) {
@@ -749,26 +697,6 @@
   FlowModel<Variable, Type> _join(
           FlowModel<Variable, Type> first, FlowModel<Variable, Type> second) =>
       FlowModel.join(typeOperations, first, second);
-
-  /// If assertions are enabled, records that the given variable has been
-  /// referenced.  The [finish] method will verify that all referenced variables
-  /// were eventually passed to [add].
-  void _variableReferenced(Variable variable) {
-    assert(() {
-      _referencedVariables.add(variable);
-      return true;
-    }());
-  }
-
-  /// If assertions are enabled, records that the given variables have been
-  /// referenced.  The [finish] method will verify that all referenced variables
-  /// were eventually passed to [add].
-  void _variablesReferenced(Iterable<Variable> variables) {
-    assert(() {
-      _referencedVariables.addAll(variables);
-      return true;
-    }());
-  }
 }
 
 /// An instance of the [FlowModel] class represents the information gathered by
@@ -795,6 +723,9 @@
   /// variable that is no longer in scope.
   final Map<Variable, VariableModel<Type> /*!*/ > variableInfo;
 
+  /// Variable model for variables that have never been seen before.
+  final VariableModel<Type> _freshVariableInfo;
+
   /// Creates a state object with the given [reachable] status.  All variables
   /// are assumed to be unpromoted and already assigned, so joining another
   /// state with this one will have no effect on it.
@@ -804,7 +735,8 @@
           const {},
         );
 
-  FlowModel._(this.reachable, this.variableInfo) {
+  FlowModel._(this.reachable, this.variableInfo)
+      : _freshVariableInfo = new VariableModel.fresh() {
     assert(() {
       for (VariableModel<Type> value in variableInfo.values) {
         assert(value != null);
@@ -813,16 +745,9 @@
     }());
   }
 
-  /// Updates the state to track a newly declared local [variable].  The
-  /// optional [assigned] boolean indicates whether the variable is assigned at
-  /// the point of declaration.
-  FlowModel<Variable, Type> add(Variable variable, {bool assigned: false}) {
-    Map<Variable, VariableModel<Type>> newVariableInfo =
-        new Map<Variable, VariableModel<Type>>.from(variableInfo);
-    newVariableInfo[variable] = new VariableModel<Type>(null, assigned);
-
-    return new FlowModel<Variable, Type>._(reachable, newVariableInfo);
-  }
+  /// Gets the info for the given [variable], creating it if it doesn't exist.
+  VariableModel<Type> infoFor(Variable variable) =>
+      variableInfo[variable] ?? _freshVariableInfo;
 
   /// Updates the state to indicate that the given [variable] has been
   /// determined to contain a non-null value.
@@ -831,7 +756,7 @@
   /// assigned?  Does it matter?
   FlowModel<Variable, Type> markNonNullable(
       TypeOperations<Variable, Type> typeOperations, Variable variable) {
-    VariableModel<Type> info = variableInfo[variable];
+    VariableModel<Type> info = infoFor(variable);
     Type previousType = info.promotedType;
     previousType ??= typeOperations.variableType(variable);
     Type type = typeOperations.promoteToNonNull(previousType);
@@ -853,7 +778,7 @@
     Variable variable,
     Type type,
   ) {
-    VariableModel<Type> info = variableInfo[variable];
+    VariableModel<Type> info = infoFor(variable);
     Type previousType = info.promotedType;
     previousType ??= typeOperations.variableType(variable);
 
@@ -867,10 +792,6 @@
   /// Updates the state to indicate that the given [variables] are no longer
   /// promoted; they are presumed to have their declared types.
   ///
-  /// If assertions are enabled and [referencedVariables] is not `null`, all
-  /// variables in [variables] will be stored in [referencedVariables] as a side
-  /// effect of this call.
-  ///
   /// This is used at the top of loops to conservatively cancel the promotion of
   /// variables that are modified within the loop, so that we correctly analyze
   /// code like the following:
@@ -887,16 +808,11 @@
   /// and only remove promotions if it can be shown that they aren't restored
   /// later in the loop body.  If we switch to a fixed point analysis, we should
   /// be able to remove this method.
-  FlowModel<Variable, Type> removePromotedAll(
-      Iterable<Variable> variables, Set<Variable> referencedVariables) {
+  FlowModel<Variable, Type> removePromotedAll(Iterable<Variable> variables) {
     Map<Variable, VariableModel<Type>> newVariableInfo;
     for (Variable variable in variables) {
-      assert(() {
-        referencedVariables?.add(variable);
-        return true;
-      }());
-      VariableModel<Type> info = variableInfo[variable];
-      if (info?.promotedType != null) {
+      VariableModel<Type> info = infoFor(variable);
+      if (info.promotedType != null) {
         (newVariableInfo ??= new Map<Variable, VariableModel<Type>>.from(
             variableInfo))[variable] = info.withPromotedType(null);
       }
@@ -934,16 +850,32 @@
     Map<Variable, VariableModel<Type>> newVariableInfo =
         <Variable, VariableModel<Type>>{};
     bool variableInfoMatchesThis = true;
-    bool variableInfoMatchesOther =
-        other.variableInfo.length == variableInfo.length;
+    bool variableInfoMatchesOther = true;
     for (MapEntry<Variable, VariableModel<Type>> entry
         in variableInfo.entries) {
       Variable variable = entry.key;
-      VariableModel<Type> otherModel = other.variableInfo[variable];
-      VariableModel<Type> restricted = entry.value
-          .restrict(typeOperations, otherModel, unsafe.contains(variable));
-      newVariableInfo[variable] = restricted;
-      if (!identical(restricted, entry.value)) variableInfoMatchesThis = false;
+      VariableModel<Type> thisModel = entry.value;
+      VariableModel<Type> otherModel = other.infoFor(variable);
+      VariableModel<Type> restricted = thisModel.restrict(
+          typeOperations, otherModel, unsafe.contains(variable));
+      if (!identical(restricted, _freshVariableInfo)) {
+        newVariableInfo[variable] = restricted;
+      }
+      if (!identical(restricted, thisModel)) variableInfoMatchesThis = false;
+      if (!identical(restricted, otherModel)) variableInfoMatchesOther = false;
+    }
+    for (MapEntry<Variable, VariableModel<Type>> entry
+        in other.variableInfo.entries) {
+      Variable variable = entry.key;
+      if (variableInfo.containsKey(variable)) continue;
+      VariableModel<Type> thisModel = _freshVariableInfo;
+      VariableModel<Type> otherModel = entry.value;
+      VariableModel<Type> restricted = thisModel.restrict(
+          typeOperations, otherModel, unsafe.contains(variable));
+      if (!identical(restricted, _freshVariableInfo)) {
+        newVariableInfo[variable] = restricted;
+      }
+      if (!identical(restricted, thisModel)) variableInfoMatchesThis = false;
       if (!identical(restricted, otherModel)) variableInfoMatchesOther = false;
     }
     assert(variableInfoMatchesThis ==
@@ -975,9 +907,8 @@
   /// previous type promotion is removed.
   ///
   /// TODO(paulberry): allow for writes that preserve type promotions.
-  FlowModel<Variable, Type> write(
-      TypeOperations<Variable, Type> typeOperations, Variable variable) {
-    VariableModel<Type> infoForVar = variableInfo[variable];
+  FlowModel<Variable, Type> write(Variable variable) {
+    VariableModel<Type> infoForVar = infoFor(variable);
     VariableModel<Type> newInfoForVar = infoForVar.write();
     if (identical(newInfoForVar, infoForVar)) return this;
     return _updateVariableInfo(variable, newInfoForVar);
@@ -1110,9 +1041,6 @@
 
 /// Operations on types, abstracted from concrete type interfaces.
 abstract class TypeOperations<Variable, Type> {
-  /// Return `true` if the [variable] is a local variable, not a parameter.
-  bool isLocalVariable(Variable variable);
-
   /// Returns `true` if [type1] and [type2] are the same type.
   bool isSameType(Type type1, Type type2);
 
@@ -1146,6 +1074,12 @@
 
   VariableModel(this.promotedType, this.assigned);
 
+  /// Creates a [VariableModel] representing a variable that's never been seen
+  /// before.
+  VariableModel.fresh()
+      : promotedType = null,
+        assigned = false;
+
   @override
   bool operator ==(Object other) {
     return other is VariableModel<Type> &&
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 f1d6340..656b1ae 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -10,6 +10,8 @@
 
 import '../builder/declaration_builder.dart';
 
+import '../builder/extension_builder.dart';
+
 import '../constant_context.dart' show ConstantContext;
 
 import '../dill/dill_library_builder.dart' show DillLibraryBuilder;
@@ -23,8 +25,7 @@
 import '../modifier.dart'
     show Modifier, constMask, covariantMask, finalMask, lateMask;
 
-import '../names.dart'
-    show callName, emptyName, indexGetName, indexSetName, minusName, plusName;
+import '../names.dart' show callName, emptyName, minusName, plusName;
 
 import '../parser.dart'
     show
@@ -1869,11 +1870,19 @@
       }
       return new ThisPropertyAccessGenerator(this, token, n, getter, setter);
     } else if (declaration.isExtensionInstanceMember) {
+      ExtensionBuilder extensionBuilder = declarationBuilder;
       Builder setter =
           _getCorrespondingSetterBuilder(scope, declaration, name, charOffset);
       // TODO(johnniwinther): Check for constantContext like below?
-      return new ExtensionInstanceAccessGenerator.fromBuilder(this, name,
-          extensionThis, extensionTypeParameters, declaration, token, setter);
+      return new ExtensionInstanceAccessGenerator.fromBuilder(
+          this,
+          extensionBuilder.extension,
+          name,
+          extensionThis,
+          extensionTypeParameters,
+          declaration,
+          token,
+          setter);
     } else if (declaration.isRegularMethod) {
       assert(declaration.isStatic || declaration.isTopLevel);
       return new StaticAccessGenerator(
@@ -3247,17 +3256,21 @@
   @override
   void handleIndexedExpression(
       Token openSquareBracket, Token closeSquareBracket) {
+    assert(checkState(openSquareBracket, [
+      unionOfKinds([ValueKind.Expression, ValueKind.Generator]),
+      unionOfKinds(
+          [ValueKind.Expression, ValueKind.Generator, ValueKind.Initializer])
+    ]));
     debugEvent("IndexedExpression");
     Expression index = popForValue();
     Object receiver = pop();
-    if (receiver is ThisAccessGenerator && receiver.isSuper) {
-      push(new SuperIndexedAccessGenerator(
-          this,
-          openSquareBracket,
-          index,
-          lookupInstanceMember(indexGetName, isSuper: true),
-          lookupInstanceMember(indexSetName, isSuper: true)));
+    if (receiver is Generator) {
+      push(receiver.buildIndexedAccess(index, openSquareBracket));
+    } else if (receiver is Expression) {
+      push(IndexedAccessGenerator.make(
+          this, openSquareBracket, receiver, index, null, null));
     } else {
+      assert(receiver is Initializer);
       push(IndexedAccessGenerator.make(
           this, openSquareBracket, toValue(receiver), index, null, null));
     }
@@ -3502,8 +3515,8 @@
   }
 
   Expression buildExtensionMethodInvocation(
-      int fileOffset, Procedure target, Arguments arguments) {
-    // TODO(johnniwinther): Check type argument count.
+      int fileOffset, Procedure target, Arguments arguments,
+      {bool isTearOff}) {
     List<TypeParameter> typeParameters = target.function.typeParameters;
     LocatedMessage argMessage = checkArgumentsForFunction(
         target.function, arguments, fileOffset, typeParameters);
@@ -3517,10 +3530,13 @@
           message: argMessage);
     }
 
-    StaticInvocation node = new StaticInvocation(target, arguments)
-      ..fileOffset = fileOffset;
-    // TODO(johnniwinther): Check type argument bounds.
-    //libraryBuilder.checkBoundsInStaticInvocation(node, typeEnvironment, uri);
+    Expression node;
+    if (isTearOff) {
+      node = new ExtensionTearOff(target, arguments);
+    } else {
+      node = new StaticInvocation(target, arguments);
+    }
+    node.fileOffset = fileOffset;
     return node;
   }
 
@@ -4751,7 +4767,8 @@
   }
 
   @override
-  void endTypeVariable(Token token, int index, Token extendsOrSuper) {
+  void endTypeVariable(
+      Token token, int index, Token extendsOrSuper, Token variance) {
     debugEvent("TypeVariable");
     UnresolvedType bound = pop();
     // Peek to leave type parameters on top of stack.
@@ -4759,6 +4776,9 @@
 
     TypeVariableBuilder variable = typeVariables[index];
     variable.bound = bound?.builder;
+    if (variance != null) {
+      variable.variance = Variance.fromString(variance.lexeme);
+    }
   }
 
   @override
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 539b86f..0821f5e 100644
--- a/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
@@ -60,7 +60,6 @@
         templateConstEvalInvalidStringInterpolationOperand,
         templateConstEvalInvalidSymbolName,
         templateConstEvalKeyImplementsEqual,
-        templateConstEvalNonConstantLiteral,
         templateConstEvalNonConstantVariableGet,
         templateConstEvalZeroDivisor;
 
@@ -820,8 +819,7 @@
   @override
   Constant visitListLiteral(ListLiteral node) {
     if (!node.isConst) {
-      return report(
-          node, templateConstEvalNonConstantLiteral.withArguments('List'));
+      return reportInvalid(node, "Non-constant list literal");
     }
     final ListConstantBuilder builder =
         new ListConstantBuilder(node, node.typeArgument, this);
@@ -844,8 +842,7 @@
   @override
   Constant visitSetLiteral(SetLiteral node) {
     if (!node.isConst) {
-      return report(
-          node, templateConstEvalNonConstantLiteral.withArguments('Set'));
+      return reportInvalid(node, "Non-constant set literal");
     }
     final SetConstantBuilder builder =
         new SetConstantBuilder(node, node.typeArgument, this);
@@ -868,8 +865,7 @@
   @override
   Constant visitMapLiteral(MapLiteral node) {
     if (!node.isConst) {
-      return report(
-          node, templateConstEvalNonConstantLiteral.withArguments('Map'));
+      return reportInvalid(node, "Non-constant map literal");
     }
     final MapConstantBuilder builder =
         new MapConstantBuilder(node, node.keyType, node.valueType, this);
@@ -891,8 +887,7 @@
 
   @override
   Constant visitFunctionExpression(FunctionExpression node) {
-    return report(
-        node, templateConstEvalNonConstantLiteral.withArguments('Function'));
+    return reportInvalid(node, "Function literal");
   }
 
   @override
@@ -1714,12 +1709,6 @@
       }
     }
 
-    // TODO(kmillikin) For an invalid factory invocation we should adopt a
-    // better message.  This will show something like:
-    //
-    // "The invocation of 'List' is not allowed within a const context."
-    //
-    // Which is not quite right when the code was "new List()".
     String name = target.name.name;
     if (target is Procedure && target.isFactory) {
       if (name.isEmpty) {
@@ -1728,8 +1717,7 @@
         name = '${target.enclosingClass.name}.${name}';
       }
     }
-    return report(
-        node, templateConstEvalInvalidStaticInvocation.withArguments(name));
+    return reportInvalid(node, "Invocation of $name");
   }
 
   @override
diff --git a/pkg/front_end/lib/src/fasta/kernel/constant_int_folder.dart b/pkg/front_end/lib/src/fasta/kernel/constant_int_folder.dart
index e28900f..9bd4a18 100644
--- a/pkg/front_end/lib/src/fasta/kernel/constant_int_folder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/constant_int_folder.dart
@@ -10,10 +10,7 @@
 import 'constant_evaluator.dart';
 
 import '../fasta_codes.dart'
-    show
-        templateConstEvalInvalidMethodInvocation,
-        templateConstEvalNegativeShift,
-        templateConstEvalZeroDivisor;
+    show templateConstEvalNegativeShift, templateConstEvalZeroDivisor;
 
 abstract class ConstantIntFolder {
   final ConstantEvaluator evaluator;
@@ -73,10 +70,7 @@
       case '~':
         return new IntConstant(~operand.value);
       default:
-        return evaluator.report(
-            node,
-            templateConstEvalInvalidMethodInvocation.withArguments(
-                op, operand));
+        return evaluator.reportInvalid(node, "Invalid unary operator $op");
     }
   }
 
@@ -121,8 +115,7 @@
       case '>':
         return evaluator.makeBoolConstant(a > b);
       default:
-        return evaluator.report(node,
-            templateConstEvalInvalidMethodInvocation.withArguments(op, left));
+        return evaluator.reportInvalid(node, "Invalid binary operator $op");
     }
   }
 
@@ -171,10 +164,7 @@
         int intValue = _toUint32(operand.value);
         return new DoubleConstant(_truncate32(~intValue).toDouble());
       default:
-        return evaluator.report(
-            node,
-            templateConstEvalInvalidMethodInvocation.withArguments(
-                op, operand));
+        return evaluator.reportInvalid(node, "Invalid unary operator $op");
     }
   }
 
@@ -225,8 +215,7 @@
       case '>':
         return evaluator.makeBoolConstant(a > b);
       default:
-        return evaluator.report(node,
-            templateConstEvalInvalidMethodInvocation.withArguments(op, left));
+        return evaluator.reportInvalid(node, "Invalid binary operator $op");
     }
   }
 
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 89098b2..e1f4092 100644
--- a/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
@@ -82,8 +82,6 @@
 
 import 'kernel_shadow_ast.dart';
 
-import '../type_inference/type_inferrer.dart';
-
 /// A generator represents a subexpression for which we can't yet build an
 /// expression because we don't yet know the context in which it's used.
 ///
@@ -178,6 +176,11 @@
       bool voidContext: false,
       Procedure interfaceTarget});
 
+  /// Returns a [Generator] or [Expression] representing an index access
+  /// (e.g. `a[b]`) with the generator on the receiver and [index] as the
+  /// index expression.
+  Generator buildIndexedAccess(Expression index, Token token);
+
   /// Returns a [Expression] representing a compile-time error.
   ///
   /// At runtime, an exception will be thrown.
@@ -413,6 +416,12 @@
   }
 
   @override
+  Generator buildIndexedAccess(Expression index, Token token) {
+    return new IndexedAccessGenerator(
+        _helper, token, buildSimpleRead(), index, null, null);
+  }
+
+  @override
   void printOn(StringSink sink) {
     NameSystem syntheticNames = new NameSystem();
     sink.write(", variable: ");
@@ -451,9 +460,6 @@
 
   final Member setter;
 
-  /// Synthetic variable created for [receiver] if need.
-  VariableDeclaration _receiverVariable;
-
   PropertyAccessGenerator(ExpressionGeneratorHelper helper, Token token,
       this.receiver, this.name, this.getter, this.setter)
       : super(helper, token);
@@ -464,11 +470,6 @@
   @override
   String get _plainNameForRead => name.name;
 
-  receiverAccess() {
-    _receiverVariable ??= new VariableDeclaration.forValue(receiver);
-    return new VariableGet(_receiverVariable)..fileOffset = fileOffset;
-  }
-
   @override
   Expression doInvocation(int offset, Arguments arguments) {
     return _helper.buildMethodInvocation(receiver, name, arguments, offset);
@@ -477,8 +478,6 @@
   @override
   void printOn(StringSink sink) {
     NameSystem syntheticNames = new NameSystem();
-    sink.write(", _receiverVariable: ");
-    printNodeOn(_receiverVariable, sink, syntheticNames: syntheticNames);
     sink.write(", receiver: ");
     printNodeOn(receiver, sink, syntheticNames: syntheticNames);
     sink.write(", name: ");
@@ -576,6 +575,12 @@
     return new PropertyPostIncDec(variable, read, write)..fileOffset = offset;
   }
 
+  @override
+  Generator buildIndexedAccess(Expression index, Token token) {
+    return new IndexedAccessGenerator(
+        _helper, token, buildSimpleRead(), index, null, null);
+  }
+
   /// Creates a [Generator] for the access of property [name] on [receiver].
   static Generator make(
       ExpressionGeneratorHelper helper,
@@ -749,6 +754,12 @@
   }
 
   @override
+  Generator buildIndexedAccess(Expression index, Token token) {
+    return new IndexedAccessGenerator(
+        _helper, token, buildSimpleRead(), index, null, null);
+  }
+
+  @override
   void printOn(StringSink sink) {
     NameSystem syntheticNames = new NameSystem();
     sink.write(", name: ");
@@ -864,6 +875,12 @@
   }
 
   @override
+  Generator buildIndexedAccess(Expression index, Token token) {
+    return new IndexedAccessGenerator(
+        _helper, token, buildSimpleRead(), index, null, null);
+  }
+
+  @override
   void printOn(StringSink sink) {
     NameSystem syntheticNames = new NameSystem();
     sink.write(", receiver: ");
@@ -996,6 +1013,12 @@
   }
 
   @override
+  Generator buildIndexedAccess(Expression index, Token token) {
+    return new IndexedAccessGenerator(
+        _helper, token, buildSimpleRead(), index, null, null);
+  }
+
+  @override
   void printOn(StringSink sink) {
     NameSystem syntheticNames = new NameSystem();
     sink.write(", name: ");
@@ -1097,6 +1120,12 @@
   }
 
   @override
+  Generator buildIndexedAccess(Expression index, Token token) {
+    return new IndexedAccessGenerator(
+        _helper, token, buildSimpleRead(), index, null, null);
+  }
+
+  @override
   void printOn(StringSink sink) {
     NameSystem syntheticNames = new NameSystem();
     sink.write(", receiver: ");
@@ -1222,6 +1251,12 @@
   }
 
   @override
+  Generator buildIndexedAccess(Expression index, Token token) {
+    return new IndexedAccessGenerator(
+        _helper, token, buildSimpleRead(), index, null, null);
+  }
+
+  @override
   void printOn(StringSink sink) {
     NameSystem syntheticNames = new NameSystem();
     sink.write(", index: ");
@@ -1324,6 +1359,12 @@
   }
 
   @override
+  Generator buildIndexedAccess(Expression index, Token token) {
+    return new IndexedAccessGenerator(
+        _helper, token, buildSimpleRead(), index, null, null);
+  }
+
+  @override
   void printOn(StringSink sink) {
     NameSystem syntheticNames = new NameSystem();
     sink.write(", index: ");
@@ -1531,6 +1572,12 @@
   }
 
   @override
+  Generator buildIndexedAccess(Expression index, Token token) {
+    return new IndexedAccessGenerator(
+        _helper, token, buildSimpleRead(), index, null, null);
+  }
+
+  @override
   void printOn(StringSink sink) {
     NameSystem syntheticNames = new NameSystem();
     sink.write(", targetName: ");
@@ -1561,6 +1608,8 @@
 ///
 /// These can only occur within an extension instance member.
 class ExtensionInstanceAccessGenerator extends Generator {
+  final Extension extension;
+
   /// The original name of the target.
   final String targetName;
 
@@ -1600,6 +1649,7 @@
   ExtensionInstanceAccessGenerator(
       ExpressionGeneratorHelper helper,
       Token token,
+      this.extension,
       this.targetName,
       this.readTarget,
       this.invokeTarget,
@@ -1613,6 +1663,7 @@
 
   factory ExtensionInstanceAccessGenerator.fromBuilder(
       ExpressionGeneratorHelper helper,
+      Extension extension,
       String targetName,
       VariableDeclaration extensionThis,
       List<TypeParameter> extensionTypeParameters,
@@ -1648,6 +1699,7 @@
     return new ExtensionInstanceAccessGenerator(
         helper,
         token,
+        extension,
         targetName,
         readTarget,
         invokeTarget,
@@ -1694,7 +1746,8 @@
               _extensionTypeParameterCount,
               0,
               _helper.createVariableGet(extensionThis, fileOffset),
-              extensionTypeArguments: _createExtensionTypeArguments()));
+              extensionTypeArguments: _createExtensionTypeArguments()),
+          isTearOff: invokeTarget != null);
     }
     return read;
   }
@@ -1710,9 +1763,10 @@
       write = _makeInvalidWrite(value);
     } else {
       write = new ExtensionSet(
+          extension,
+          _createExtensionTypeArguments(),
           _helper.createVariableGet(extensionThis, fileOffset),
-          new ExtensionAccessTarget(writeTarget, null, ProcedureKind.Setter,
-              _createExtensionTypeArguments()),
+          writeTarget,
           value,
           forEffect: forEffect,
           readOnlyReceiver: true);
@@ -1788,7 +1842,8 @@
               extensionTypeArguments: _createExtensionTypeArguments(),
               typeArguments: arguments.types,
               positionalArguments: arguments.positional,
-              namedArguments: arguments.named));
+              namedArguments: arguments.named),
+          isTearOff: false);
     } else {
       return _helper.buildMethodInvocation(buildSimpleRead(), callName,
           arguments, adjustForImplicitCall(_plainNameForRead, offset),
@@ -1797,6 +1852,12 @@
   }
 
   @override
+  Generator buildIndexedAccess(Expression index, Token token) {
+    return new IndexedAccessGenerator(
+        _helper, token, buildSimpleRead(), index, null, null);
+  }
+
+  @override
   void printOn(StringSink sink) {
     NameSystem syntheticNames = new NameSystem();
     sink.write(", targetName: ");
@@ -1830,6 +1891,8 @@
 ///   }
 ///
 class ExplicitExtensionInstanceAccessGenerator extends Generator {
+  final Extension extension;
+
   /// The name of the original target;
   final String targetName;
 
@@ -1873,6 +1936,7 @@
   ExplicitExtensionInstanceAccessGenerator(
       ExpressionGeneratorHelper helper,
       Token token,
+      this.extension,
       this.targetName,
       this.readTarget,
       this.invokeTarget,
@@ -1890,6 +1954,7 @@
   factory ExplicitExtensionInstanceAccessGenerator.fromBuilder(
       ExpressionGeneratorHelper helper,
       Token token,
+      Extension extension,
       Builder getterBuilder,
       Builder setterBuilder,
       Expression receiver,
@@ -1934,6 +1999,7 @@
     return new ExplicitExtensionInstanceAccessGenerator(
         helper,
         token,
+        extension,
         targetName,
         readTarget,
         invokeTarget,
@@ -1945,7 +2011,7 @@
   }
 
   @override
-  String get _debugName => "InstanceExtensionAccessGenerator";
+  String get _debugName => "ExplicitExtensionIndexedAccessGenerator";
 
   @override
   String get _plainNameForRead => targetName;
@@ -1954,6 +2020,13 @@
     return explicitTypeArguments ?? const <DartType>[];
   }
 
+  /// Returns `true` if performing a read operation is a tear off.
+  ///
+  /// This is the case if [invokeTarget] is non-null, since extension methods
+  /// have both a [readTarget] and an [invokeTarget], whereas extension getters
+  /// only have a [readTarget].
+  bool get isReadTearOff => invokeTarget != null;
+
   @override
   Expression buildSimpleRead() {
     if (isNullAware) {
@@ -1977,7 +2050,8 @@
           readTarget,
           _helper.forest.createArgumentsForExtensionMethod(
               fileOffset, extensionTypeParameterCount, 0, receiver,
-              extensionTypeArguments: _createExtensionTypeArguments()));
+              extensionTypeArguments: _createExtensionTypeArguments()),
+          isTearOff: isReadTearOff);
     }
     return read;
   }
@@ -2006,12 +2080,8 @@
       write = _makeInvalidWrite(value);
     } else {
       write = new ExtensionSet(
-          receiver,
-          new ExtensionAccessTarget(writeTarget, null, ProcedureKind.Setter,
-              _createExtensionTypeArguments()),
-          value,
-          readOnlyReceiver: readOnlyReceiver,
-          forEffect: forEffect);
+          extension, explicitTypeArguments, receiver, writeTarget, value,
+          readOnlyReceiver: readOnlyReceiver, forEffect: forEffect);
     }
     write.fileOffset = offset;
     return write;
@@ -2174,7 +2244,8 @@
               extensionTypeArguments: _createExtensionTypeArguments(),
               typeArguments: arguments.types,
               positionalArguments: arguments.positional,
-              namedArguments: arguments.named));
+              namedArguments: arguments.named),
+          isTearOff: false);
     } else {
       invocation = _helper.buildMethodInvocation(
           _createRead(receiverExpression),
@@ -2193,6 +2264,12 @@
   }
 
   @override
+  Generator buildIndexedAccess(Expression index, Token token) {
+    return new IndexedAccessGenerator(
+        _helper, token, buildSimpleRead(), index, null, null);
+  }
+
+  @override
   void printOn(StringSink sink) {
     NameSystem syntheticNames = new NameSystem();
     sink.write(", targetName: ");
@@ -2204,8 +2281,204 @@
   }
 }
 
+class ExplicitExtensionIndexedAccessGenerator extends Generator {
+  final Extension extension;
+
+  /// The static [Member] generated for the [] operation.
+  ///
+  /// This can be `null` if the extension doesn't have an [] method.
+  final Procedure readTarget;
+
+  /// The static [Member] generated for the []= operation.
+  ///
+  /// This can be `null` if the extension doesn't have an []= method.
+  final Procedure writeTarget;
+
+  /// The expression holding the receiver value for the explicit extension
+  /// access, that is, `a` in `Extension<int>(a)[index]`.
+  final Expression receiver;
+
+  /// The index expression;
+  final Expression index;
+
+  /// The type arguments explicitly passed to the explicit extension access,
+  /// like `<int>` in `Extension<int>(a)[b]`.
+  final List<DartType> explicitTypeArguments;
+
+  /// The number of type parameters declared on the extension declaration.
+  final int extensionTypeParameterCount;
+
+  ExplicitExtensionIndexedAccessGenerator(
+      ExpressionGeneratorHelper helper,
+      Token token,
+      this.extension,
+      this.readTarget,
+      this.writeTarget,
+      this.receiver,
+      this.index,
+      this.explicitTypeArguments,
+      this.extensionTypeParameterCount)
+      : assert(readTarget != null || writeTarget != null),
+        assert(receiver != null),
+        super(helper, token);
+
+  factory ExplicitExtensionIndexedAccessGenerator.fromBuilder(
+      ExpressionGeneratorHelper helper,
+      Token token,
+      Extension extension,
+      Builder getterBuilder,
+      Builder setterBuilder,
+      Expression receiver,
+      Expression index,
+      List<DartType> explicitTypeArguments,
+      int extensionTypeParameterCount) {
+    Procedure readTarget;
+    if (getterBuilder != null) {
+      if (getterBuilder is AccessErrorBuilder) {
+        AccessErrorBuilder error = getterBuilder;
+        getterBuilder = error.builder;
+        // We should only see an access error here if we've looked up a setter
+        // when not explicitly looking for a setter.
+        assert(getterBuilder is MemberBuilder);
+      } else if (getterBuilder is MemberBuilder) {
+        MemberBuilder procedureBuilder = getterBuilder;
+        readTarget = procedureBuilder.member;
+      } else {
+        return unhandled(
+            "${getterBuilder.runtimeType}",
+            "InstanceExtensionAccessGenerator.fromBuilder",
+            offsetForToken(token),
+            helper.uri);
+      }
+    }
+    Procedure writeTarget;
+    if (setterBuilder is MemberBuilder) {
+      MemberBuilder memberBuilder = setterBuilder;
+      writeTarget = memberBuilder.member;
+    }
+    return new ExplicitExtensionIndexedAccessGenerator(
+        helper,
+        token,
+        extension,
+        readTarget,
+        writeTarget,
+        receiver,
+        index,
+        explicitTypeArguments,
+        extensionTypeParameterCount);
+  }
+
+  List<DartType> _createExtensionTypeArguments() {
+    return explicitTypeArguments ?? const <DartType>[];
+  }
+
+  String get _plainNameForRead => "[]";
+
+  String get _debugName => "ExplicitExtensionIndexedAccessGenerator";
+
+  @override
+  Expression buildSimpleRead() {
+    if (readTarget == null) {
+      return _makeInvalidRead();
+    }
+    return _helper.buildExtensionMethodInvocation(
+        fileOffset,
+        readTarget,
+        _forest.createArgumentsForExtensionMethod(
+            fileOffset, extensionTypeParameterCount, 0, receiver,
+            extensionTypeArguments: _createExtensionTypeArguments(),
+            positionalArguments: <Expression>[index]),
+        isTearOff: false);
+  }
+
+  @override
+  Expression buildAssignment(Expression value, {bool voidContext: false}) {
+    if (writeTarget == null) {
+      return _makeInvalidWrite(value);
+    }
+    if (voidContext) {
+      return _helper.buildExtensionMethodInvocation(
+          fileOffset,
+          writeTarget,
+          _forest.createArgumentsForExtensionMethod(
+              fileOffset, extensionTypeParameterCount, 0, receiver,
+              extensionTypeArguments: _createExtensionTypeArguments(),
+              positionalArguments: <Expression>[index, value]),
+          isTearOff: false);
+    } else {
+      return new ExtensionIndexSet(
+          extension, explicitTypeArguments, receiver, writeTarget, index, value)
+        ..fileOffset = fileOffset;
+    }
+  }
+
+  @override
+  Expression buildIfNullAssignment(Expression value, DartType type, int offset,
+      {bool voidContext: false}) {
+    return new IfNullExtensionIndexSet(extension, explicitTypeArguments,
+        receiver, readTarget, writeTarget, index, value,
+        readOffset: fileOffset,
+        testOffset: offset,
+        writeOffset: fileOffset,
+        forEffect: voidContext)
+      ..fileOffset = offset;
+  }
+
+  Expression buildCompoundAssignment(Name binaryOperator, Expression value,
+      {int offset: TreeNode.noOffset,
+      bool voidContext: false,
+      Procedure interfaceTarget,
+      bool isPreIncDec: false,
+      bool isPostIncDec: false}) {
+    return new CompoundExtensionIndexSet(extension, explicitTypeArguments,
+        receiver, readTarget, writeTarget, index, binaryOperator, value,
+        readOffset: fileOffset,
+        binaryOffset: offset,
+        writeOffset: fileOffset,
+        forEffect: voidContext,
+        forPostIncDec: isPostIncDec);
+  }
+
+  @override
+  Expression buildPostfixIncrement(Name binaryOperator,
+      {int offset = TreeNode.noOffset,
+      bool voidContext = false,
+      Procedure interfaceTarget}) {
+    Expression value = _forest.createIntLiteral(1, null)..fileOffset = offset;
+    return buildCompoundAssignment(binaryOperator, value,
+        offset: offset,
+        voidContext: voidContext,
+        interfaceTarget: interfaceTarget,
+        isPostIncDec: true);
+  }
+
+  @override
+  Expression doInvocation(int offset, Arguments arguments) {
+    return _helper.buildMethodInvocation(
+        buildSimpleRead(), callName, arguments, offset,
+        isImplicitCall: true);
+  }
+
+  @override
+  Generator buildIndexedAccess(Expression index, Token token) {
+    return new IndexedAccessGenerator(
+        _helper, token, buildSimpleRead(), index, null, null);
+  }
+
+  @override
+  void printOn(StringSink sink) {
+    NameSystem syntheticNames = new NameSystem();
+    sink.write(", index: ");
+    printNodeOn(index, sink, syntheticNames: syntheticNames);
+    sink.write(", readTarget: ");
+    printQualifiedNameOn(readTarget, sink, syntheticNames: syntheticNames);
+    sink.write(", writeTarget: ");
+    printQualifiedNameOn(writeTarget, sink, syntheticNames: syntheticNames);
+  }
+}
+
 /// A [ExplicitExtensionAccessGenerator] represents a subexpression whose
-/// prefix is a forced extension resolution.
+/// prefix is an explicit extension application.
 ///
 /// For instance
 ///
@@ -2281,28 +2554,33 @@
     return _makeInvalidRead();
   }
 
+  Generator _createInstanceAccess(Name name, {bool isNullAware}) {
+    Builder getter = extensionBuilder.lookupLocalMember(name.name);
+    Builder setter =
+        extensionBuilder.lookupLocalMember(name.name, setter: true);
+    if (getter == null && setter == null) {
+      return new UnresolvedNameGenerator(_helper, token, name);
+    }
+    return new ExplicitExtensionInstanceAccessGenerator.fromBuilder(
+        _helper,
+        token,
+        extensionBuilder.extension,
+        getter,
+        setter,
+        receiver,
+        explicitTypeArguments,
+        extensionBuilder.typeParameters?.length ?? 0,
+        isNullAware: isNullAware);
+  }
+
   /* Expression | Generator */ buildPropertyAccess(
       IncompleteSendGenerator send, int operatorOffset, bool isNullAware) {
     if (_helper.constantContext != ConstantContext.none) {
       _helper.addProblem(
           messageNotAConstantExpression, fileOffset, token.length);
     }
-    Builder getter = extensionBuilder.lookupLocalMember(send.name.name);
-    Builder setter =
-        extensionBuilder.lookupLocalMember(send.name.name, setter: true);
-    if (getter == null && setter == null) {
-      return new UnresolvedNameGenerator(_helper, token, send.name);
-    }
     Generator generator =
-        new ExplicitExtensionInstanceAccessGenerator.fromBuilder(
-            _helper,
-            token,
-            getter,
-            setter,
-            receiver,
-            explicitTypeArguments,
-            extensionBuilder.typeParameters?.length ?? 0,
-            isNullAware: isNullAware);
+        _createInstanceAccess(send.name, isNullAware: isNullAware);
     if (send.arguments != null) {
       return generator.doInvocation(offsetForToken(send.token), send.arguments);
     } else {
@@ -2312,8 +2590,8 @@
 
   @override
   doInvocation(int offset, Arguments arguments) {
-    return unimplemented(
-        "ExplicitExtensionAccessGenerator.doInvocation", fileOffset, _uri);
+    Generator generator = _createInstanceAccess(callName, isNullAware: false);
+    return generator.doInvocation(offset, arguments);
   }
 
   @override
@@ -2329,6 +2607,26 @@
   }
 
   @override
+  Generator buildIndexedAccess(Expression index, Token token) {
+    Builder getter = extensionBuilder.lookupLocalMember(indexGetName.name);
+    Builder setter = extensionBuilder.lookupLocalMember(indexSetName.name);
+    if (getter == null && setter == null) {
+      return new UnresolvedNameGenerator(_helper, token, indexGetName);
+    }
+
+    return new ExplicitExtensionIndexedAccessGenerator.fromBuilder(
+        _helper,
+        token,
+        extensionBuilder.extension,
+        getter,
+        setter,
+        receiver,
+        index,
+        explicitTypeArguments,
+        extensionBuilder.typeParameters?.length ?? 0);
+  }
+
+  @override
   void printOn(StringSink sink) {
     sink.write(", extensionBuilder: ");
     sink.write(extensionBuilder);
@@ -2413,6 +2711,12 @@
   }
 
   @override
+  Generator buildIndexedAccess(Expression index, Token token) {
+    return new IndexedAccessGenerator(
+        _helper, token, buildSimpleRead(), index, null, null);
+  }
+
+  @override
   void printOn(StringSink sink) {
     sink.write(", builder: ");
     sink.write(builder);
@@ -2559,6 +2863,12 @@
   }
 
   @override
+  Generator buildIndexedAccess(Expression index, Token token) {
+    return new IndexedAccessGenerator(
+        _helper, token, buildSimpleRead(), index, null, null);
+  }
+
+  @override
   void printOn(StringSink sink) {
     sink.write(", prefixGenerator: ");
     sink.write(prefixGenerator);
@@ -2878,6 +3188,14 @@
   }
 
   @override
+  Generator buildIndexedAccess(Expression index, Token token) {
+    // TODO(johnniwinther): The read-only quality of the variable should be
+    // passed on to the generator.
+    return new IndexedAccessGenerator(
+        _helper, token, buildSimpleRead(), index, null, null);
+  }
+
+  @override
   void printOn(StringSink sink) {
     NameSystem syntheticNames = new NameSystem();
     sink.write(", expression: ");
@@ -3001,6 +3319,12 @@
     }
     return buildError(arguments);
   }
+
+  @override
+  Generator buildIndexedAccess(Expression index, Token token) {
+    return new IndexedAccessGenerator(
+        _helper, token, buildSimpleRead(), index, null, null);
+  }
 }
 
 class UnresolvedNameGenerator extends ErroneousExpressionGenerator {
@@ -3077,6 +3401,12 @@
     return buildError(_forest.createArguments(fileOffset, <Expression>[value]),
         isSetter: true);
   }
+
+  @override
+  Generator buildIndexedAccess(Expression index, Token token) {
+    return new IndexedAccessGenerator(
+        _helper, token, buildSimpleRead(), index, null, null);
+  }
 }
 
 class UnlinkedGenerator extends Generator {
@@ -3196,6 +3526,12 @@
   Expression doInvocation(int offset, Arguments arguments) {
     return unsupported("doInvocation", offset, _uri);
   }
+
+  @override
+  Generator buildIndexedAccess(Expression index, Token token) {
+    return new IndexedAccessGenerator(
+        _helper, token, buildSimpleRead(), index, null, null);
+  }
 }
 
 abstract class ContextAwareGenerator extends Generator {
@@ -3258,6 +3594,12 @@
     return _helper.buildProblem(messageIllegalAssignmentToNonAssignable,
         fileOffset, lengthForToken(token));
   }
+
+  @override
+  Generator buildIndexedAccess(Expression index, Token token) {
+    return new IndexedAccessGenerator(
+        _helper, token, buildSimpleRead(), index, null, null);
+  }
 }
 
 class DelayedAssignment extends ContextAwareGenerator {
@@ -3499,6 +3841,12 @@
   Expression _makeInvalidWrite(Expression value) => _makeInvalidRead();
 
   @override
+  Generator buildIndexedAccess(Expression index, Token token) {
+    return new IndexedAccessGenerator(
+        _helper, token, buildSimpleRead(), index, null, null);
+  }
+
+  @override
   void printOn(StringSink sink) {
     sink.write(", prefix: ");
     sink.write(prefix.name);
@@ -3587,6 +3935,12 @@
   }
 
   @override
+  Generator buildIndexedAccess(Expression index, Token token) {
+    return new IndexedAccessGenerator(
+        _helper, token, buildSimpleRead(), index, null, null);
+  }
+
+  @override
   void printOn(StringSink sink) {
     sink.write(", prefixGenerator: ");
     prefixGenerator.printOn(sink);
@@ -3688,6 +4042,12 @@
       Constness constness) {
     return buildProblem();
   }
+
+  @override
+  Generator buildIndexedAccess(Expression index, Token token) {
+    return new IndexedAccessGenerator(
+        _helper, token, buildSimpleRead(), index, null, null);
+  }
 }
 
 /// A [ThisAccessGenerator] represents a subexpression whose prefix is `this`
@@ -3910,6 +4270,20 @@
     return buildAssignmentError();
   }
 
+  @override
+  Generator buildIndexedAccess(Expression index, Token token) {
+    if (isSuper) {
+      return new SuperIndexedAccessGenerator(
+          _helper,
+          token,
+          index,
+          _helper.lookupInstanceMember(indexGetName, isSuper: true),
+          _helper.lookupInstanceMember(indexSetName, isSuper: true));
+    } else {
+      return new ThisIndexedAccessGenerator(_helper, token, index, null, null);
+    }
+  }
+
   Expression buildAssignmentError() {
     return _helper.buildProblem(
         isSuper ? messageCannotAssignToSuper : messageNotAnLvalue,
@@ -4045,6 +4419,11 @@
   }
 
   @override
+  Generator buildIndexedAccess(Expression index, Token token) {
+    return unsupported("buildIndexedAccess", offsetForToken(token), _uri);
+  }
+
+  @override
   void printOn(StringSink sink) {
     sink.write(", name: ");
     sink.write(name.name);
@@ -4119,6 +4498,11 @@
   }
 
   @override
+  Generator buildIndexedAccess(Expression index, Token token) {
+    return unsupported("buildIndexedAccess", offsetForToken(token), _uri);
+  }
+
+  @override
   void printOn(StringSink sink) {
     sink.write(", name: ");
     sink.write(name.name);
diff --git a/pkg/front_end/lib/src/fasta/kernel/expression_generator_helper.dart b/pkg/front_end/lib/src/fasta/kernel/expression_generator_helper.dart
index 3231dc7..a6d6421 100644
--- a/pkg/front_end/lib/src/fasta/kernel/expression_generator_helper.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/expression_generator_helper.dart
@@ -82,7 +82,8 @@
       {Constness constness, int charOffset});
 
   Expression buildExtensionMethodInvocation(
-      int fileOffset, Procedure target, Arguments arguments);
+      int fileOffset, Procedure target, Arguments arguments,
+      {bool isTearOff});
 
   Expression throwNoSuchMethodError(
       Expression receiver, String name, Arguments arguments, int offset,
diff --git a/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart b/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
index b761c58..816cc1e 100644
--- a/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
@@ -41,6 +41,8 @@
       switch (node.kind) {
         case InternalExpressionKind.Cascade:
           return visitCascade(node, typeContext);
+        case InternalExpressionKind.CompoundExtensionIndexSet:
+          return visitCompoundExtensionIndexSet(node, typeContext);
         case InternalExpressionKind.CompoundIndexSet:
           return visitCompoundIndexSet(node, typeContext);
         case InternalExpressionKind.CompoundPropertySet:
@@ -49,10 +51,16 @@
           return visitCompoundSuperIndexSet(node, typeContext);
         case InternalExpressionKind.DeferredCheck:
           return visitDeferredCheck(node, typeContext);
+        case InternalExpressionKind.ExtensionIndexSet:
+          return visitExtensionIndexSet(node, typeContext);
+        case InternalExpressionKind.ExtensionTearOff:
+          return visitExtensionTearOff(node, typeContext);
         case InternalExpressionKind.ExtensionSet:
           return visitExtensionSet(node, typeContext);
         case InternalExpressionKind.IfNull:
           return visitIfNull(node, typeContext);
+        case InternalExpressionKind.IfNullExtensionIndexSet:
+          return visitIfNullExtensionIndexSet(node, typeContext);
         case InternalExpressionKind.IfNullIndexSet:
           return visitIfNullIndexSet(node, typeContext);
         case InternalExpressionKind.IfNullPropertySet:
@@ -381,16 +389,50 @@
     // No inference needs to be done.
   }
 
+  ExpressionInferenceResult visitExtensionTearOff(
+      ExtensionTearOff node, DartType typeContext) {
+    FunctionType calleeType = node.target != null
+        ? node.target.function.functionType
+        : new FunctionType([], const DynamicType());
+    bool hadExplicitTypeArguments =
+        getExplicitTypeArguments(node.arguments) != null;
+    DartType inferredType = inferrer.inferInvocation(typeContext,
+        node.fileOffset, calleeType, calleeType.returnType, node.arguments);
+    Expression replacement = new StaticInvocation(node.target, node.arguments);
+    if (!inferrer.isTopLevel &&
+        !hadExplicitTypeArguments &&
+        node.target != null) {
+      inferrer.library.checkBoundsInStaticInvocation(
+          replacement, inferrer.typeSchemaEnvironment, inferrer.helper.uri,
+          inferred: true);
+    }
+    node.replaceWith(replacement);
+    inferredType =
+        inferrer.instantiateTearOff(inferredType, typeContext, replacement);
+    return new ExpressionInferenceResult(inferredType);
+  }
+
   ExpressionInferenceResult visitExtensionSet(
       ExtensionSet node, DartType typeContext) {
-    // Since the variable is not used in the body we don't need to type infer
-    // it.  We can just type infer the body.
     ExpressionInferenceResult receiverResult = inferrer.inferExpression(
         node.receiver, const UnknownType(), true,
         isVoidAllowed: false);
 
+    List<DartType> extensionTypeArguments =
+        inferrer.computeExtensionTypeArgument(node.extension,
+            node.explicitTypeArguments, receiverResult.inferredType);
+
+    DartType receiverType = inferrer.getExtensionReceiverType(
+        node.extension, extensionTypeArguments);
+
+    inferrer.ensureAssignable(receiverType, receiverResult.inferredType,
+        node.receiver, node.receiver.fileOffset);
+
+    ObjectAccessTarget target = new ExtensionAccessTarget(
+        node.target, null, ProcedureKind.Setter, extensionTypeArguments);
+
     DartType valueType =
-        inferrer.getSetterType(node.target, receiverResult.inferredType);
+        inferrer.getSetterType(target, receiverResult.inferredType);
 
     ExpressionInferenceResult valueResult = inferrer.inferExpression(
         node.value, const UnknownType(), true,
@@ -417,9 +459,9 @@
       receiver = createVariableGet(receiverVariable);
     }
     Expression assignment = new StaticInvocation(
-        node.target.member,
+        node.target,
         new Arguments(<Expression>[receiver, value],
-            types: node.target.inferredExtensionTypeArguments)
+            types: extensionTypeArguments)
           ..fileOffset = node.fileOffset)
       ..fileOffset = node.fileOffset;
 
@@ -2268,9 +2310,9 @@
     Expression assignment;
     if (indexSetTarget.isMissing) {
       assignment = inferrer.helper.buildProblem(
-          templateSuperclassHasNoMethod.withArguments('[]='),
+          templateSuperclassHasNoMethod.withArguments(indexSetName.name),
           node.fileOffset,
-          '[]='.length);
+          noLength);
     } else {
       assert(indexSetTarget.isInstanceMember);
       inferrer.instrumentation?.record(inferrer.uri, node.fileOffset, 'target',
@@ -2295,6 +2337,85 @@
     return new ExpressionInferenceResult(inferredType, replacement);
   }
 
+  ExpressionInferenceResult visitExtensionIndexSet(
+      ExtensionIndexSet node, DartType typeContext) {
+    ExpressionInferenceResult receiverResult = inferrer.inferExpression(
+        node.receiver, const UnknownType(), true,
+        isVoidAllowed: false);
+
+    List<DartType> extensionTypeArguments =
+        inferrer.computeExtensionTypeArgument(node.extension,
+            node.explicitTypeArguments, receiverResult.inferredType);
+
+    DartType receiverType = inferrer.getExtensionReceiverType(
+        node.extension, extensionTypeArguments);
+
+    inferrer.ensureAssignable(receiverType, receiverResult.inferredType,
+        node.receiver, node.receiver.fileOffset);
+
+    VariableDeclaration receiverVariable =
+        createVariable(node.receiver, receiverType);
+
+    ObjectAccessTarget target = new ExtensionAccessTarget(
+        node.setter, null, ProcedureKind.Operator, extensionTypeArguments);
+
+    DartType indexType = inferrer.getIndexKeyType(target, receiverType);
+    DartType valueType = inferrer.getIndexSetValueType(target, receiverType);
+
+    ExpressionInferenceResult indexResult = inferrer
+        .inferExpression(node.index, indexType, true, isVoidAllowed: true);
+
+    inferrer.ensureAssignable(
+        indexType, indexResult.inferredType, node.index, node.index.fileOffset);
+
+    VariableDeclaration indexVariable =
+        createVariable(node.index, indexResult.inferredType);
+
+    ExpressionInferenceResult valueResult = inferrer
+        .inferExpression(node.value, valueType, true, isVoidAllowed: true);
+    inferrer.ensureAssignable(
+        valueType, valueResult.inferredType, node.value, node.value.fileOffset);
+    VariableDeclaration valueVariable =
+        createVariable(node.value, valueResult.inferredType);
+
+    // The inferred type is that inferred type of the value expression and not
+    // the type of the value parameter.
+    DartType inferredType = valueResult.inferredType;
+
+    Expression replacement;
+    Expression assignment;
+    if (target.isMissing) {
+      assignment = inferrer.helper.buildProblem(
+          templateUndefinedMethod.withArguments(
+              indexSetName.name, receiverType),
+          node.fileOffset,
+          noLength);
+    } else {
+      assert(target.isExtensionMember);
+      assignment = new StaticInvocation(
+          target.member,
+          new Arguments(<Expression>[
+            createVariableGet(receiverVariable),
+            createVariableGet(indexVariable),
+            createVariableGet(valueVariable)
+          ], types: target.inferredExtensionTypeArguments)
+            ..fileOffset = node.fileOffset)
+        ..fileOffset = node.fileOffset;
+    }
+    VariableDeclaration assignmentVariable =
+        createVariable(assignment, const VoidType());
+    node.replaceWith(replacement = new Let(
+        receiverVariable,
+        createLet(
+            indexVariable,
+            createLet(
+                valueVariable,
+                createLet(
+                    assignmentVariable, createVariableGet(valueVariable)))))
+      ..fileOffset = node.fileOffset);
+    return new ExpressionInferenceResult(inferredType, replacement);
+  }
+
   ExpressionInferenceResult visitIfNullIndexSet(
       IfNullIndexSet node, DartType typeContext) {
     ExpressionInferenceResult receiverResult = inferrer.inferExpression(
@@ -2436,18 +2557,18 @@
 
     Expression inner;
     if (node.forEffect) {
-      // Encode `o[a] ??= b`, if `node.readOnlyReceiver` is false, as:
+      // Encode `Extension(o)[a] ??= b`, if `node.readOnlyReceiver` is false,
+      // as:
       //
-      //     let v1 = o in
-      //     let v2 = a in
-      //     let v3 = v1[v2] in
-      //        v3 == null ? v1.[]=(v2, b) : null
+      //     let receiverVariable = o in
+      //     let indexVariable = a in
+      //        receiverVariable[indexVariable]  == null
+      //          ? receiverVariable.[]=(indexVariable, b) : null
       //
       // and if `node.readOnlyReceiver` is true as:
       //
-      //     let v2 = a in
-      //     let v3 = o[v2] in
-      //        v3 == null ? o.[]=(v2, b) : null
+      //     let indexVariable = a in
+      //         o[indexVariable] == null ? o.[]=(indexVariable, b) : null
       //
       MethodInvocation equalsNull =
           createEqualsNull(node.testOffset, read, equalsMember);
@@ -2456,26 +2577,28 @@
         ..fileOffset = node.testOffset;
       inner = createLet(indexVariable, conditional);
     } else {
-      // Encode `o[a] ??= b` as, if `node.readOnlyReceiver` is false, as:
+      // Encode `Extension(o)[a] ??= b` as, if `node.readOnlyReceiver` is false,
+      // as:
       //
-      //     let v1 = o in
-      //     let v2 = a in
-      //     let v3 = v1[v2] in
-      //       v3 == null
-      //        ? (let v4 = b in
-      //           let _ = v1.[]=(v2, v4) in
-      //           v4)
-      //        : v3
+      //     let receiverVariable = o in
+      //     let indexVariable = a in
+      //     let readVariable = receiverVariable[indexVariable] in
+      //       readVariable == null
+      //        ? (let valueVariable = b in
+      //           let writeVariable =
+      //             receiverVariable.[]=(indexVariable, valueVariable) in
+      //               valueVariable)
+      //        : readVariable
       //
       // and if `node.readOnlyReceiver` is true as:
       //
-      //     let v2 = a in
-      //     let v3 = o[v2] in
-      //       v3 == null
-      //        ? (let v4 = b in
-      //           let _ = o.[]=(v2, v4) in
-      //           v4)
-      //        : v3
+      //     let indexVariable = a in
+      //     let readVariable = o[indexVariable] in
+      //       readVariable == null
+      //        ? (let valueVariable = b in
+      //           let writeVariable = o.[]=(indexVariable, valueVariable) in
+      //               valueVariable)
+      //        : readVariable
       //
       //
       assert(valueVariable != null);
@@ -2646,6 +2769,171 @@
     return new ExpressionInferenceResult(inferredType, replacement);
   }
 
+  ExpressionInferenceResult visitIfNullExtensionIndexSet(
+      IfNullExtensionIndexSet node, DartType typeContext) {
+    ExpressionInferenceResult receiverResult = inferrer.inferExpression(
+        node.receiver, const UnknownType(), true,
+        isVoidAllowed: false);
+
+    List<DartType> extensionTypeArguments =
+        inferrer.computeExtensionTypeArgument(node.extension,
+            node.explicitTypeArguments, receiverResult.inferredType);
+
+    DartType receiverType = inferrer.getExtensionReceiverType(
+        node.extension, extensionTypeArguments);
+
+    inferrer.ensureAssignable(receiverType, receiverResult.inferredType,
+        node.receiver, node.receiver.fileOffset);
+
+    VariableDeclaration receiverVariable =
+        createVariable(node.receiver, receiverType);
+
+    ObjectAccessTarget readTarget = node.getter != null
+        ? new ExtensionAccessTarget(
+            node.getter, null, ProcedureKind.Operator, extensionTypeArguments)
+        : const ObjectAccessTarget.missing();
+
+    DartType readType = inferrer.getReturnType(readTarget, receiverType);
+    DartType readIndexType = inferrer.getIndexKeyType(readTarget, receiverType);
+
+    Member equalsMember = inferrer
+        .findInterfaceMember(readType, equalsName, node.testOffset)
+        .member;
+
+    ObjectAccessTarget writeTarget = node.setter != null
+        ? new ExtensionAccessTarget(
+            node.setter, null, ProcedureKind.Operator, extensionTypeArguments)
+        : const ObjectAccessTarget.missing();
+
+    DartType writeIndexType =
+        inferrer.getIndexKeyType(writeTarget, receiverType);
+    DartType valueType =
+        inferrer.getIndexSetValueType(writeTarget, receiverType);
+
+    ExpressionInferenceResult indexResult = inferrer
+        .inferExpression(node.index, readIndexType, true, isVoidAllowed: true);
+
+    VariableDeclaration indexVariable =
+        createVariable(node.index, indexResult.inferredType);
+
+    VariableGet readIndex = createVariableGet(indexVariable);
+    inferrer.ensureAssignable(readIndexType, indexResult.inferredType,
+        readIndex, readIndex.fileOffset);
+
+    VariableGet writeIndex = createVariableGet(indexVariable);
+    inferrer.ensureAssignable(writeIndexType, indexResult.inferredType,
+        writeIndex, writeIndex.fileOffset);
+
+    ExpressionInferenceResult valueResult = inferrer
+        .inferExpression(node.value, valueType, true, isVoidAllowed: true);
+    inferrer.ensureAssignable(
+        valueType, valueResult.inferredType, node.value, node.value.fileOffset);
+
+    DartType inferredType = inferrer.typeSchemaEnvironment
+        .getStandardUpperBound(readType, valueResult.inferredType);
+
+    Expression read;
+
+    if (readTarget.isMissing) {
+      read = inferrer.helper.buildProblem(
+          templateUndefinedMethod.withArguments(
+              indexGetName.name, receiverType),
+          node.readOffset,
+          noLength);
+    } else {
+      assert(readTarget.isExtensionMember);
+      read = new StaticInvocation(
+          readTarget.member,
+          new Arguments(<Expression>[
+            createVariableGet(receiverVariable),
+            readIndex,
+          ], types: readTarget.inferredExtensionTypeArguments)
+            ..fileOffset = node.readOffset)
+        ..fileOffset = node.readOffset;
+    }
+
+    VariableDeclaration valueVariable;
+    Expression valueExpression;
+    if (node.forEffect) {
+      valueExpression = node.value;
+    } else {
+      valueVariable = createVariable(node.value, valueResult.inferredType);
+      valueExpression = createVariableGet(valueVariable);
+    }
+
+    Expression write;
+
+    if (writeTarget.isMissing) {
+      write = inferrer.helper.buildProblem(
+          templateUndefinedMethod.withArguments(
+              indexSetName.name, receiverType),
+          node.writeOffset,
+          noLength);
+    } else {
+      assert(writeTarget.isExtensionMember);
+      write = new StaticInvocation(
+          writeTarget.member,
+          new Arguments(<Expression>[
+            createVariableGet(receiverVariable),
+            writeIndex,
+            valueExpression
+          ], types: writeTarget.inferredExtensionTypeArguments)
+            ..fileOffset = node.writeOffset)
+        ..fileOffset = node.writeOffset;
+    }
+
+    Expression inner;
+    if (node.forEffect) {
+      // Encode `Extension(o)[a] ??= b` as:
+      //
+      //     let receiverVariable = o;
+      //     let indexVariable = a in
+      //        receiverVariable[indexVariable] == null
+      //          ? receiverVariable.[]=(indexVariable, b) : null
+      //
+      MethodInvocation equalsNull =
+          createEqualsNull(node.testOffset, read, equalsMember);
+      ConditionalExpression conditional = new ConditionalExpression(equalsNull,
+          write, new NullLiteral()..fileOffset = node.testOffset, inferredType)
+        ..fileOffset = node.testOffset;
+      inner = createLet(indexVariable, conditional);
+    } else {
+      // Encode `Extension(o)[a] ??= b` as:
+      //
+      //     let receiverVariable = o;
+      //     let indexVariable = a in
+      //     let readVariable = receiverVariable[indexVariable] in
+      //       readVariable == null
+      //        ? (let valueVariable = b in
+      //           let writeVariable =
+      //               receiverVariable.[]=(indexVariable, valueVariable) in
+      //           valueVariable)
+      //        : readVariable
+      //
+      assert(valueVariable != null);
+
+      VariableDeclaration readVariable = createVariable(read, readType);
+      MethodInvocation equalsNull = createEqualsNull(
+          node.testOffset, createVariableGet(readVariable), equalsMember);
+      VariableDeclaration writeVariable =
+          createVariable(write, const VoidType());
+      ConditionalExpression conditional = new ConditionalExpression(
+          equalsNull,
+          createLet(valueVariable,
+              createLet(writeVariable, createVariableGet(valueVariable))),
+          createVariableGet(readVariable),
+          inferredType)
+        ..fileOffset = node.fileOffset;
+      inner = createLet(indexVariable, createLet(readVariable, conditional));
+    }
+
+    Expression replacement = new Let(receiverVariable, inner)
+      ..fileOffset = node.fileOffset;
+
+    node.replaceWith(replacement);
+    return new ExpressionInferenceResult(inferredType, replacement);
+  }
+
   ExpressionInferenceResult visitCompoundIndexSet(
       CompoundIndexSet node, DartType typeContext) {
     ExpressionInferenceResult receiverResult = inferrer.inferExpression(
@@ -3368,6 +3656,247 @@
         node.forPostIncDec ? readType : binaryType, replacement);
   }
 
+  ExpressionInferenceResult visitCompoundExtensionIndexSet(
+      CompoundExtensionIndexSet node, DartType typeContext) {
+    ExpressionInferenceResult receiverResult = inferrer.inferExpression(
+        node.receiver, const UnknownType(), true,
+        isVoidAllowed: false);
+
+    List<DartType> extensionTypeArguments =
+        inferrer.computeExtensionTypeArgument(node.extension,
+            node.explicitTypeArguments, receiverResult.inferredType);
+
+    ObjectAccessTarget readTarget = node.getter != null
+        ? new ExtensionAccessTarget(
+            node.getter, null, ProcedureKind.Operator, extensionTypeArguments)
+        : const ObjectAccessTarget.missing();
+
+    DartType receiverType = inferrer.getPositionalParameterTypeForTarget(
+        readTarget, receiverResult.inferredType, 0);
+
+    inferrer.ensureAssignable(receiverType, receiverResult.inferredType,
+        node.receiver, node.receiver.fileOffset);
+
+    VariableDeclaration receiverVariable =
+        createVariable(node.receiver, receiverType);
+
+    DartType readType = inferrer.getReturnType(readTarget, receiverType);
+    DartType readIndexType = inferrer.getPositionalParameterTypeForTarget(
+        readTarget, receiverType, 0);
+
+    ExpressionInferenceResult indexResult = inferrer
+        .inferExpression(node.index, readIndexType, true, isVoidAllowed: true);
+    VariableDeclaration indexVariable =
+        createVariable(node.index, indexResult.inferredType);
+
+    Expression readIndex = createVariableGet(indexVariable);
+    Expression readIndexReplacement = inferrer.ensureAssignable(readIndexType,
+        indexResult.inferredType, readIndex, readIndex.fileOffset);
+    if (readIndexReplacement != null) {
+      readIndex = readIndexReplacement;
+    }
+
+    Expression read;
+    if (readTarget.isMissing) {
+      read = inferrer.helper.buildProblem(
+          templateUndefinedMethod.withArguments(
+              indexGetName.name, receiverType),
+          node.readOffset,
+          noLength);
+    } else {
+      assert(readTarget.isExtensionMember);
+      read = new StaticInvocation(
+          readTarget.member,
+          new Arguments(<Expression>[
+            createVariableGet(receiverVariable),
+            readIndex,
+          ], types: readTarget.inferredExtensionTypeArguments)
+            ..fileOffset = node.readOffset)
+        ..fileOffset = node.readOffset;
+    }
+
+    VariableDeclaration leftVariable;
+    Expression left;
+    if (node.forEffect) {
+      left = read;
+    } else if (node.forPostIncDec) {
+      leftVariable = createVariable(read, readType);
+      left = createVariableGet(leftVariable);
+    } else {
+      left = read;
+    }
+
+    ObjectAccessTarget binaryTarget = inferrer.findInterfaceMember(
+        readType, node.binaryName, node.binaryOffset,
+        includeExtensionMethods: true);
+
+    MethodContravarianceCheckKind binaryCheckKind =
+        inferrer.preCheckInvocationContravariance(readType, binaryTarget,
+            isThisReceiver: false);
+
+    DartType binaryType = inferrer.getReturnType(binaryTarget, readType);
+    DartType rhsType =
+        inferrer.getPositionalParameterTypeForTarget(binaryTarget, readType, 0);
+
+    ExpressionInferenceResult rhsResult =
+        inferrer.inferExpression(node.rhs, rhsType, true, isVoidAllowed: true);
+    inferrer.ensureAssignable(
+        rhsType, rhsResult.inferredType, node.rhs, node.rhs.fileOffset);
+
+    if (inferrer.isOverloadedArithmeticOperatorAndType(
+        binaryTarget, readType)) {
+      binaryType = inferrer.typeSchemaEnvironment
+          .getTypeOfOverloadedArithmetic(readType, rhsResult.inferredType);
+    }
+
+    Expression binary;
+    if (binaryTarget.isMissing) {
+      binary = inferrer.helper.buildProblem(
+          templateUndefinedMethod.withArguments(node.binaryName.name, readType),
+          node.binaryOffset,
+          node.binaryName.name.length);
+    } else if (binaryTarget.isExtensionMember) {
+      binary = new StaticInvocation(
+          binaryTarget.member,
+          new Arguments(<Expression>[
+            left,
+            node.rhs,
+          ], types: binaryTarget.inferredExtensionTypeArguments)
+            ..fileOffset = node.binaryOffset)
+        ..fileOffset = node.binaryOffset;
+    } else {
+      binary = new MethodInvocation(
+          left,
+          node.binaryName,
+          new Arguments(<Expression>[
+            node.rhs,
+          ])
+            ..fileOffset = node.binaryOffset,
+          binaryTarget.member)
+        ..fileOffset = node.binaryOffset;
+
+      if (binaryCheckKind == MethodContravarianceCheckKind.checkMethodReturn) {
+        if (inferrer.instrumentation != null) {
+          inferrer.instrumentation.record(inferrer.uri, node.binaryOffset,
+              'checkReturn', new InstrumentationValueForType(readType));
+        }
+        binary = new AsExpression(binary, binaryType)
+          ..isTypeError = true
+          ..fileOffset = node.binaryOffset;
+      }
+    }
+
+    ObjectAccessTarget writeTarget = node.setter != null
+        ? new ExtensionAccessTarget(
+            node.setter, null, ProcedureKind.Operator, extensionTypeArguments)
+        : const ObjectAccessTarget.missing();
+
+    DartType writeIndexType = inferrer.getPositionalParameterTypeForTarget(
+        writeTarget, receiverType, 0);
+    Expression writeIndex = createVariableGet(indexVariable);
+    Expression writeIndexReplacement = inferrer.ensureAssignable(writeIndexType,
+        indexResult.inferredType, writeIndex, writeIndex.fileOffset);
+    if (writeIndexReplacement != null) {
+      writeIndex = writeIndexReplacement;
+    }
+
+    DartType valueType =
+        inferrer.getIndexSetValueType(writeTarget, inferrer.thisType);
+    Expression binaryReplacement = inferrer.ensureAssignable(
+        valueType, binaryType, binary, node.fileOffset);
+    if (binaryReplacement != null) {
+      binary = binaryReplacement;
+    }
+
+    VariableDeclaration valueVariable;
+    Expression valueExpression;
+    if (node.forEffect || node.forPostIncDec) {
+      valueExpression = binary;
+    } else {
+      valueVariable = createVariable(binary, binaryType);
+      valueExpression = createVariableGet(valueVariable);
+    }
+
+    Expression write;
+
+    if (writeTarget.isMissing) {
+      write = inferrer.helper.buildProblem(
+          templateUndefinedMethod.withArguments(
+              indexSetName.name, receiverType),
+          node.writeOffset,
+          noLength);
+    } else {
+      assert(writeTarget.isExtensionMember);
+      write = new StaticInvocation(
+          writeTarget.member,
+          new Arguments(<Expression>[
+            createVariableGet(receiverVariable),
+            writeIndex,
+            valueExpression
+          ], types: writeTarget.inferredExtensionTypeArguments)
+            ..fileOffset = node.writeOffset)
+        ..fileOffset = node.writeOffset;
+    }
+
+    Expression inner;
+    if (node.forEffect) {
+      assert(leftVariable == null);
+      assert(valueVariable == null);
+      // Encode `Extension(o)[a] += b` as:
+      //
+      //     let receiverVariable = o in
+      //     let indexVariable = a in
+      //         receiverVariable.[]=(receiverVariable, o.[](indexVariable) + b)
+      //
+      inner = createLet(indexVariable, write);
+    } else if (node.forPostIncDec) {
+      // Encode `Extension(o)[a]++` as:
+      //
+      //     let receiverVariable = o in
+      //     let indexVariable = a in
+      //     let leftVariable = receiverVariable.[](indexVariable)
+      //     let writeVariable =
+      //       receiverVariable.[]=(indexVariable, leftVariable + 1) in
+      //         leftVariable
+      //
+      assert(leftVariable != null);
+      assert(valueVariable == null);
+
+      VariableDeclaration writeVariable =
+          createVariable(write, const VoidType());
+      inner = createLet(
+          indexVariable,
+          createLet(leftVariable,
+              createLet(writeVariable, createVariableGet(leftVariable))));
+    } else {
+      // Encode `Extension(o)[a] += b` as:
+      //
+      //     let receiverVariable = o in
+      //     let indexVariable = a in
+      //     let valueVariable = receiverVariable.[](indexVariable) + b
+      //     let writeVariable =
+      //       receiverVariable.[]=(indexVariable, valueVariable) in
+      //         valueVariable
+      //
+      assert(leftVariable == null);
+      assert(valueVariable != null);
+
+      VariableDeclaration writeVariable =
+          createVariable(write, const VoidType());
+      inner = createLet(
+          indexVariable,
+          createLet(valueVariable,
+              createLet(writeVariable, createVariableGet(valueVariable))));
+    }
+
+    Expression replacement = new Let(receiverVariable, inner)
+      ..fileOffset = node.fileOffset;
+
+    node.replaceWith(replacement);
+    return new ExpressionInferenceResult(
+        node.forPostIncDec ? readType : binaryType, replacement);
+  }
+
   @override
   ExpressionInferenceResult visitNullLiteral(
       NullLiteral node, DartType typeContext) {
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart
index 294aa54..627fbc5 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart
@@ -184,12 +184,16 @@
 
 enum InternalExpressionKind {
   Cascade,
+  CompoundExtensionIndexSet,
   CompoundIndexSet,
   CompoundPropertySet,
   CompoundSuperIndexSet,
   DeferredCheck,
+  ExtensionIndexSet,
+  ExtensionTearOff,
   ExtensionSet,
   IfNull,
+  IfNullExtensionIndexSet,
   IfNullIndexSet,
   IfNullPropertySet,
   IfNullSet,
@@ -1601,6 +1605,77 @@
   }
 }
 
+/// Internal expression representing an extension index set expression.
+///
+/// An extension index set expression of the form `Extension(o)[a] = b` used
+/// for value is encoded as the expression:
+///
+///     let receiverVariable = o
+///     let indexVariable = a in
+///     let valueVariable = b in '
+///     let writeVariable =
+///         receiverVariable.[]=(indexVariable, valueVariable) in
+///           valueVariable
+///
+/// An extension index set expression used for effect is encoded as
+///
+///    o.[]=(a, b)
+///
+/// using [StaticInvocation].
+///
+class ExtensionIndexSet extends InternalExpression {
+  final Extension extension;
+
+  final List<DartType> explicitTypeArguments;
+
+  /// The receiver of the extension access.
+  Expression receiver;
+
+  /// The []= member.
+  Member setter;
+
+  /// The index expression of the operation.
+  Expression index;
+
+  /// The value expression of the operation.
+  Expression value;
+
+  ExtensionIndexSet(this.extension, this.explicitTypeArguments, this.receiver,
+      this.setter, this.index, this.value)
+      : assert(explicitTypeArguments == null ||
+            explicitTypeArguments.length == extension.typeParameters.length) {
+    receiver?.parent = this;
+    index?.parent = this;
+    value?.parent = this;
+  }
+
+  @override
+  InternalExpressionKind get kind => InternalExpressionKind.ExtensionIndexSet;
+
+  @override
+  void visitChildren(Visitor<dynamic> v) {
+    receiver?.accept(v);
+    index?.accept(v);
+    value?.accept(v);
+  }
+
+  @override
+  void transformChildren(Transformer v) {
+    if (receiver != null) {
+      receiver = receiver.accept<TreeNode>(v);
+      receiver?.parent = this;
+    }
+    if (index != null) {
+      index = index.accept<TreeNode>(v);
+      index?.parent = this;
+    }
+    if (value != null) {
+      value = value.accept<TreeNode>(v);
+      value?.parent = this;
+    }
+  }
+}
+
 /// Internal expression representing an if-null index assignment.
 ///
 /// An if-null index assignment of the form `o[a] ??= b` is, if used for value,
@@ -1768,6 +1843,99 @@
   }
 }
 
+/// Internal expression representing an if-null super index set expression.
+///
+/// An if-null super index set expression of the form `super[a] ??= b` is, if
+/// used for value, encoded as the expression:
+///
+///     let v1 = a in
+///     let v2 = super.[](v1) in
+///       v2 == null
+///        ? (let v3 = b in
+///           let _ = super.[]=(v1, v3) in
+///           v3)
+///        : v2
+///
+/// and, if used for effect, encoded as the expression:
+///
+///     let v1 = a in
+///     let v2 = super.[](v1) in
+///        v2 == null ? super.[]=(v1, b) : null
+///
+class IfNullExtensionIndexSet extends InternalExpression {
+  final Extension extension;
+
+  final List<DartType> explicitTypeArguments;
+
+  /// The extension receiver;
+  Expression receiver;
+
+  /// The [] member;
+  Member getter;
+
+  /// The []= member;
+  Member setter;
+
+  /// The index expression of the operation.
+  Expression index;
+
+  /// The value expression of the operation.
+  Expression value;
+
+  /// The file offset for the [] operation.
+  final int readOffset;
+
+  /// The file offset for the == operation.
+  final int testOffset;
+
+  /// The file offset for the []= operation.
+  final int writeOffset;
+
+  /// If `true`, the expression is only need for effect and not for its value.
+  final bool forEffect;
+
+  IfNullExtensionIndexSet(this.extension, this.explicitTypeArguments,
+      this.receiver, this.getter, this.setter, this.index, this.value,
+      {this.readOffset, this.testOffset, this.writeOffset, this.forEffect})
+      : assert(explicitTypeArguments == null ||
+            explicitTypeArguments.length == extension.typeParameters.length),
+        assert(readOffset != null),
+        assert(testOffset != null),
+        assert(writeOffset != null),
+        assert(forEffect != null) {
+    receiver?.parent = this;
+    index?.parent = this;
+    value?.parent = this;
+  }
+
+  @override
+  InternalExpressionKind get kind =>
+      InternalExpressionKind.IfNullExtensionIndexSet;
+
+  @override
+  void visitChildren(Visitor<dynamic> v) {
+    receiver?.accept(v);
+    index?.accept(v);
+    value?.accept(v);
+  }
+
+  @override
+  void transformChildren(Transformer v) {
+    if (receiver != null) {
+      receiver = receiver.accept<TreeNode>(v);
+      receiver?.parent = this;
+    }
+    if (index != null) {
+      index = index.accept<TreeNode>(v);
+      index?.parent = this;
+    }
+    if (value != null) {
+      value = value.accept<TreeNode>(v);
+      value?.parent = this;
+    }
+  }
+}
+
 /// Internal expression representing a compound index assignment.
 ///
 /// An if-null index assignment of the form `o[a] += b` is, if used for value,
@@ -2112,6 +2280,117 @@
   }
 }
 
+/// Internal expression representing a compound extension index assignment.
+///
+/// An compound extension index assignment of the form `Extension(o)[a] += b`
+/// is, if used for value, encoded as the expression:
+///
+///     let receiverVariable = o;
+///     let indexVariable = a in
+///     let valueVariable = receiverVariable.[](indexVariable) + b
+///     let writeVariable =
+///       receiverVariable.[]=(indexVariable, valueVariable) in
+///         valueVariable
+///
+/// and, if used for effect, encoded as the expression:
+///
+///     let receiverVariable = o;
+///     let indexVariable = a in
+///         receiverVariable.[]=(indexVariable,
+///             receiverVariable.[](indexVariable) + b)
+///
+class CompoundExtensionIndexSet extends InternalExpression {
+  final Extension extension;
+
+  final List<DartType> explicitTypeArguments;
+
+  Expression receiver;
+
+  /// The [] member.
+  Member getter;
+
+  /// The []= member.
+  Member setter;
+
+  /// The index expression of the operation.
+  Expression index;
+
+  /// The name of the binary operation.
+  Name binaryName;
+
+  /// The right-hand side of the binary expression.
+  Expression rhs;
+
+  /// The file offset for the [] operation.
+  final int readOffset;
+
+  /// The file offset for the []= operation.
+  final int writeOffset;
+
+  /// The file offset for the binary operation.
+  final int binaryOffset;
+
+  /// If `true`, the expression is only need for effect and not for its value.
+  final bool forEffect;
+
+  /// If `true`, the expression is a post-fix inc/dec expression.
+  final bool forPostIncDec;
+
+  CompoundExtensionIndexSet(
+      this.extension,
+      this.explicitTypeArguments,
+      this.receiver,
+      this.getter,
+      this.setter,
+      this.index,
+      this.binaryName,
+      this.rhs,
+      {this.readOffset,
+      this.binaryOffset,
+      this.writeOffset,
+      this.forEffect,
+      this.forPostIncDec})
+      : assert(explicitTypeArguments == null ||
+            explicitTypeArguments.length == extension.typeParameters.length),
+        assert(readOffset != null),
+        assert(binaryOffset != null),
+        assert(writeOffset != null),
+        assert(forEffect != null),
+        assert(forPostIncDec != null) {
+    receiver?.parent = this;
+    index?.parent = this;
+    rhs?.parent = this;
+    fileOffset = binaryOffset;
+  }
+
+  @override
+  InternalExpressionKind get kind =>
+      InternalExpressionKind.CompoundExtensionIndexSet;
+
+  @override
+  void visitChildren(Visitor<dynamic> v) {
+    receiver?.accept(v);
+    index?.accept(v);
+    rhs?.accept(v);
+  }
+
+  @override
+  void transformChildren(Transformer v) {
+    if (receiver != null) {
+      receiver = receiver.accept<TreeNode>(v);
+      receiver?.parent = this;
+    }
+    if (index != null) {
+      index = index.accept<TreeNode>(v);
+      index?.parent = this;
+    }
+    if (rhs != null) {
+      rhs = rhs.accept<TreeNode>(v);
+      rhs?.parent = this;
+    }
+  }
+}
+
 /// Internal expression representing an assignment to an extension setter.
 ///
 /// An extension set of the form `receiver.target = value` is, if used for
@@ -2134,11 +2413,15 @@
 ///
 // TODO(johnniwinther): Rename read-only to side-effect-free.
 class ExtensionSet extends InternalExpression {
+  final Extension extension;
+
+  final List<DartType> explicitTypeArguments;
+
   /// The receiver for the assignment.
   Expression receiver;
 
   /// The extension member called for the assignment.
-  ObjectAccessTarget target;
+  Member target;
 
   /// The right-hand side value of the assignment.
   Expression value;
@@ -2151,9 +2434,12 @@
   /// variable.
   final bool readOnlyReceiver;
 
-  ExtensionSet(this.receiver, this.target, this.value,
+  ExtensionSet(this.extension, this.explicitTypeArguments, this.receiver,
+      this.target, this.value,
       {this.readOnlyReceiver, this.forEffect})
-      : assert(readOnlyReceiver != null),
+      : assert(explicitTypeArguments == null ||
+            explicitTypeArguments.length == extension.typeParameters.length),
+        assert(readOnlyReceiver != null),
         assert(forEffect != null) {
     receiver?.parent = this;
     value?.parent = this;
@@ -2221,6 +2507,7 @@
   }
 }
 
+/// Front end specific implementation of [PropertySet].
 class PropertySetImpl extends PropertySet {
   /// If `true` the assignment is need for its effect and not for its value.
   final bool forEffect;
@@ -2235,6 +2522,46 @@
         super(receiver, name, value, interfaceTarget);
 }
 
+/// Internal representation of a read of an extension instance member.
+///
+/// A read of an extension instance member `o.foo` is encoded as the
+/// [StaticInvocation]
+///
+///     extension|foo(o)
+///
+/// where `extension|foo` is the top level method created for reading the
+/// `foo` member. If `foo` is an extension instance method, then `extension|foo`
+/// the special tear-off function created for extension instance methods.
+/// Otherwise `extension|foo` is the top level method corresponding to the
+/// extension instance getter being read.
+class ExtensionTearOff extends InternalExpression {
+  /// The top-level method that is that target for the read operation.
+  Member target;
+
+  /// The arguments provided to the top-level method.
+  Arguments arguments;
+
+  ExtensionTearOff(this.target, this.arguments) {
+    arguments?.parent = this;
+  }
+
+  @override
+  InternalExpressionKind get kind => InternalExpressionKind.ExtensionTearOff;
+
+  @override
+  void visitChildren(Visitor<dynamic> v) {
+    arguments?.accept(v);
+  }
+
+  @override
+  void transformChildren(Transformer v) {
+    if (arguments != null) {
+      arguments = arguments.accept<TreeNode>(v);
+      arguments?.parent = this;
+    }
+  }
+}
+
 /// Creates a [Let] of [variable] with the given [body] using
 /// `variable.fileOffset` as the file offset for the let.
 ///
diff --git a/pkg/front_end/lib/src/fasta/parser/forwarding_listener.dart b/pkg/front_end/lib/src/fasta/parser/forwarding_listener.dart
index af3ed3b..f5e9320 100644
--- a/pkg/front_end/lib/src/fasta/parser/forwarding_listener.dart
+++ b/pkg/front_end/lib/src/fasta/parser/forwarding_listener.dart
@@ -993,8 +993,9 @@
   }
 
   @override
-  void endTypeVariable(Token token, int index, Token extendsOrSuper) {
-    listener?.endTypeVariable(token, index, extendsOrSuper);
+  void endTypeVariable(
+      Token token, int index, Token extendsOrSuper, Token variance) {
+    listener?.endTypeVariable(token, index, extendsOrSuper, variance);
   }
 
   @override
diff --git a/pkg/front_end/lib/src/fasta/parser/listener.dart b/pkg/front_end/lib/src/fasta/parser/listener.dart
index 9c67ac4..e5f5fad 100644
--- a/pkg/front_end/lib/src/fasta/parser/listener.dart
+++ b/pkg/front_end/lib/src/fasta/parser/listener.dart
@@ -1220,7 +1220,8 @@
   /// - Type bound
   ///
   /// See [beginTypeVariable] for additional substructures.
-  void endTypeVariable(Token token, int index, Token extendsOrSuper) {
+  void endTypeVariable(
+      Token token, int index, Token extendsOrSuper, Token variance) {
     logEvent("TypeVariable");
   }
 
diff --git a/pkg/front_end/lib/src/fasta/parser/parser.dart b/pkg/front_end/lib/src/fasta/parser/parser.dart
index e139297..f2753bd 100644
--- a/pkg/front_end/lib/src/fasta/parser/parser.dart
+++ b/pkg/front_end/lib/src/fasta/parser/parser.dart
@@ -5141,14 +5141,6 @@
 
   Token parseSend(Token token, IdentifierContext context) {
     Token beginToken = token = ensureIdentifier(token, context);
-    if (optional('!', token.next)) {
-      Token bang = token.next;
-      Token next = bang.next;
-      if (optional('(', next) || optional('[', next)) {
-        listener.handleNonNullAssertExpression(bang);
-        token = bang;
-      }
-    }
     TypeParamOrArgInfo typeArg = computeMethodTypeArguments(token);
     if (typeArg != noTypeParamOrArg) {
       token = typeArg.parseArguments(token, this);
diff --git a/pkg/front_end/lib/src/fasta/parser/type_info_impl.dart b/pkg/front_end/lib/src/fasta/parser/type_info_impl.dart
index 2a16412..de9c32d 100644
--- a/pkg/front_end/lib/src/fasta/parser/type_info_impl.dart
+++ b/pkg/front_end/lib/src/fasta/parser/type_info_impl.dart
@@ -763,7 +763,7 @@
     listener.beginTypeVariable(token);
     listener.handleTypeVariablesDefined(token, 1);
     listener.handleNoType(token);
-    listener.endTypeVariable(endGroup, 0, null);
+    listener.endTypeVariable(endGroup, 0, null, null);
     listener.endTypeVariables(beginGroup, endGroup);
     return endGroup;
   }
@@ -1075,7 +1075,7 @@
       // Type variables are "completed" in reverse order, so capture the last
       // consumed token from the first "completed" type variable.
       token ??= token2;
-      listener.endTypeVariable(next2, --count, extendsOrSuper);
+      listener.endTypeVariable(next2, --count, extendsOrSuper, variance);
 
       typeStarts = typeStarts.tail;
       superTypeInfos = superTypeInfos.tail;
diff --git a/pkg/front_end/lib/src/fasta/source/diet_listener.dart b/pkg/front_end/lib/src/fasta/source/diet_listener.dart
index 400fba9..10bb91e 100644
--- a/pkg/front_end/lib/src/fasta/source/diet_listener.dart
+++ b/pkg/front_end/lib/src/fasta/source/diet_listener.dart
@@ -544,7 +544,8 @@
   }
 
   @override
-  void endTypeVariable(Token token, int index, Token extendsOrSuper) {
+  void endTypeVariable(
+      Token token, int index, Token extendsOrSuper, Token variance) {
     debugEvent("endTypeVariable");
   }
 
@@ -586,6 +587,28 @@
   }
 
   @override
+  void endExtensionFactoryMethod(
+      Token beginToken, Token factoryKeyword, Token endToken) {
+    debugEvent("ExtensionFactoryMethod");
+    pop(); // bodyToken
+    pop(); // name
+    pop(); // metadata
+    checkEmpty(beginToken.charOffset);
+    // Skip the declaration. An error as already been produced by the parser.
+  }
+
+  @override
+  void endExtensionConstructor(Token getOrSet, Token beginToken,
+      Token beginParam, Token beginInitializers, Token endToken) {
+    debugEvent("ExtensionConstructor");
+    pop(); // bodyToken
+    pop(); // name
+    pop(); // metadata
+    checkEmpty(beginToken.charOffset);
+    // Skip the declaration. An error as already been produced by the parser.
+  }
+
+  @override
   void endRedirectingFactoryBody(Token beginToken, Token endToken) {
     debugEvent("RedirectingFactoryBody");
     discard(1); // ConstructorReference.
diff --git a/pkg/front_end/lib/src/fasta/source/outline_builder.dart b/pkg/front_end/lib/src/fasta/source/outline_builder.dart
index 77ca872..0377599 100644
--- a/pkg/front_end/lib/src/fasta/source/outline_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/outline_builder.dart
@@ -4,7 +4,7 @@
 
 library fasta.outline_builder;
 
-import 'package:kernel/ast.dart' show ProcedureKind;
+import 'package:kernel/ast.dart' show ProcedureKind, Variance;
 
 import '../builder/builder.dart';
 
@@ -1574,13 +1574,17 @@
   }
 
   @override
-  void endTypeVariable(Token token, int index, Token extendsOrSuper) {
+  void endTypeVariable(
+      Token token, int index, Token extendsOrSuper, Token variance) {
     debugEvent("endTypeVariable");
     TypeBuilder bound = nullIfParserRecovery(pop());
     // Peek to leave type parameters on top of stack.
     List<TypeVariableBuilder> typeParameters = peek();
     if (typeParameters != null) {
       typeParameters[index].bound = bound;
+      if (variance != null) {
+        typeParameters[index].variance = Variance.fromString(variance.lexeme);
+      }
     }
   }
 
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 811db64..c1fcc30 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
@@ -2775,6 +2775,9 @@
   void checkBoundsInStaticInvocation(
       StaticInvocation node, TypeEnvironment typeEnvironment, Uri fileUri,
       {bool inferred = false}) {
+    // TODO(johnniwinther): Handle partially inferred type arguments in
+    // extension method calls. Currently all are considered inferred in the
+    // error messages.
     if (node.arguments.types.isEmpty) return;
     Class klass = node.target.enclosingClass;
     List<TypeParameter> parameters = node.target.function.typeParameters;
diff --git a/pkg/front_end/lib/src/fasta/source/type_promotion_look_ahead_listener.dart b/pkg/front_end/lib/src/fasta/source/type_promotion_look_ahead_listener.dart
index 8a1c08d..67cdaec 100644
--- a/pkg/front_end/lib/src/fasta/source/type_promotion_look_ahead_listener.dart
+++ b/pkg/front_end/lib/src/fasta/source/type_promotion_look_ahead_listener.dart
@@ -1316,7 +1316,8 @@
   }
 
   @override
-  void endTypeVariable(Token token, int index, Token extendsOrSuper) {
+  void endTypeVariable(
+      Token token, int index, Token extendsOrSuper, Token variance) {
     debugEvent("TypeVariable", token);
     state.pop(); // Name.
   }
@@ -1327,6 +1328,11 @@
   }
 
   @override
+  void handleVarianceModifier(Token variance) {
+    debugEvent("VarianceModifier", variance);
+  }
+
+  @override
   void handleNoTypeVariables(Token token) {
     debugEvent("NoTypeVariables", token);
   }
diff --git a/pkg/front_end/lib/src/fasta/source/value_kinds.dart b/pkg/front_end/lib/src/fasta/source/value_kinds.dart
index 08ecbf0..2047483 100644
--- a/pkg/front_end/lib/src/fasta/source/value_kinds.dart
+++ b/pkg/front_end/lib/src/fasta/source/value_kinds.dart
@@ -47,6 +47,8 @@
       const _SingleValueKind<List<type.FormalParameterBuilder>>(
           NullValue.FormalParameters);
   static const ValueKind Generator = const _SingleValueKind<type.Generator>();
+  static const ValueKind Initializer =
+      const _SingleValueKind<type.Initializer>();
   static const ValueKind MethodBody = const _SingleValueKind<type.MethodBody>();
   static const ValueKind Modifiers =
       const _SingleValueKind<List<type.Modifier>>();
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
index 4717c77..faf4afd 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
@@ -66,7 +66,7 @@
 
 import '../kernel/type_algorithms.dart' show hasAnyTypeVariables;
 
-import '../names.dart' show callName, unaryMinusName;
+import '../names.dart';
 
 import '../problems.dart' show unexpected, unhandled;
 
@@ -656,10 +656,29 @@
     return type is InterfaceType && type.classNode == coreTypes.nullClass;
   }
 
-  List<DartType> _inferExtensionTypeArguments(
-      List<TypeParameter> typeParameters,
-      DartType onType,
-      DartType receiverType) {
+  /// Computes the type arguments for an access to an extension instance member
+  /// on [extension] with the static [receiverType]. If [explicitTypeArguments]
+  /// are provided, these are returned, otherwise type arguments are inferred
+  /// using [receiverType].
+  List<DartType> computeExtensionTypeArgument(Extension extension,
+      List<DartType> explicitTypeArguments, DartType receiverType) {
+    if (explicitTypeArguments != null) {
+      assert(explicitTypeArguments.length == extension.typeParameters.length);
+      return explicitTypeArguments;
+    } else if (extension.typeParameters.isEmpty) {
+      assert(explicitTypeArguments == null);
+      return const <DartType>[];
+    } else {
+      return inferExtensionTypeArguments(extension, receiverType);
+    }
+  }
+
+  /// Infers the type arguments for an access to an extension instance member
+  /// on [extension] with the static [receiverType].
+  List<DartType> inferExtensionTypeArguments(
+      Extension extension, DartType receiverType) {
+    List<TypeParameter> typeParameters = extension.typeParameters;
+    DartType onType = extension.onType;
     List<DartType> inferredTypes =
         new List<DartType>.filled(typeParameters.length, const UnknownType());
     typeSchemaEnvironment.inferGenericFunctionOrType(
@@ -719,8 +738,23 @@
     if (target.isUnresolved &&
         receiverType is! DynamicType &&
         includeExtensionMethods) {
+      Name otherName = name;
+      bool otherIsSetter;
+      if (name == indexGetName) {
+        // [] must be checked against []=.
+        otherName = indexSetName;
+        otherIsSetter = false;
+      } else if (name == indexSetName) {
+        // []= must be checked against [].
+        otherName = indexGetName;
+        otherIsSetter = false;
+      } else {
+        otherName = name;
+        otherIsSetter = !setter;
+      }
+
       Member otherMember =
-          _getInterfaceMember(classNode, name, !setter, fileOffset);
+          _getInterfaceMember(classNode, otherName, otherIsSetter, fileOffset);
       if (otherMember != null) {
         // If we're looking for `foo` and `foo=` can be found or vice-versa then
         // extension methods should not be found.
@@ -730,12 +764,12 @@
       ExtensionAccessCandidate bestSoFar;
       List<ExtensionAccessCandidate> noneMoreSpecific = [];
       library.scope.forEachExtension((ExtensionBuilder extensionBuilder) {
-        MemberBuilder getterBuilder =
-            extensionBuilder.lookupLocalMember(name.name, setter: false);
-        MemberBuilder setterBuilder =
-            extensionBuilder.lookupLocalMember(name.name, setter: true);
-        if ((getterBuilder != null && !getterBuilder.isStatic) ||
-            (setterBuilder != null && !setterBuilder.isStatic)) {
+        MemberBuilder thisBuilder =
+            extensionBuilder.lookupLocalMember(name.name, setter: setter);
+        MemberBuilder otherBuilder = extensionBuilder
+            .lookupLocalMember(otherName.name, setter: otherIsSetter);
+        if ((thisBuilder != null && !thisBuilder.isStatic) ||
+            (otherBuilder != null && !otherBuilder.isStatic)) {
           DartType onType;
           DartType onTypeInstantiateToBounds;
           List<DartType> inferredTypeArguments;
@@ -746,10 +780,8 @@
           } else {
             List<TypeParameter> typeParameters =
                 extensionBuilder.extension.typeParameters;
-            inferredTypeArguments = _inferExtensionTypeArguments(
-                extensionBuilder.extension.typeParameters,
-                extensionBuilder.extension.onType,
-                receiverType);
+            inferredTypeArguments = inferExtensionTypeArguments(
+                extensionBuilder.extension, receiverType);
             Substitution inferredSubstitution =
                 Substitution.fromPairs(typeParameters, inferredTypeArguments);
 
@@ -774,17 +806,14 @@
           }
 
           if (typeSchemaEnvironment.isSubtypeOf(receiverType, onType)) {
-            MemberBuilder memberBuilder =
-                setter ? setterBuilder : getterBuilder;
-
             ExtensionAccessCandidate candidate = new ExtensionAccessCandidate(
                 onType,
                 onTypeInstantiateToBounds,
-                memberBuilder != null
+                thisBuilder != null
                     ? new ObjectAccessTarget.extensionMember(
-                        memberBuilder.procedure,
-                        memberBuilder.extensionTearOff,
-                        memberBuilder.kind,
+                        thisBuilder.procedure,
+                        thisBuilder.extensionTearOff,
+                        thisBuilder.kind,
                         inferredTypeArguments)
                     : const ObjectAccessTarget.missing(),
                 isPlatform: extensionBuilder.library.uri.scheme == 'dart');
@@ -1154,6 +1183,19 @@
     throw unhandled('$target', 'getFunctionType', null, null);
   }
 
+  /// Returns the type of the receiver argument in an access to an extension
+  /// member on [extension] with the given extension [typeArguments].
+  DartType getExtensionReceiverType(
+      Extension extension, List<DartType> typeArguments) {
+    DartType receiverType = extension.onType;
+    if (extension.typeParameters.isNotEmpty) {
+      Substitution substitution =
+          Substitution.fromPairs(extension.typeParameters, typeArguments);
+      return substitution.substituteType(receiverType);
+    }
+    return receiverType;
+  }
+
   /// Returns the return type of the invocation of [target] on [receiverType].
   // TODO(johnniwinther): Cleanup [getFunctionType], [getReturnType],
   // [getIndexKeyType] and [getIndexSetValueType]. We shouldn't need that many.
@@ -2121,8 +2163,13 @@
         parent?.replaceChild(node, errorNode);
       }
     }
-    _checkBoundsInMethodInvocation(target, receiverType, calleeType, methodName,
-        arguments, node.fileOffset);
+    if (target.isExtensionMember) {
+      library.checkBoundsInStaticInvocation(
+          replacement, typeSchemaEnvironment, helper.uri);
+    } else {
+      _checkBoundsInMethodInvocation(target, receiverType, calleeType,
+          methodName, arguments, node.fileOffset);
+    }
 
     return new ExpressionInferenceResult(inferredType, replacement);
   }
@@ -2308,6 +2355,8 @@
                       receiver,
                       extensionTypeArguments:
                           readTarget.inferredExtensionTypeArguments)));
+          inferredType =
+              instantiateTearOff(inferredType, typeContext, expression);
           break;
         case ProcedureKind.Setter:
         case ProcedureKind.Factory:
diff --git a/pkg/front_end/messages.status b/pkg/front_end/messages.status
index 3742020..34bb332 100644
--- a/pkg/front_end/messages.status
+++ b/pkg/front_end/messages.status
@@ -98,7 +98,6 @@
 ConstEvalKeyImplementsEqual/example: Fail
 ConstEvalNegativeShift/analyzerCode: Fail # http://dartbug.com/33481
 ConstEvalNegativeShift/example: Fail
-ConstEvalNonConstantLiteral/example: Fail
 ConstEvalNonConstantVariableGet/example: Fail
 ConstEvalNotListOrSetInSpread/example: Fail
 ConstEvalNotMapInSpread/example: Fail
diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml
index 8568a27..2782772 100644
--- a/pkg/front_end/messages.yaml
+++ b/pkg/front_end/messages.yaml
@@ -104,10 +104,6 @@
   template: "The key '#constant' does not have a primitive operator '=='."
   analyzerCode: CONST_MAP_KEY_EXPRESSION_TYPE_IMPLEMENTS_EQUALS
 
-ConstEvalNonConstantLiteral:
-  template: "Can't have a non-constant #string literal within a const context."
-  analyzerCode: NON_CONSTANT_DEFAULT_VALUE
-
 ConstEvalInvalidType:
   template: "Expected constant '#constant' to be of type '#type', but was of type '#type2'."
 
@@ -125,19 +121,21 @@
   template: "Binary operator '#string' on '#string2' requires non-negative operand, but was '#string3'."
 
 ConstEvalInvalidMethodInvocation:
-  template: "The method '#string' can't be invoked on '#constant' within a const context."
+  template: "The method '#string' can't be invoked on '#constant' in a constant expression."
   analyzerCode: UNDEFINED_OPERATOR
 
 ConstEvalInvalidPropertyGet:
-  template: "The property '#string' can't be accessed on '#constant' within a const context."
+  template: "The property '#string' can't be accessed on '#constant' in a constant expression."
   analyzerCode: CONST_EVAL_THROWS_EXCEPTION
 
 ConstEvalInvalidStringInterpolationOperand:
-  template: "The '#constant' can't be used as part of a string interpolation within a const context, only values of type 'null', 'bool', 'int', 'double', or 'String' can be used."
+  template: |
+    The constant value '#constant' can't be used as part of a string interpolation in a constant expression.
+    Only values of type 'null', 'bool', 'int', 'double', or 'String' can be used.
   analyzerCode: CONST_EVAL_TYPE_BOOL_NUM_STRING
 
 ConstEvalInvalidStaticInvocation:
-  template: "The invocation of '#name' is not allowed within a const context."
+  template: "The invocation of '#name' is not allowed in a constant expression."
   analyzerCode: CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
 
 ConstEvalInvalidSymbolName:
@@ -1889,18 +1887,21 @@
   template: "Extensions can't declare abstract members."
   tip: "Try providing an implementation for the member."
   analyzerCode: ParserErrorCode.EXTENSION_DECLARES_ABSTRACT_MEMBER
+  hasPublishedDocs: true
 
 ExtensionDeclaresConstructor:
   index: 92
   template: "Extensions can't declare constructors."
   tip: "Try removing the constructor declaration."
   analyzerCode: ParserErrorCode.EXTENSION_DECLARES_CONSTRUCTOR
+  hasPublishedDocs: true
 
 ExtensionDeclaresInstanceField:
   index: 93
   template: "Extensions can't declare instance fields"
   tip: "Try removing the field declaration or making it a static field"
   analyzerCode: ParserErrorCode.EXTENSION_DECLARES_INSTANCE_FIELD
+  hasPublishedDocs: true
 
 ConflictsWithConstructor:
   template: "Conflicts with constructor '#name'."
diff --git a/pkg/front_end/parser_testcases/nnbd/nullCheckBeforeIndex.dart b/pkg/front_end/parser_testcases/nnbd/nullCheckBeforeIndex.dart
new file mode 100644
index 0000000..63bb3d4
--- /dev/null
+++ b/pkg/front_end/parser_testcases/nnbd/nullCheckBeforeIndex.dart
@@ -0,0 +1 @@
+f() { foo.bar!.baz[arg]; }
\ No newline at end of file
diff --git a/pkg/front_end/parser_testcases/nnbd/nullCheckBeforeIndex.dart.expect b/pkg/front_end/parser_testcases/nnbd/nullCheckBeforeIndex.dart.expect
new file mode 100644
index 0000000..9ddb2a0
--- /dev/null
+++ b/pkg/front_end/parser_testcases/nnbd/nullCheckBeforeIndex.dart.expect
@@ -0,0 +1,37 @@
+beginCompilationUnit(f)
+  beginMetadataStar(f)
+  endMetadataStar(0)
+  beginTopLevelMember(f)
+    beginTopLevelMethod(, null)
+      handleNoType()
+      handleIdentifier(f, topLevelFunctionDeclaration)
+      handleNoTypeVariables(()
+      beginFormalParameters((, MemberKind.TopLevelMethod)
+      endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+      handleAsyncModifier(null, null)
+      beginBlockFunctionBody({)
+        handleIdentifier(foo, expression)
+        handleNoTypeArguments(.)
+        handleNoArguments(.)
+        handleSend(foo, .)
+        handleIdentifier(bar, expressionContinuation)
+        handleNoTypeArguments(!)
+        handleNoArguments(!)
+        handleSend(bar, !)
+      endBinaryExpression(.)
+      handleNonNullAssertExpression(!)
+      handleIdentifier(baz, expressionContinuation)
+      handleNoTypeArguments([)
+      handleNoArguments([)
+      handleSend(baz, [)
+    endBinaryExpression(.)
+    handleIdentifier(arg, expression)
+    handleNoTypeArguments(])
+    handleNoArguments(])
+    handleSend(arg, ])
+    handleIndexedExpression([, ])
+    handleExpressionStatement(;)
+  endBlockFunctionBody(1, {, })
+endTopLevelMethod(f, null, })
+endTopLevelDeclaration()
+endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/nnbd/nullCheckBeforeIndex_with_parens.dart b/pkg/front_end/parser_testcases/nnbd/nullCheckBeforeIndex_with_parens.dart
new file mode 100644
index 0000000..c4c6025
--- /dev/null
+++ b/pkg/front_end/parser_testcases/nnbd/nullCheckBeforeIndex_with_parens.dart
@@ -0,0 +1 @@
+f() { (foo.bar)!.baz[arg]; }
\ No newline at end of file
diff --git a/pkg/front_end/parser_testcases/nnbd/nullCheckBeforeIndex_with_parens.dart.expect b/pkg/front_end/parser_testcases/nnbd/nullCheckBeforeIndex_with_parens.dart.expect
new file mode 100644
index 0000000..d10dfba
--- /dev/null
+++ b/pkg/front_end/parser_testcases/nnbd/nullCheckBeforeIndex_with_parens.dart.expect
@@ -0,0 +1,38 @@
+beginCompilationUnit(f)
+  beginMetadataStar(f)
+  endMetadataStar(0)
+  beginTopLevelMember(f)
+    beginTopLevelMethod(, null)
+      handleNoType()
+      handleIdentifier(f, topLevelFunctionDeclaration)
+      handleNoTypeVariables(()
+      beginFormalParameters((, MemberKind.TopLevelMethod)
+      endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+      handleAsyncModifier(null, null)
+      beginBlockFunctionBody({)
+        handleIdentifier(foo, expression)
+        handleNoTypeArguments(.)
+        handleNoArguments(.)
+        handleSend(foo, .)
+        handleIdentifier(bar, expressionContinuation)
+        handleNoTypeArguments())
+        handleNoArguments())
+        handleSend(bar, ))
+      endBinaryExpression(.)
+      handleParenthesizedExpression(()
+      handleNonNullAssertExpression(!)
+      handleIdentifier(baz, expressionContinuation)
+      handleNoTypeArguments([)
+      handleNoArguments([)
+      handleSend(baz, [)
+    endBinaryExpression(.)
+    handleIdentifier(arg, expression)
+    handleNoTypeArguments(])
+    handleNoArguments(])
+    handleSend(arg, ])
+    handleIndexedExpression([, ])
+    handleExpressionStatement(;)
+  endBlockFunctionBody(1, {, })
+endTopLevelMethod(f, null, })
+endTopLevelDeclaration()
+endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex.dart b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex.dart
new file mode 100644
index 0000000..25e3f32
--- /dev/null
+++ b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex.dart
@@ -0,0 +1 @@
+f() { obj![arg]; }
\ No newline at end of file
diff --git a/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex.dart.expect b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex.dart.expect
new file mode 100644
index 0000000..92b9ac2
--- /dev/null
+++ b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex.dart.expect
@@ -0,0 +1,27 @@
+beginCompilationUnit(f)
+  beginMetadataStar(f)
+  endMetadataStar(0)
+  beginTopLevelMember(f)
+    beginTopLevelMethod(, null)
+      handleNoType()
+      handleIdentifier(f, topLevelFunctionDeclaration)
+      handleNoTypeVariables(()
+      beginFormalParameters((, MemberKind.TopLevelMethod)
+      endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+      handleAsyncModifier(null, null)
+      beginBlockFunctionBody({)
+        handleIdentifier(obj, expression)
+        handleNoTypeArguments(!)
+        handleNoArguments(!)
+        handleSend(obj, !)
+        handleNonNullAssertExpression(!)
+        handleIdentifier(arg, expression)
+        handleNoTypeArguments(])
+        handleNoArguments(])
+        handleSend(arg, ])
+        handleIndexedExpression([, ])
+        handleExpressionStatement(;)
+      endBlockFunctionBody(1, {, })
+    endTopLevelMethod(f, null, })
+  endTopLevelDeclaration()
+endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex2.dart b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex2.dart
new file mode 100644
index 0000000..69f3bc6
--- /dev/null
+++ b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex2.dart
@@ -0,0 +1 @@
+f() { obj![arg]![arg2]; }
\ No newline at end of file
diff --git a/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex2.dart.expect b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex2.dart.expect
new file mode 100644
index 0000000..f6e7d35
--- /dev/null
+++ b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex2.dart.expect
@@ -0,0 +1,33 @@
+beginCompilationUnit(f)
+  beginMetadataStar(f)
+  endMetadataStar(0)
+  beginTopLevelMember(f)
+    beginTopLevelMethod(, null)
+      handleNoType()
+      handleIdentifier(f, topLevelFunctionDeclaration)
+      handleNoTypeVariables(()
+      beginFormalParameters((, MemberKind.TopLevelMethod)
+      endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+      handleAsyncModifier(null, null)
+      beginBlockFunctionBody({)
+        handleIdentifier(obj, expression)
+        handleNoTypeArguments(!)
+        handleNoArguments(!)
+        handleSend(obj, !)
+        handleNonNullAssertExpression(!)
+        handleIdentifier(arg, expression)
+        handleNoTypeArguments(])
+        handleNoArguments(])
+        handleSend(arg, ])
+        handleIndexedExpression([, ])
+        handleNonNullAssertExpression(!)
+        handleIdentifier(arg2, expression)
+        handleNoTypeArguments(])
+        handleNoArguments(])
+        handleSend(arg2, ])
+        handleIndexedExpression([, ])
+        handleExpressionStatement(;)
+      endBlockFunctionBody(1, {, })
+    endTopLevelMethod(f, null, })
+  endTopLevelDeclaration()
+endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex2_with_parens.dart b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex2_with_parens.dart
new file mode 100644
index 0000000..16b0fe7
--- /dev/null
+++ b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex2_with_parens.dart
@@ -0,0 +1 @@
+f() { (((obj!)[arg])!)[arg2]; }
\ No newline at end of file
diff --git a/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex2_with_parens.dart.expect b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex2_with_parens.dart.expect
new file mode 100644
index 0000000..e1cdb65
--- /dev/null
+++ b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex2_with_parens.dart.expect
@@ -0,0 +1,36 @@
+beginCompilationUnit(f)
+  beginMetadataStar(f)
+  endMetadataStar(0)
+  beginTopLevelMember(f)
+    beginTopLevelMethod(, null)
+      handleNoType()
+      handleIdentifier(f, topLevelFunctionDeclaration)
+      handleNoTypeVariables(()
+      beginFormalParameters((, MemberKind.TopLevelMethod)
+      endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+      handleAsyncModifier(null, null)
+      beginBlockFunctionBody({)
+        handleIdentifier(obj, expression)
+        handleNoTypeArguments(!)
+        handleNoArguments(!)
+        handleSend(obj, !)
+        handleNonNullAssertExpression(!)
+        handleParenthesizedExpression(()
+        handleIdentifier(arg, expression)
+        handleNoTypeArguments(])
+        handleNoArguments(])
+        handleSend(arg, ])
+        handleIndexedExpression([, ])
+        handleParenthesizedExpression(()
+        handleNonNullAssertExpression(!)
+        handleParenthesizedExpression(()
+        handleIdentifier(arg2, expression)
+        handleNoTypeArguments(])
+        handleNoArguments(])
+        handleSend(arg2, ])
+        handleIndexedExpression([, ])
+        handleExpressionStatement(;)
+      endBlockFunctionBody(1, {, })
+    endTopLevelMethod(f, null, })
+  endTopLevelDeclaration()
+endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex3.dart b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex3.dart
new file mode 100644
index 0000000..b22f0d0
--- /dev/null
+++ b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex3.dart
@@ -0,0 +1 @@
+f() { foo.bar![arg]; }
\ No newline at end of file
diff --git a/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex3.dart.expect b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex3.dart.expect
new file mode 100644
index 0000000..fbda0ef
--- /dev/null
+++ b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex3.dart.expect
@@ -0,0 +1,32 @@
+beginCompilationUnit(f)
+  beginMetadataStar(f)
+  endMetadataStar(0)
+  beginTopLevelMember(f)
+    beginTopLevelMethod(, null)
+      handleNoType()
+      handleIdentifier(f, topLevelFunctionDeclaration)
+      handleNoTypeVariables(()
+      beginFormalParameters((, MemberKind.TopLevelMethod)
+      endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+      handleAsyncModifier(null, null)
+      beginBlockFunctionBody({)
+        handleIdentifier(foo, expression)
+        handleNoTypeArguments(.)
+        handleNoArguments(.)
+        handleSend(foo, .)
+        handleIdentifier(bar, expressionContinuation)
+        handleNoTypeArguments(!)
+        handleNoArguments(!)
+        handleSend(bar, !)
+      endBinaryExpression(.)
+      handleNonNullAssertExpression(!)
+      handleIdentifier(arg, expression)
+      handleNoTypeArguments(])
+      handleNoArguments(])
+      handleSend(arg, ])
+      handleIndexedExpression([, ])
+      handleExpressionStatement(;)
+    endBlockFunctionBody(1, {, })
+  endTopLevelMethod(f, null, })
+endTopLevelDeclaration()
+endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex3_with_parens.dart b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex3_with_parens.dart
new file mode 100644
index 0000000..97eb467
--- /dev/null
+++ b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex3_with_parens.dart
@@ -0,0 +1 @@
+f() { (foo.bar)![arg]; }
\ No newline at end of file
diff --git a/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex3_with_parens.dart.expect b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex3_with_parens.dart.expect
new file mode 100644
index 0000000..e014b78
--- /dev/null
+++ b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex3_with_parens.dart.expect
@@ -0,0 +1,33 @@
+beginCompilationUnit(f)
+  beginMetadataStar(f)
+  endMetadataStar(0)
+  beginTopLevelMember(f)
+    beginTopLevelMethod(, null)
+      handleNoType()
+      handleIdentifier(f, topLevelFunctionDeclaration)
+      handleNoTypeVariables(()
+      beginFormalParameters((, MemberKind.TopLevelMethod)
+      endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+      handleAsyncModifier(null, null)
+      beginBlockFunctionBody({)
+        handleIdentifier(foo, expression)
+        handleNoTypeArguments(.)
+        handleNoArguments(.)
+        handleSend(foo, .)
+        handleIdentifier(bar, expressionContinuation)
+        handleNoTypeArguments())
+        handleNoArguments())
+        handleSend(bar, ))
+      endBinaryExpression(.)
+      handleParenthesizedExpression(()
+      handleNonNullAssertExpression(!)
+      handleIdentifier(arg, expression)
+      handleNoTypeArguments(])
+      handleNoArguments(])
+      handleSend(arg, ])
+      handleIndexedExpression([, ])
+      handleExpressionStatement(;)
+    endBlockFunctionBody(1, {, })
+  endTopLevelMethod(f, null, })
+endTopLevelDeclaration()
+endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex4.dart b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex4.dart
new file mode 100644
index 0000000..b927b26
--- /dev/null
+++ b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex4.dart
@@ -0,0 +1 @@
+f() { foo!.bar![arg]; }
\ No newline at end of file
diff --git a/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex4.dart.expect b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex4.dart.expect
new file mode 100644
index 0000000..2fc33bb
--- /dev/null
+++ b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex4.dart.expect
@@ -0,0 +1,33 @@
+beginCompilationUnit(f)
+  beginMetadataStar(f)
+  endMetadataStar(0)
+  beginTopLevelMember(f)
+    beginTopLevelMethod(, null)
+      handleNoType()
+      handleIdentifier(f, topLevelFunctionDeclaration)
+      handleNoTypeVariables(()
+      beginFormalParameters((, MemberKind.TopLevelMethod)
+      endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+      handleAsyncModifier(null, null)
+      beginBlockFunctionBody({)
+        handleIdentifier(foo, expression)
+        handleNoTypeArguments(!)
+        handleNoArguments(!)
+        handleSend(foo, !)
+        handleNonNullAssertExpression(!)
+        handleIdentifier(bar, expressionContinuation)
+        handleNoTypeArguments(!)
+        handleNoArguments(!)
+        handleSend(bar, !)
+      endBinaryExpression(.)
+      handleNonNullAssertExpression(!)
+      handleIdentifier(arg, expression)
+      handleNoTypeArguments(])
+      handleNoArguments(])
+      handleSend(arg, ])
+      handleIndexedExpression([, ])
+      handleExpressionStatement(;)
+    endBlockFunctionBody(1, {, })
+  endTopLevelMethod(f, null, })
+endTopLevelDeclaration()
+endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex4_with_parens.dart b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex4_with_parens.dart
new file mode 100644
index 0000000..f745152c
--- /dev/null
+++ b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex4_with_parens.dart
@@ -0,0 +1 @@
+f() { ((foo!).bar!)[arg]; }
\ No newline at end of file
diff --git a/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex4_with_parens.dart.expect b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex4_with_parens.dart.expect
new file mode 100644
index 0000000..2aa6ce6
--- /dev/null
+++ b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex4_with_parens.dart.expect
@@ -0,0 +1,35 @@
+beginCompilationUnit(f)
+  beginMetadataStar(f)
+  endMetadataStar(0)
+  beginTopLevelMember(f)
+    beginTopLevelMethod(, null)
+      handleNoType()
+      handleIdentifier(f, topLevelFunctionDeclaration)
+      handleNoTypeVariables(()
+      beginFormalParameters((, MemberKind.TopLevelMethod)
+      endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+      handleAsyncModifier(null, null)
+      beginBlockFunctionBody({)
+        handleIdentifier(foo, expression)
+        handleNoTypeArguments(!)
+        handleNoArguments(!)
+        handleSend(foo, !)
+        handleNonNullAssertExpression(!)
+        handleParenthesizedExpression(()
+        handleIdentifier(bar, expressionContinuation)
+        handleNoTypeArguments(!)
+        handleNoArguments(!)
+        handleSend(bar, !)
+      endBinaryExpression(.)
+      handleNonNullAssertExpression(!)
+      handleParenthesizedExpression(()
+      handleIdentifier(arg, expression)
+      handleNoTypeArguments(])
+      handleNoArguments(])
+      handleSend(arg, ])
+      handleIndexedExpression([, ])
+      handleExpressionStatement(;)
+    endBlockFunctionBody(1, {, })
+  endTopLevelMethod(f, null, })
+endTopLevelDeclaration()
+endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex5.dart b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex5.dart
new file mode 100644
index 0000000..12a4bdc
--- /dev/null
+++ b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex5.dart
@@ -0,0 +1 @@
+f() { foo.bar![arg]![arg2]; }
\ No newline at end of file
diff --git a/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex5.dart.expect b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex5.dart.expect
new file mode 100644
index 0000000..2d56362
--- /dev/null
+++ b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex5.dart.expect
@@ -0,0 +1,38 @@
+beginCompilationUnit(f)
+  beginMetadataStar(f)
+  endMetadataStar(0)
+  beginTopLevelMember(f)
+    beginTopLevelMethod(, null)
+      handleNoType()
+      handleIdentifier(f, topLevelFunctionDeclaration)
+      handleNoTypeVariables(()
+      beginFormalParameters((, MemberKind.TopLevelMethod)
+      endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+      handleAsyncModifier(null, null)
+      beginBlockFunctionBody({)
+        handleIdentifier(foo, expression)
+        handleNoTypeArguments(.)
+        handleNoArguments(.)
+        handleSend(foo, .)
+        handleIdentifier(bar, expressionContinuation)
+        handleNoTypeArguments(!)
+        handleNoArguments(!)
+        handleSend(bar, !)
+      endBinaryExpression(.)
+      handleNonNullAssertExpression(!)
+      handleIdentifier(arg, expression)
+      handleNoTypeArguments(])
+      handleNoArguments(])
+      handleSend(arg, ])
+      handleIndexedExpression([, ])
+      handleNonNullAssertExpression(!)
+      handleIdentifier(arg2, expression)
+      handleNoTypeArguments(])
+      handleNoArguments(])
+      handleSend(arg2, ])
+      handleIndexedExpression([, ])
+      handleExpressionStatement(;)
+    endBlockFunctionBody(1, {, })
+  endTopLevelMethod(f, null, })
+endTopLevelDeclaration()
+endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex5_with_parens.dart b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex5_with_parens.dart
new file mode 100644
index 0000000..f5c5a00
--- /dev/null
+++ b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex5_with_parens.dart
@@ -0,0 +1 @@
+f() { (((foo.bar!)[arg])!)[arg2]; }
\ No newline at end of file
diff --git a/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex5_with_parens.dart.expect b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex5_with_parens.dart.expect
new file mode 100644
index 0000000..f93cac9
--- /dev/null
+++ b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex5_with_parens.dart.expect
@@ -0,0 +1,41 @@
+beginCompilationUnit(f)
+  beginMetadataStar(f)
+  endMetadataStar(0)
+  beginTopLevelMember(f)
+    beginTopLevelMethod(, null)
+      handleNoType()
+      handleIdentifier(f, topLevelFunctionDeclaration)
+      handleNoTypeVariables(()
+      beginFormalParameters((, MemberKind.TopLevelMethod)
+      endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+      handleAsyncModifier(null, null)
+      beginBlockFunctionBody({)
+        handleIdentifier(foo, expression)
+        handleNoTypeArguments(.)
+        handleNoArguments(.)
+        handleSend(foo, .)
+        handleIdentifier(bar, expressionContinuation)
+        handleNoTypeArguments(!)
+        handleNoArguments(!)
+        handleSend(bar, !)
+      endBinaryExpression(.)
+      handleNonNullAssertExpression(!)
+      handleParenthesizedExpression(()
+      handleIdentifier(arg, expression)
+      handleNoTypeArguments(])
+      handleNoArguments(])
+      handleSend(arg, ])
+      handleIndexedExpression([, ])
+      handleParenthesizedExpression(()
+      handleNonNullAssertExpression(!)
+      handleParenthesizedExpression(()
+      handleIdentifier(arg2, expression)
+      handleNoTypeArguments(])
+      handleNoArguments(])
+      handleSend(arg2, ])
+      handleIndexedExpression([, ])
+      handleExpressionStatement(;)
+    endBlockFunctionBody(1, {, })
+  endTopLevelMethod(f, null, })
+endTopLevelDeclaration()
+endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex6.dart b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex6.dart
new file mode 100644
index 0000000..afd5a23
--- /dev/null
+++ b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex6.dart
@@ -0,0 +1 @@
+f() { foo!.bar![arg]![arg2]; }
\ No newline at end of file
diff --git a/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex6.dart.expect b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex6.dart.expect
new file mode 100644
index 0000000..ee55e8f
--- /dev/null
+++ b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex6.dart.expect
@@ -0,0 +1,39 @@
+beginCompilationUnit(f)
+  beginMetadataStar(f)
+  endMetadataStar(0)
+  beginTopLevelMember(f)
+    beginTopLevelMethod(, null)
+      handleNoType()
+      handleIdentifier(f, topLevelFunctionDeclaration)
+      handleNoTypeVariables(()
+      beginFormalParameters((, MemberKind.TopLevelMethod)
+      endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+      handleAsyncModifier(null, null)
+      beginBlockFunctionBody({)
+        handleIdentifier(foo, expression)
+        handleNoTypeArguments(!)
+        handleNoArguments(!)
+        handleSend(foo, !)
+        handleNonNullAssertExpression(!)
+        handleIdentifier(bar, expressionContinuation)
+        handleNoTypeArguments(!)
+        handleNoArguments(!)
+        handleSend(bar, !)
+      endBinaryExpression(.)
+      handleNonNullAssertExpression(!)
+      handleIdentifier(arg, expression)
+      handleNoTypeArguments(])
+      handleNoArguments(])
+      handleSend(arg, ])
+      handleIndexedExpression([, ])
+      handleNonNullAssertExpression(!)
+      handleIdentifier(arg2, expression)
+      handleNoTypeArguments(])
+      handleNoArguments(])
+      handleSend(arg2, ])
+      handleIndexedExpression([, ])
+      handleExpressionStatement(;)
+    endBlockFunctionBody(1, {, })
+  endTopLevelMethod(f, null, })
+endTopLevelDeclaration()
+endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex6_with_parens.dart b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex6_with_parens.dart
new file mode 100644
index 0000000..a23cf8e
--- /dev/null
+++ b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex6_with_parens.dart
@@ -0,0 +1 @@
+f() { ((((foo!).bar!)[arg])!)[arg2]; }
\ No newline at end of file
diff --git a/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex6_with_parens.dart.expect b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex6_with_parens.dart.expect
new file mode 100644
index 0000000..d1a1044
--- /dev/null
+++ b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex6_with_parens.dart.expect
@@ -0,0 +1,43 @@
+beginCompilationUnit(f)
+  beginMetadataStar(f)
+  endMetadataStar(0)
+  beginTopLevelMember(f)
+    beginTopLevelMethod(, null)
+      handleNoType()
+      handleIdentifier(f, topLevelFunctionDeclaration)
+      handleNoTypeVariables(()
+      beginFormalParameters((, MemberKind.TopLevelMethod)
+      endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+      handleAsyncModifier(null, null)
+      beginBlockFunctionBody({)
+        handleIdentifier(foo, expression)
+        handleNoTypeArguments(!)
+        handleNoArguments(!)
+        handleSend(foo, !)
+        handleNonNullAssertExpression(!)
+        handleParenthesizedExpression(()
+        handleIdentifier(bar, expressionContinuation)
+        handleNoTypeArguments(!)
+        handleNoArguments(!)
+        handleSend(bar, !)
+      endBinaryExpression(.)
+      handleNonNullAssertExpression(!)
+      handleParenthesizedExpression(()
+      handleIdentifier(arg, expression)
+      handleNoTypeArguments(])
+      handleNoArguments(])
+      handleSend(arg, ])
+      handleIndexedExpression([, ])
+      handleParenthesizedExpression(()
+      handleNonNullAssertExpression(!)
+      handleParenthesizedExpression(()
+      handleIdentifier(arg2, expression)
+      handleNoTypeArguments(])
+      handleNoArguments(])
+      handleSend(arg2, ])
+      handleIndexedExpression([, ])
+      handleExpressionStatement(;)
+    endBlockFunctionBody(1, {, })
+  endTopLevelMethod(f, null, })
+endTopLevelDeclaration()
+endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex_with_parens.dart b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex_with_parens.dart
new file mode 100644
index 0000000..380b3bc
--- /dev/null
+++ b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex_with_parens.dart
@@ -0,0 +1 @@
+f() { (obj!)[arg]; }
\ No newline at end of file
diff --git a/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex_with_parens.dart.expect b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex_with_parens.dart.expect
new file mode 100644
index 0000000..40baa37
--- /dev/null
+++ b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex_with_parens.dart.expect
@@ -0,0 +1,28 @@
+beginCompilationUnit(f)
+  beginMetadataStar(f)
+  endMetadataStar(0)
+  beginTopLevelMember(f)
+    beginTopLevelMethod(, null)
+      handleNoType()
+      handleIdentifier(f, topLevelFunctionDeclaration)
+      handleNoTypeVariables(()
+      beginFormalParameters((, MemberKind.TopLevelMethod)
+      endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+      handleAsyncModifier(null, null)
+      beginBlockFunctionBody({)
+        handleIdentifier(obj, expression)
+        handleNoTypeArguments(!)
+        handleNoArguments(!)
+        handleSend(obj, !)
+        handleNonNullAssertExpression(!)
+        handleParenthesizedExpression(()
+        handleIdentifier(arg, expression)
+        handleNoTypeArguments(])
+        handleNoArguments(])
+        handleSend(arg, ])
+        handleIndexedExpression([, ])
+        handleExpressionStatement(;)
+      endBlockFunctionBody(1, {, })
+    endTopLevelMethod(f, null, })
+  endTopLevelDeclaration()
+endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/parser.status b/pkg/front_end/parser_testcases/parser.status
new file mode 100644
index 0000000..e22cfe5
--- /dev/null
+++ b/pkg/front_end/parser_testcases/parser.status
@@ -0,0 +1,3 @@
+# Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE.md file.
diff --git a/pkg/front_end/test/constants/data/function.dart b/pkg/front_end/test/constants/data/function.dart
index 656e0ab..987b64c5 100644
--- a/pkg/front_end/test/constants/data/function.dart
+++ b/pkg/front_end/test/constants/data/function.dart
@@ -14,15 +14,16 @@
     /*cfe.Instantiation(method2<String,int>)*/ method2;
 
 main() {
-  print(/*Function(method1)*/ function0);
-  // TODO(paulberry): analyzer should record instantiation information.  See
-  // dartbug.com/37608.
+  print(
+      /*cfe|dart2js.Function(method1)*/
+      /*analyzer.Function(method1,type=T Function<T>(T))*/
+      function0);
   print(
       /*cfe|dart2js.Instantiation(method1<int>)*/
-      /*analyzer.Function(method1)*/
+      /*analyzer.Function(method1,type=int Function(int))*/
       instantiation0);
   print(
       /*cfe|dart2js.Instantiation(method2<String,int>)*/
-      /*analyzer.Function(method2)*/
+      /*analyzer.Function(method2,type=Map<String, int> Function(String, int))*/
       instantiation1);
 }
diff --git a/pkg/front_end/test/fasta/flow_analysis/flow_analysis_test.dart b/pkg/front_end/test/fasta/flow_analysis/flow_analysis_test.dart
index b93bf2e..a171dbf 100644
--- a/pkg/front_end/test/fasta/flow_analysis/flow_analysis_test.dart
+++ b/pkg/front_end/test/fasta/flow_analysis/flow_analysis_test.dart
@@ -190,14 +190,6 @@
       expect(() => flow.finish(), _asserts);
     });
 
-    test('finish checks for un-added variables', () {
-      var h = _Harness();
-      var x = _Var('x', _Type('int'));
-      var flow = h.createFlow();
-      flow.isAssigned(x);
-      expect(() => flow.finish(), _asserts);
-    });
-
     test('for_conditionBegin() un-promotes', () {
       var h = _Harness();
       var x = h.addVar('x', 'int?');
@@ -221,7 +213,7 @@
         h.declare(y, initialized: true);
         h.promote(y, 'int');
         flow.for_conditionBegin({x});
-        flow.add(x, assigned: true);
+        flow.write(x);
         flow.for_bodyBegin(_Statement(), _Expression());
         flow.for_updaterBegin();
         flow.for_end();
@@ -705,8 +697,8 @@
         h.promote(z, 'int');
         flow.tryCatchStatement_catchEnd();
         flow.tryCatchStatement_end();
-        // Only x should be promoted, because it's the only variable promoted
-        // in both the try body and the catch handler.
+        // Only x should be promoted, because it's the only variable
+        // promoted in both the try body and the catch handler.
         expect(flow.promotedType(x).type, 'int');
         expect(flow.promotedType(y), isNull);
         expect(flow.promotedType(z), isNull);
@@ -850,7 +842,7 @@
         h.declare(y, initialized: true);
         h.promote(y, 'int');
         flow.whileStatement_conditionBegin({x});
-        flow.add(x, assigned: true);
+        flow.write(x);
         flow.whileStatement_bodyBegin(_Statement(), _Expression());
         flow.whileStatement_end();
       });
@@ -951,54 +943,31 @@
       });
     });
 
-    group('add', () {
-      test('default', () {
-        // By default, added variables are considered unassigned.
-        var s1 = FlowModel<_Var, _Type>(true);
-        var s2 = s1.add(intVar);
-        expect(s2.reachable, true);
-        expect(s2.variableInfo, {intVar: VariableModel<_Type>(null, false)});
-      });
-
-      test('unassigned', () {
-        var s1 = FlowModel<_Var, _Type>(true);
-        var s2 = s1.add(intVar, assigned: false);
-        expect(s2.reachable, true);
-        expect(s2.variableInfo, {intVar: VariableModel<_Type>(null, false)});
-      });
-
-      test('assigned', () {
-        var s1 = FlowModel<_Var, _Type>(true);
-        var s2 = s1.add(intVar, assigned: true);
-        expect(s2.variableInfo, {intVar: VariableModel<_Type>(null, true)});
-      });
-    });
-
     group('promote', () {
       test('unpromoted -> unchanged (same)', () {
         var h = _Harness();
-        var s1 = FlowModel<_Var, _Type>(true).add(intVar);
+        var s1 = FlowModel<_Var, _Type>(true);
         var s2 = s1.promote(h, intVar, _Type('int'));
         expect(s2, same(s1));
       });
 
       test('unpromoted -> unchanged (supertype)', () {
         var h = _Harness();
-        var s1 = FlowModel<_Var, _Type>(true).add(intVar);
+        var s1 = FlowModel<_Var, _Type>(true);
         var s2 = s1.promote(h, intVar, _Type('Object'));
         expect(s2, same(s1));
       });
 
       test('unpromoted -> unchanged (unrelated)', () {
         var h = _Harness();
-        var s1 = FlowModel<_Var, _Type>(true).add(intVar);
+        var s1 = FlowModel<_Var, _Type>(true);
         var s2 = s1.promote(h, intVar, _Type('String'));
         expect(s2, same(s1));
       });
 
       test('unpromoted -> subtype', () {
         var h = _Harness();
-        var s1 = FlowModel<_Var, _Type>(true).add(intQVar);
+        var s1 = FlowModel<_Var, _Type>(true);
         var s2 = s1.promote(h, intQVar, _Type('int'));
         expect(s2.reachable, true);
         _Type.allowComparisons(() {
@@ -1009,36 +978,32 @@
 
       test('promoted -> unchanged (same)', () {
         var h = _Harness();
-        var s1 = FlowModel<_Var, _Type>(true)
-            .add(objectQVar)
-            .promote(h, objectQVar, _Type('int'));
+        var s1 =
+            FlowModel<_Var, _Type>(true).promote(h, objectQVar, _Type('int'));
         var s2 = s1.promote(h, objectQVar, _Type('int'));
         expect(s2, same(s1));
       });
 
       test('promoted -> unchanged (supertype)', () {
         var h = _Harness();
-        var s1 = FlowModel<_Var, _Type>(true)
-            .add(objectQVar)
-            .promote(h, objectQVar, _Type('int'));
+        var s1 =
+            FlowModel<_Var, _Type>(true).promote(h, objectQVar, _Type('int'));
         var s2 = s1.promote(h, objectQVar, _Type('Object'));
         expect(s2, same(s1));
       });
 
       test('promoted -> unchanged (unrelated)', () {
         var h = _Harness();
-        var s1 = FlowModel<_Var, _Type>(true)
-            .add(objectQVar)
-            .promote(h, objectQVar, _Type('int'));
+        var s1 =
+            FlowModel<_Var, _Type>(true).promote(h, objectQVar, _Type('int'));
         var s2 = s1.promote(h, objectQVar, _Type('String'));
         expect(s2, same(s1));
       });
 
       test('promoted -> subtype', () {
         var h = _Harness();
-        var s1 = FlowModel<_Var, _Type>(true)
-            .add(objectQVar)
-            .promote(h, objectQVar, _Type('int?'));
+        var s1 =
+            FlowModel<_Var, _Type>(true).promote(h, objectQVar, _Type('int?'));
         var s2 = s1.promote(h, objectQVar, _Type('int'));
         expect(s2.reachable, true);
         _Type.allowComparisons(() {
@@ -1051,27 +1016,25 @@
     group('write', () {
       var objectQVar = _Var('x', _Type('Object?'));
       test('unchanged', () {
-        var h = _Harness();
-        var s1 = FlowModel<_Var, _Type>(true).add(objectQVar, assigned: true);
-        var s2 = s1.write(h, objectQVar);
+        var s1 = FlowModel<_Var, _Type>(true).write(objectQVar);
+        var s2 = s1.write(objectQVar);
         expect(s2, same(s1));
       });
 
       test('marks as assigned', () {
-        var h = _Harness();
-        var s1 = FlowModel<_Var, _Type>(true).add(objectQVar, assigned: false);
-        var s2 = s1.write(h, objectQVar);
+        var s1 = FlowModel<_Var, _Type>(true);
+        var s2 = s1.write(objectQVar);
         expect(s2.reachable, true);
-        expect(s2.variableInfo[objectQVar], VariableModel<_Type>(null, true));
+        expect(s2.infoFor(objectQVar), VariableModel<_Type>(null, true));
       });
 
       test('un-promotes', () {
         var h = _Harness();
         var s1 = FlowModel<_Var, _Type>(true)
-            .add(objectQVar, assigned: true)
+            .write(objectQVar)
             .promote(h, objectQVar, _Type('int'));
         expect(s1.variableInfo, contains(objectQVar));
-        var s2 = s1.write(h, objectQVar);
+        var s2 = s1.write(objectQVar);
         expect(s2.reachable, true);
         expect(s2.variableInfo, {objectQVar: VariableModel<_Type>(null, true)});
       });
@@ -1080,35 +1043,33 @@
     group('markNonNullable', () {
       test('unpromoted -> unchanged', () {
         var h = _Harness();
-        var s1 = FlowModel<_Var, _Type>(true).add(intVar);
+        var s1 = FlowModel<_Var, _Type>(true);
         var s2 = s1.markNonNullable(h, intVar);
         expect(s2, same(s1));
       });
 
       test('unpromoted -> promoted', () {
         var h = _Harness();
-        var s1 = FlowModel<_Var, _Type>(true).add(intQVar);
+        var s1 = FlowModel<_Var, _Type>(true);
         var s2 = s1.markNonNullable(h, intQVar);
         expect(s2.reachable, true);
         _Type.allowComparisons(() {
-          expect(s2.variableInfo[intQVar], VariableModel(_Type('int'), false));
+          expect(s2.infoFor(intQVar), VariableModel(_Type('int'), false));
         });
       });
 
       test('promoted -> unchanged', () {
         var h = _Harness();
-        var s1 = FlowModel<_Var, _Type>(true)
-            .add(objectQVar)
-            .promote(h, objectQVar, _Type('int'));
+        var s1 =
+            FlowModel<_Var, _Type>(true).promote(h, objectQVar, _Type('int'));
         var s2 = s1.markNonNullable(h, objectQVar);
         expect(s2, same(s1));
       });
 
       test('promoted -> re-promoted', () {
         var h = _Harness();
-        var s1 = FlowModel<_Var, _Type>(true)
-            .add(objectQVar)
-            .promote(h, objectQVar, _Type('int?'));
+        var s1 =
+            FlowModel<_Var, _Type>(true).promote(h, objectQVar, _Type('int?'));
         var s2 = s1.markNonNullable(h, objectQVar);
         expect(s2.reachable, true);
         _Type.allowComparisons(() {
@@ -1121,22 +1082,18 @@
     group('removePromotedAll', () {
       test('unchanged', () {
         var h = _Harness();
-        var s1 = FlowModel<_Var, _Type>(true)
-            .add(objectQVar)
-            .add(intQVar)
-            .promote(h, objectQVar, _Type('int'));
-        var s2 = s1.removePromotedAll([intQVar], null);
+        var s1 =
+            FlowModel<_Var, _Type>(true).promote(h, objectQVar, _Type('int'));
+        var s2 = s1.removePromotedAll([intQVar]);
         expect(s2, same(s1));
       });
 
       test('changed', () {
         var h = _Harness();
         var s1 = FlowModel<_Var, _Type>(true)
-            .add(objectQVar)
-            .add(intQVar)
             .promote(h, objectQVar, _Type('int'))
             .promote(h, intQVar, _Type('int'));
-        var s2 = s1.removePromotedAll([intQVar], null);
+        var s2 = s1.removePromotedAll([intQVar]);
         expect(s2.reachable, true);
         _Type.allowComparisons(() {
           expect(s2.variableInfo, {
@@ -1164,14 +1121,14 @@
         var b = _Var('b', _Type('int'));
         var c = _Var('c', _Type('int'));
         var d = _Var('d', _Type('int'));
-        var s0 = FlowModel<_Var, _Type>(true).add(a).add(b).add(c).add(d);
-        var s1 = s0.write(h, a).write(h, b);
-        var s2 = s0.write(h, a).write(h, c);
+        var s0 = FlowModel<_Var, _Type>(true);
+        var s1 = s0.write(a).write(b);
+        var s2 = s0.write(a).write(c);
         var result = s1.restrict(h, s2, Set());
-        expect(result.variableInfo[a].assigned, true);
-        expect(result.variableInfo[b].assigned, true);
-        expect(result.variableInfo[c].assigned, true);
-        expect(result.variableInfo[d].assigned, false);
+        expect(result.infoFor(a).assigned, true);
+        expect(result.infoFor(b).assigned, true);
+        expect(result.infoFor(c).assigned, true);
+        expect(result.infoFor(d).assigned, false);
       });
 
       test('promotion', () {
@@ -1179,15 +1136,15 @@
             String expectedType) {
           var h = _Harness();
           var x = _Var('x', _Type('Object?'));
-          var s0 = FlowModel<_Var, _Type>(true).add(x, assigned: true);
+          var s0 = FlowModel<_Var, _Type>(true).write(x);
           var s1 = thisType == null ? s0 : s0.promote(h, x, _Type(thisType));
           var s2 = otherType == null ? s0 : s0.promote(h, x, _Type(otherType));
           var result = s1.restrict(h, s2, unsafe ? [x].toSet() : Set());
           if (expectedType == null) {
             expect(result.variableInfo, contains(x));
-            expect(result.variableInfo[x].promotedType, isNull);
+            expect(result.infoFor(x).promotedType, isNull);
           } else {
-            expect(result.variableInfo[x].promotedType.type, expectedType);
+            expect(result.infoFor(x).promotedType.type, expectedType);
           }
         }
 
@@ -1209,9 +1166,9 @@
         var h = _Harness();
         var x = _Var('x', _Type('Object?'));
         var s0 = FlowModel<_Var, _Type>(true);
-        var s1 = s0.add(x, assigned: true);
-        expect(s0.restrict(h, s1, {}), same(s0));
-        expect(s0.restrict(h, s1, {x}), same(s0));
+        var s1 = s0.write(x);
+        expect(s0.restrict(h, s1, {}), same(s1));
+        expect(s0.restrict(h, s1, {x}), same(s1));
         expect(s1.restrict(h, s0, {}), same(s1));
         expect(s1.restrict(h, s0, {x}), same(s1));
       });
@@ -1374,7 +1331,9 @@
       FlowAnalysis<_Statement, _Expression, _Var, _Type>(this, this, this);
 
   void declare(_Var v, {@required bool initialized}) {
-    _flow.add(v, assigned: initialized);
+    if (initialized) {
+      _flow.write(v);
+    }
   }
 
   /// Creates a [LazyExpression] representing an `== null` check performed on
@@ -1403,12 +1362,6 @@
     _flow.ifStatement_end(false);
   }
 
-  @override
-  bool isLocalVariable(_Var variable) {
-    // TODO(paulberry): make tests where this returns false
-    return true;
-  }
-
   /// Creates a [LazyExpression] representing an `is!` check, checking whether
   /// [variable] has the given [type].
   LazyExpression isNotType(_Var variable, String type) {
diff --git a/pkg/front_end/test/fasta/generator_to_string_test.dart b/pkg/front_end/test/fasta/generator_to_string_test.dart
index fe1bbc0..b7aeac8 100644
--- a/pkg/front_end/test/fasta/generator_to_string_test.dart
+++ b/pkg/front_end/test/fasta/generator_to_string_test.dart
@@ -127,7 +127,7 @@
         " promotedType: void)",
         new VariableUseGenerator(helper, token, variable, type));
     check(
-        "PropertyAccessGenerator(offset: 4, _receiverVariable: null,"
+        "PropertyAccessGenerator(offset: 4,"
         " receiver: expression, name: bar, getter: $uri::myGetter,"
         " setter: $uri::mySetter)",
         new PropertyAccessGenerator(
diff --git a/pkg/front_end/test/fasta/messages_test.dart b/pkg/front_end/test/fasta/messages_test.dart
index 08e960e..f749478 100644
--- a/pkg/front_end/test/fasta/messages_test.dart
+++ b/pkg/front_end/test/fasta/messages_test.dart
@@ -104,6 +104,7 @@
       Severity severity;
       YamlNode badSeverity;
       YamlNode unnecessarySeverity;
+      List<String> badHasPublishedDocsValue = <String>[];
       List<String> spellingMessages;
       const String spellingPostMessage = "\nIf the word(s) look okay, update "
           "'spell_checking_list_messages.txt' or "
@@ -264,6 +265,12 @@
             // index is validated during generation
             break;
 
+          case "hasPublishedDocs":
+            if (value != true) {
+              badHasPublishedDocsValue.add(name);
+            }
+            break;
+
           default:
             unknownKeys.add(key);
         }
@@ -306,6 +313,14 @@
               : null);
 
       yield createDescription(
+          'hasPublishedDocs',
+          null,
+          badHasPublishedDocsValue.isNotEmpty
+              ? "Bad hasPublishedDocs value (only 'true' supported) in:"
+                  " ${badHasPublishedDocsValue.join(', ')}"
+              : null);
+
+      yield createDescription(
           "severity",
           null,
           badSeverity != null
@@ -320,6 +335,7 @@
               ? "The 'ERROR' severity is the default and not necessary."
               : null,
           location: unnecessarySeverity?.span?.start);
+
       yield createDescription(
           "spelling",
           null,
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 1dd6051..dc5203c 100644
--- a/pkg/front_end/test/fasta/parser/type_info_test.dart
+++ b/pkg/front_end/test/fasta/parser/type_info_test.dart
@@ -695,7 +695,7 @@
       'beginTypeVariable T',
       'handleTypeVariablesDefined T 1',
       'handleNoType T',
-      'endTypeVariable > 0 null',
+      'endTypeVariable > 0 null null',
       'endTypeVariables < >',
       'beginFunctionType Function',
       'handleNoType ',
@@ -729,7 +729,7 @@
       'beginTypeVariable T',
       'handleTypeVariablesDefined T 1',
       'handleNoType T',
-      'endTypeVariable > 0 null',
+      'endTypeVariable > 0 null null',
       'endTypeVariables < >',
       'beginFunctionType Function',
       'handleNoType ',
@@ -1377,7 +1377,7 @@
           'beginTypeVariable T',
           'handleTypeVariablesDefined T 1',
           'handleNoType T',
-          'endTypeVariable > 0 null',
+          'endTypeVariable > 0 null null',
           'endTypeVariables < >',
           'beginFunctionType C',
           'beginTypeVariables <',
@@ -1387,7 +1387,7 @@
           'beginTypeVariable T',
           'handleTypeVariablesDefined T 1',
           'handleNoType T',
-          'endTypeVariable > 0 null',
+          'endTypeVariable > 0 null null',
           'endTypeVariables < >',
           'beginFunctionType C',
           'handleIdentifier C prefixedTypeReference',
@@ -1638,7 +1638,7 @@
       'beginTypeVariable T',
       'handleTypeVariablesDefined T 1',
       'handleNoType T',
-      'endTypeVariable > 0 null',
+      'endTypeVariable > 0 null null',
       'endTypeVariables < >',
     ]);
     expect(listener.errors, isNull);
@@ -2023,9 +2023,9 @@
       'beginTypeVariable T',
       'handleTypeVariablesDefined T 2',
       'handleNoType T',
-      'endTypeVariable > 1 null',
+      'endTypeVariable > 1 null null',
       'handleNoType S',
-      'endTypeVariable , 0 null',
+      'endTypeVariable , 0 null null',
       'endTypeVariables < >',
     ]);
     expectComplexTypeParam('<S extends T>',
@@ -2040,7 +2040,7 @@
           'handleIdentifier T typeReference',
           'handleNoTypeArguments >',
           'handleType T null',
-          'endTypeVariable > 0 extends',
+          'endTypeVariable > 0 extends null',
           'endTypeVariables < >',
         ]);
     expectComplexTypeParam('<S extends List<T>>',
@@ -2059,7 +2059,7 @@
           'handleType T null',
           'endTypeArguments 1 < >',
           'handleType List null',
-          'endTypeVariable > 0 extends',
+          'endTypeVariable > 0 extends null',
           'endTypeVariables < >',
         ]);
     expectComplexTypeParam('<R, S extends void Function()>',
@@ -2081,9 +2081,9 @@
           'beginFormalParameters ( MemberKind.GeneralizedFunctionType',
           'endFormalParameters 0 ( ) MemberKind.GeneralizedFunctionType',
           'endFunctionType Function null',
-          'endTypeVariable > 1 extends',
+          'endTypeVariable > 1 extends null',
           'handleNoType R',
-          'endTypeVariable , 0 null',
+          'endTypeVariable , 0 null null',
           'endTypeVariables < >',
         ]);
     expectComplexTypeParam('<@A S,T>', typeArgumentCount: 2, expectedCalls: [
@@ -2103,9 +2103,9 @@
       'beginTypeVariable T',
       'handleTypeVariablesDefined T 2',
       'handleNoType T',
-      'endTypeVariable > 1 null',
+      'endTypeVariable > 1 null null',
       'handleNoType S',
-      'endTypeVariable , 0 null',
+      'endTypeVariable , 0 null null',
       'endTypeVariables < >',
     ]);
     expectComplexTypeParam('<@A() S,T>', typeArgumentCount: 2, expectedCalls: [
@@ -2126,9 +2126,9 @@
       'beginTypeVariable T',
       'handleTypeVariablesDefined T 2',
       'handleNoType T',
-      'endTypeVariable > 1 null',
+      'endTypeVariable > 1 null null',
       'handleNoType S',
-      'endTypeVariable , 0 null',
+      'endTypeVariable , 0 null null',
       'endTypeVariables < >',
     ]);
     expectComplexTypeParam('<@A() @B S,T>',
@@ -2156,9 +2156,9 @@
           'beginTypeVariable T',
           'handleTypeVariablesDefined T 2',
           'handleNoType T',
-          'endTypeVariable > 1 null',
+          'endTypeVariable > 1 null null',
           'handleNoType S',
-          'endTypeVariable , 0 null',
+          'endTypeVariable , 0 null null',
           'endTypeVariables < >',
         ]);
   }
@@ -2179,7 +2179,7 @@
           'handleIdentifier void typeReference',
           'handleNoTypeArguments >',
           'handleType void null',
-          'endTypeVariable > 0 extends',
+          'endTypeVariable > 0 extends null',
           'endTypeVariables < >'
         ]);
   }
@@ -2198,7 +2198,7 @@
           'beginTypeVariable S',
           'handleTypeVariablesDefined S 1',
           'handleNoType S',
-          'endTypeVariable Function 0 null',
+          'endTypeVariable Function 0 null null',
           'endTypeVariables < >',
         ]);
     expectComplexTypeParam('<void Function()>',
@@ -2214,7 +2214,7 @@
           'beginTypeVariable ',
           'handleTypeVariablesDefined  1',
           'handleNoType ',
-          'endTypeVariable void 0 null',
+          'endTypeVariable void 0 null null',
           'endTypeVariables < >',
         ]);
     expectComplexTypeParam('<S<T>>', typeArgumentCount: 1, expectedErrors: [
@@ -2227,7 +2227,7 @@
       'beginTypeVariable S',
       'handleTypeVariablesDefined S 1',
       'handleNoType S',
-      'endTypeVariable < 0 null',
+      'endTypeVariable < 0 null null',
       'endTypeVariables < >',
     ]);
     expectComplexTypeParam('<S T>',
@@ -2270,7 +2270,7 @@
           'handleType T null',
           'endTypeArguments 1 < >',
           'handleType List null',
-          'endTypeVariable fieldName 0 extends',
+          'endTypeVariable fieldName 0 extends null',
           'endTypeVariables < >',
         ]);
   }
@@ -2292,7 +2292,7 @@
           'handleType T null',
           'endTypeArguments 1 < >',
           'handleType Comparable null',
-          'endTypeVariable > 0 extends',
+          'endTypeVariable > 0 extends null',
           'endTypeVariables < >',
         ]);
     expectComplexTypeParam('<T extends Comparable<S>, S>',
@@ -2309,7 +2309,7 @@
           'beginTypeVariable S',
           'handleTypeVariablesDefined S 2',
           'handleNoType S',
-          'endTypeVariable > 1 null',
+          'endTypeVariable > 1 null null',
           'handleIdentifier Comparable typeReference',
           'beginTypeArguments <',
           'handleIdentifier S typeReference',
@@ -2317,7 +2317,7 @@
           'handleType S null',
           'endTypeArguments 1 < >',
           'handleType Comparable null',
-          'endTypeVariable , 0 extends',
+          'endTypeVariable , 0 extends null',
           'endTypeVariables < >'
         ]);
     expectComplexTypeParam('<T extends Function(T)>',
@@ -2345,7 +2345,7 @@
               'MemberKind.GeneralizedFunctionType',
           'endFormalParameters 1 ( ) MemberKind.GeneralizedFunctionType',
           'endFunctionType Function null',
-          'endTypeVariable > 0 extends',
+          'endTypeVariable > 0 extends null',
           'endTypeVariables < >'
         ]);
     expectComplexTypeParam('<T extends List<List<T>>>',
@@ -2368,7 +2368,7 @@
           'handleType List null',
           'endTypeArguments 1 < >',
           'handleType List null',
-          'endTypeVariable > 0 extends',
+          'endTypeVariable > 0 extends null',
           'endTypeVariables < >'
         ]);
     expectComplexTypeParam('<T extends List<Map<S, T>>>',
@@ -2394,7 +2394,7 @@
           'handleType Map null',
           'endTypeArguments 1 < >',
           'handleType List null',
-          'endTypeVariable > 0 extends',
+          'endTypeVariable > 0 extends null',
           'endTypeVariables < >'
         ]);
     expectComplexTypeParam('<T extends List<Map<S, T>>>=',
@@ -2421,7 +2421,7 @@
           'handleType Map null',
           'endTypeArguments 1 < >',
           'handleType List null',
-          'endTypeVariable >= 0 extends',
+          'endTypeVariable >= 0 extends null',
           'endTypeVariables < >'
         ]);
   }
@@ -2441,7 +2441,7 @@
           'beginTypeVariable S',
           'handleTypeVariablesDefined S 1',
           'handleNoType S',
-          'endTypeVariable < 0 null',
+          'endTypeVariable < 0 null null',
           'endTypeVariables < >',
         ]);
     expectComplexTypeParam('<S();> A',
@@ -2459,7 +2459,7 @@
           'beginTypeVariable S',
           'handleTypeVariablesDefined S 1',
           'handleNoType S',
-          'endTypeVariable ( 0 null',
+          'endTypeVariable ( 0 null null',
           'endTypeVariables < >',
         ]);
   }
@@ -2842,8 +2842,9 @@
   }
 
   @override
-  void endTypeVariable(Token token, int index, Token extendsOrSuper) {
-    calls.add('endTypeVariable $token $index $extendsOrSuper');
+  void endTypeVariable(
+      Token token, int index, Token extendsOrSuper, Token variance) {
+    calls.add('endTypeVariable $token $index $extendsOrSuper $variance');
     assertTokenInStream(token);
     assertTokenInStream(extendsOrSuper);
   }
diff --git a/pkg/front_end/test/parser_test.dart b/pkg/front_end/test/parser_test.dart
new file mode 100644
index 0000000..3c6cffb
--- /dev/null
+++ b/pkg/front_end/test/parser_test.dart
@@ -0,0 +1,96 @@
+// 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' show Future;
+
+import 'dart:convert' show jsonDecode;
+
+import 'dart:io' show File;
+
+import 'dart:typed_data' show Uint8List;
+
+import 'package:front_end/src/fasta/parser.dart' show Parser;
+
+import 'package:front_end/src/fasta/scanner/utf8_bytes_scanner.dart'
+    show Utf8BytesScanner;
+
+import 'package:front_end/src/scanner/token.dart' show Token;
+
+import 'package:testing/testing.dart'
+    show
+        Chain,
+        ChainContext,
+        ExpectationSet,
+        Result,
+        Step,
+        TestDescription,
+        runMe;
+
+import 'utils/kernel_chain.dart' show MatchContext;
+
+import 'parser_test_listener.dart' show ParserTestListener;
+
+const String EXPECTATIONS = '''
+[
+  {
+    "name": "ExpectationFileMismatch",
+    "group": "Fail"
+  },
+  {
+    "name": "ExpectationFileMissing",
+    "group": "Fail"
+  }
+]
+''';
+
+main([List<String> arguments = const []]) =>
+    runMe(arguments, createContext, configurationPath: "../testing.json");
+
+Future<Context> createContext(
+    Chain suite, Map<String, String> environment) async {
+  return new Context(environment["updateExpectations"] == "true");
+}
+
+class Context extends ChainContext with MatchContext {
+  final updateExpectations;
+
+  Context(this.updateExpectations);
+
+  final List<Step> steps = const <Step>[
+    const ParserStep(),
+  ];
+
+  final ExpectationSet expectationSet =
+      new ExpectationSet.fromJsonList(jsonDecode(EXPECTATIONS));
+}
+
+class ParserStep extends Step<TestDescription, TestDescription, Context> {
+  const ParserStep();
+
+  String get name => "parser";
+
+  Future<Result<TestDescription>> run(
+      TestDescription description, Context context) async {
+    File f = new File.fromUri(description.uri);
+    List<int> rawBytes = f.readAsBytesSync();
+
+    Uint8List bytes = new Uint8List(rawBytes.length + 1);
+    bytes.setRange(0, rawBytes.length, rawBytes);
+
+    Utf8BytesScanner scanner =
+        new Utf8BytesScanner(bytes, includeComments: true);
+    Token firstToken = scanner.tokenize();
+
+    if (firstToken == null) {
+      return crash(description, StackTrace.current);
+    }
+
+    ParserTestListener parserTestListener = new ParserTestListener();
+    Parser parser = new Parser(parserTestListener);
+    parser.parseUnit(firstToken);
+
+    return context.match<TestDescription>(
+        ".expect", "${parserTestListener.sb}", description.uri, description);
+  }
+}
diff --git a/pkg/front_end/test/parser_test_listener.dart b/pkg/front_end/test/parser_test_listener.dart
new file mode 100644
index 0000000..8bd1ead
--- /dev/null
+++ b/pkg/front_end/test/parser_test_listener.dart
@@ -0,0 +1,1645 @@
+// 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:front_end/src/fasta/messages.dart';
+import 'package:front_end/src/fasta/parser/assert.dart';
+import 'package:front_end/src/fasta/parser/declaration_kind.dart';
+import 'package:front_end/src/fasta/parser/formal_parameter_kind.dart';
+import 'package:front_end/src/fasta/parser/identifier_context.dart';
+import 'package:front_end/src/fasta/parser/listener.dart';
+import 'package:front_end/src/fasta/parser/member_kind.dart';
+import 'package:front_end/src/fasta/scanner/error_token.dart';
+import 'package:front_end/src/scanner/token.dart';
+
+// THIS FILE IS AUTO GENERATED BY 'test/parser_test_listener_creator.dart'
+
+class ParserTestListener implements Listener {
+  int indent = 0;
+  StringBuffer sb = new StringBuffer();
+
+  void doPrint(String s) {
+    sb.writeln(("  " * indent) + s);
+  }
+
+  Uri get uri => null;
+
+  void logEvent(String name) {
+    doPrint('logEvent(' '$name)');
+  }
+
+  set suppressParseErrors(bool value) {
+    doPrint('suppressParseErrors(' '$value)');
+  }
+
+  void beginArguments(Token token) {
+    doPrint('beginArguments(' '$token)');
+    indent++;
+  }
+
+  void endArguments(int count, Token beginToken, Token endToken) {
+    indent--;
+    doPrint('endArguments(' '$count, ' '$beginToken, ' '$endToken)');
+  }
+
+  void handleAsyncModifier(Token asyncToken, Token starToken) {
+    doPrint('handleAsyncModifier(' '$asyncToken, ' '$starToken)');
+  }
+
+  void beginAwaitExpression(Token token) {
+    doPrint('beginAwaitExpression(' '$token)');
+    indent++;
+  }
+
+  void endAwaitExpression(Token beginToken, Token endToken) {
+    indent--;
+    doPrint('endAwaitExpression(' '$beginToken, ' '$endToken)');
+  }
+
+  void endInvalidAwaitExpression(
+      Token beginToken, Token endToken, MessageCode errorCode) {
+    indent--;
+    doPrint('endInvalidAwaitExpression('
+        '$beginToken, '
+        '$endToken, '
+        '$errorCode)');
+  }
+
+  void beginBlock(Token token) {
+    doPrint('beginBlock(' '$token)');
+    indent++;
+  }
+
+  void endBlock(int count, Token beginToken, Token endToken) {
+    indent--;
+    doPrint('endBlock(' '$count, ' '$beginToken, ' '$endToken)');
+  }
+
+  void handleInvalidTopLevelBlock(Token token) {
+    doPrint('handleInvalidTopLevelBlock(' '$token)');
+  }
+
+  void beginCascade(Token token) {
+    doPrint('beginCascade(' '$token)');
+    indent++;
+  }
+
+  void endCascade() {
+    indent--;
+    doPrint('endCascade()');
+  }
+
+  void beginCaseExpression(Token caseKeyword) {
+    doPrint('beginCaseExpression(' '$caseKeyword)');
+    indent++;
+  }
+
+  void endCaseExpression(Token colon) {
+    indent--;
+    doPrint('endCaseExpression(' '$colon)');
+  }
+
+  void beginClassOrMixinBody(DeclarationKind kind, Token token) {
+    doPrint('beginClassOrMixinBody(' '$kind, ' '$token)');
+    indent++;
+  }
+
+  void endClassOrMixinBody(
+      DeclarationKind kind, int memberCount, Token beginToken, Token endToken) {
+    indent--;
+    doPrint('endClassOrMixinBody('
+        '$kind, '
+        '$memberCount, '
+        '$beginToken, '
+        '$endToken)');
+  }
+
+  void beginClassOrNamedMixinApplicationPrelude(Token token) {
+    doPrint('beginClassOrNamedMixinApplicationPrelude(' '$token)');
+    indent++;
+  }
+
+  void beginClassDeclaration(Token begin, Token abstractToken, Token name) {
+    doPrint('beginClassDeclaration(' '$begin, ' '$abstractToken, ' '$name)');
+    indent++;
+  }
+
+  void handleClassExtends(Token extendsKeyword) {
+    doPrint('handleClassExtends(' '$extendsKeyword)');
+  }
+
+  void handleClassOrMixinImplements(
+      Token implementsKeyword, int interfacesCount) {
+    doPrint('handleClassOrMixinImplements('
+        '$implementsKeyword, '
+        '$interfacesCount)');
+  }
+
+  void handleClassHeader(Token begin, Token classKeyword, Token nativeToken) {
+    doPrint('handleClassHeader(' '$begin, ' '$classKeyword, ' '$nativeToken)');
+  }
+
+  void handleRecoverClassHeader() {
+    doPrint('handleRecoverClassHeader()');
+  }
+
+  void endClassDeclaration(Token beginToken, Token endToken) {
+    indent--;
+    doPrint('endClassDeclaration(' '$beginToken, ' '$endToken)');
+  }
+
+  void beginMixinDeclaration(Token mixinKeyword, Token name) {
+    doPrint('beginMixinDeclaration(' '$mixinKeyword, ' '$name)');
+    indent++;
+  }
+
+  void handleMixinOn(Token onKeyword, int typeCount) {
+    doPrint('handleMixinOn(' '$onKeyword, ' '$typeCount)');
+  }
+
+  void handleMixinHeader(Token mixinKeyword) {
+    doPrint('handleMixinHeader(' '$mixinKeyword)');
+  }
+
+  void handleRecoverMixinHeader() {
+    doPrint('handleRecoverMixinHeader()');
+  }
+
+  void endMixinDeclaration(Token mixinKeyword, Token endToken) {
+    indent--;
+    doPrint('endMixinDeclaration(' '$mixinKeyword, ' '$endToken)');
+  }
+
+  void beginExtensionDeclarationPrelude(Token extensionKeyword) {
+    doPrint('beginExtensionDeclarationPrelude(' '$extensionKeyword)');
+    indent++;
+  }
+
+  void beginExtensionDeclaration(Token extensionKeyword, Token name) {
+    doPrint('beginExtensionDeclaration(' '$extensionKeyword, ' '$name)');
+    indent++;
+  }
+
+  void endExtensionDeclaration(
+      Token extensionKeyword, Token onKeyword, Token token) {
+    indent--;
+    doPrint('endExtensionDeclaration('
+        '$extensionKeyword, '
+        '$onKeyword, '
+        '$token)');
+  }
+
+  void beginCombinators(Token token) {
+    doPrint('beginCombinators(' '$token)');
+    indent++;
+  }
+
+  void endCombinators(int count) {
+    indent--;
+    doPrint('endCombinators(' '$count)');
+  }
+
+  void beginCompilationUnit(Token token) {
+    doPrint('beginCompilationUnit(' '$token)');
+    indent++;
+  }
+
+  void handleDirectivesOnly() {
+    doPrint('handleDirectivesOnly()');
+  }
+
+  void endCompilationUnit(int count, Token token) {
+    indent--;
+    doPrint('endCompilationUnit(' '$count, ' '$token)');
+  }
+
+  void beginConstLiteral(Token token) {
+    doPrint('beginConstLiteral(' '$token)');
+    indent++;
+  }
+
+  void endConstLiteral(Token token) {
+    indent--;
+    doPrint('endConstLiteral(' '$token)');
+  }
+
+  void beginConstructorReference(Token start) {
+    doPrint('beginConstructorReference(' '$start)');
+    indent++;
+  }
+
+  void endConstructorReference(
+      Token start, Token periodBeforeName, Token endToken) {
+    indent--;
+    doPrint('endConstructorReference('
+        '$start, '
+        '$periodBeforeName, '
+        '$endToken)');
+  }
+
+  void beginDoWhileStatement(Token token) {
+    doPrint('beginDoWhileStatement(' '$token)');
+    indent++;
+  }
+
+  void endDoWhileStatement(
+      Token doKeyword, Token whileKeyword, Token endToken) {
+    indent--;
+    doPrint(
+        'endDoWhileStatement(' '$doKeyword, ' '$whileKeyword, ' '$endToken)');
+  }
+
+  void beginDoWhileStatementBody(Token token) {
+    doPrint('beginDoWhileStatementBody(' '$token)');
+    indent++;
+  }
+
+  void endDoWhileStatementBody(Token token) {
+    indent--;
+    doPrint('endDoWhileStatementBody(' '$token)');
+  }
+
+  void beginWhileStatementBody(Token token) {
+    doPrint('beginWhileStatementBody(' '$token)');
+    indent++;
+  }
+
+  void endWhileStatementBody(Token token) {
+    indent--;
+    doPrint('endWhileStatementBody(' '$token)');
+  }
+
+  void beginEnum(Token enumKeyword) {
+    doPrint('beginEnum(' '$enumKeyword)');
+    indent++;
+  }
+
+  void endEnum(Token enumKeyword, Token leftBrace, int count) {
+    indent--;
+    doPrint('endEnum(' '$enumKeyword, ' '$leftBrace, ' '$count)');
+  }
+
+  void beginExport(Token token) {
+    doPrint('beginExport(' '$token)');
+    indent++;
+  }
+
+  void endExport(Token exportKeyword, Token semicolon) {
+    indent--;
+    doPrint('endExport(' '$exportKeyword, ' '$semicolon)');
+  }
+
+  void handleExtraneousExpression(Token token, Message message) {
+    doPrint('handleExtraneousExpression(' '$token, ' '$message)');
+  }
+
+  void handleExpressionStatement(Token token) {
+    doPrint('handleExpressionStatement(' '$token)');
+  }
+
+  void beginFactoryMethod(
+      Token lastConsumed, Token externalToken, Token constToken) {
+    doPrint('beginFactoryMethod('
+        '$lastConsumed, '
+        '$externalToken, '
+        '$constToken)');
+    indent++;
+  }
+
+  void endClassFactoryMethod(
+      Token beginToken, Token factoryKeyword, Token endToken) {
+    indent--;
+    doPrint('endClassFactoryMethod('
+        '$beginToken, '
+        '$factoryKeyword, '
+        '$endToken)');
+  }
+
+  void endMixinFactoryMethod(
+      Token beginToken, Token factoryKeyword, Token endToken) {
+    indent--;
+    doPrint('endMixinFactoryMethod('
+        '$beginToken, '
+        '$factoryKeyword, '
+        '$endToken)');
+  }
+
+  void endExtensionFactoryMethod(
+      Token beginToken, Token factoryKeyword, Token endToken) {
+    indent--;
+    doPrint('endExtensionFactoryMethod('
+        '$beginToken, '
+        '$factoryKeyword, '
+        '$endToken)');
+  }
+
+  void beginFormalParameter(Token token, MemberKind kind, Token requiredToken,
+      Token covariantToken, Token varFinalOrConst) {
+    doPrint('beginFormalParameter('
+        '$token, '
+        '$kind, '
+        '$requiredToken, '
+        '$covariantToken, '
+        '$varFinalOrConst)');
+    indent++;
+  }
+
+  void endFormalParameter(
+      Token thisKeyword,
+      Token periodAfterThis,
+      Token nameToken,
+      Token initializerStart,
+      Token initializerEnd,
+      FormalParameterKind kind,
+      MemberKind memberKind) {
+    indent--;
+    doPrint('endFormalParameter('
+        '$thisKeyword, '
+        '$periodAfterThis, '
+        '$nameToken, '
+        '$initializerStart, '
+        '$initializerEnd, '
+        '$kind, '
+        '$memberKind)');
+  }
+
+  void handleNoFormalParameters(Token token, MemberKind kind) {
+    doPrint('handleNoFormalParameters(' '$token, ' '$kind)');
+  }
+
+  void beginFormalParameters(Token token, MemberKind kind) {
+    doPrint('beginFormalParameters(' '$token, ' '$kind)');
+    indent++;
+  }
+
+  void endFormalParameters(
+      int count, Token beginToken, Token endToken, MemberKind kind) {
+    indent--;
+    doPrint('endFormalParameters('
+        '$count, '
+        '$beginToken, '
+        '$endToken, '
+        '$kind)');
+  }
+
+  void endClassFields(Token staticToken, Token covariantToken, Token lateToken,
+      Token varFinalOrConst, int count, Token beginToken, Token endToken) {
+    indent--;
+    doPrint('endClassFields('
+        '$staticToken, '
+        '$covariantToken, '
+        '$lateToken, '
+        '$varFinalOrConst, '
+        '$count, '
+        '$beginToken, '
+        '$endToken)');
+  }
+
+  void endMixinFields(Token staticToken, Token covariantToken, Token lateToken,
+      Token varFinalOrConst, int count, Token beginToken, Token endToken) {
+    indent--;
+    doPrint('endMixinFields('
+        '$staticToken, '
+        '$covariantToken, '
+        '$lateToken, '
+        '$varFinalOrConst, '
+        '$count, '
+        '$beginToken, '
+        '$endToken)');
+  }
+
+  void endExtensionFields(
+      Token staticToken,
+      Token covariantToken,
+      Token lateToken,
+      Token varFinalOrConst,
+      int count,
+      Token beginToken,
+      Token endToken) {
+    indent--;
+    doPrint('endExtensionFields('
+        '$staticToken, '
+        '$covariantToken, '
+        '$lateToken, '
+        '$varFinalOrConst, '
+        '$count, '
+        '$beginToken, '
+        '$endToken)');
+  }
+
+  void handleForInitializerEmptyStatement(Token token) {
+    doPrint('handleForInitializerEmptyStatement(' '$token)');
+  }
+
+  void handleForInitializerExpressionStatement(Token token) {
+    doPrint('handleForInitializerExpressionStatement(' '$token)');
+  }
+
+  void handleForInitializerLocalVariableDeclaration(Token token) {
+    doPrint('handleForInitializerLocalVariableDeclaration(' '$token)');
+  }
+
+  void beginForStatement(Token token) {
+    doPrint('beginForStatement(' '$token)');
+    indent++;
+  }
+
+  void handleForLoopParts(Token forKeyword, Token leftParen,
+      Token leftSeparator, int updateExpressionCount) {
+    doPrint('handleForLoopParts('
+        '$forKeyword, '
+        '$leftParen, '
+        '$leftSeparator, '
+        '$updateExpressionCount)');
+  }
+
+  void endForStatement(Token endToken) {
+    indent--;
+    doPrint('endForStatement(' '$endToken)');
+  }
+
+  void beginForStatementBody(Token token) {
+    doPrint('beginForStatementBody(' '$token)');
+    indent++;
+  }
+
+  void endForStatementBody(Token token) {
+    indent--;
+    doPrint('endForStatementBody(' '$token)');
+  }
+
+  void handleForInLoopParts(Token awaitToken, Token forToken,
+      Token leftParenthesis, Token inKeyword) {
+    doPrint('handleForInLoopParts('
+        '$awaitToken, '
+        '$forToken, '
+        '$leftParenthesis, '
+        '$inKeyword)');
+  }
+
+  void endForIn(Token endToken) {
+    indent--;
+    doPrint('endForIn(' '$endToken)');
+  }
+
+  void beginForInExpression(Token token) {
+    doPrint('beginForInExpression(' '$token)');
+    indent++;
+  }
+
+  void endForInExpression(Token token) {
+    indent--;
+    doPrint('endForInExpression(' '$token)');
+  }
+
+  void beginForInBody(Token token) {
+    doPrint('beginForInBody(' '$token)');
+    indent++;
+  }
+
+  void endForInBody(Token token) {
+    indent--;
+    doPrint('endForInBody(' '$token)');
+  }
+
+  void beginNamedFunctionExpression(Token token) {
+    doPrint('beginNamedFunctionExpression(' '$token)');
+    indent++;
+  }
+
+  void endNamedFunctionExpression(Token endToken) {
+    indent--;
+    doPrint('endNamedFunctionExpression(' '$endToken)');
+  }
+
+  void beginLocalFunctionDeclaration(Token token) {
+    doPrint('beginLocalFunctionDeclaration(' '$token)');
+    indent++;
+  }
+
+  void endLocalFunctionDeclaration(Token endToken) {
+    indent--;
+    doPrint('endLocalFunctionDeclaration(' '$endToken)');
+  }
+
+  void beginBlockFunctionBody(Token token) {
+    doPrint('beginBlockFunctionBody(' '$token)');
+    indent++;
+  }
+
+  void endBlockFunctionBody(int count, Token beginToken, Token endToken) {
+    indent--;
+    doPrint('endBlockFunctionBody(' '$count, ' '$beginToken, ' '$endToken)');
+  }
+
+  void handleNoFunctionBody(Token token) {
+    doPrint('handleNoFunctionBody(' '$token)');
+  }
+
+  void handleFunctionBodySkipped(Token token, bool isExpressionBody) {
+    doPrint('handleFunctionBodySkipped(' '$token, ' '$isExpressionBody)');
+  }
+
+  void beginFunctionName(Token token) {
+    doPrint('beginFunctionName(' '$token)');
+    indent++;
+  }
+
+  void endFunctionName(Token beginToken, Token token) {
+    indent--;
+    doPrint('endFunctionName(' '$beginToken, ' '$token)');
+  }
+
+  void beginFunctionTypeAlias(Token token) {
+    doPrint('beginFunctionTypeAlias(' '$token)');
+    indent++;
+  }
+
+  void endFunctionTypeAlias(
+      Token typedefKeyword, Token equals, Token endToken) {
+    indent--;
+    doPrint(
+        'endFunctionTypeAlias(' '$typedefKeyword, ' '$equals, ' '$endToken)');
+  }
+
+  void handleClassWithClause(Token withKeyword) {
+    doPrint('handleClassWithClause(' '$withKeyword)');
+  }
+
+  void handleClassNoWithClause() {
+    doPrint('handleClassNoWithClause()');
+  }
+
+  void beginNamedMixinApplication(
+      Token begin, Token abstractToken, Token name) {
+    doPrint(
+        'beginNamedMixinApplication(' '$begin, ' '$abstractToken, ' '$name)');
+    indent++;
+  }
+
+  void handleNamedMixinApplicationWithClause(Token withKeyword) {
+    doPrint('handleNamedMixinApplicationWithClause(' '$withKeyword)');
+  }
+
+  void endNamedMixinApplication(Token begin, Token classKeyword, Token equals,
+      Token implementsKeyword, Token endToken) {
+    indent--;
+    doPrint('endNamedMixinApplication('
+        '$begin, '
+        '$classKeyword, '
+        '$equals, '
+        '$implementsKeyword, '
+        '$endToken)');
+  }
+
+  void beginHide(Token hideKeyword) {
+    doPrint('beginHide(' '$hideKeyword)');
+    indent++;
+  }
+
+  void endHide(Token hideKeyword) {
+    indent--;
+    doPrint('endHide(' '$hideKeyword)');
+  }
+
+  void handleIdentifierList(int count) {
+    doPrint('handleIdentifierList(' '$count)');
+  }
+
+  void beginTypeList(Token token) {
+    doPrint('beginTypeList(' '$token)');
+    indent++;
+  }
+
+  void endTypeList(int count) {
+    indent--;
+    doPrint('endTypeList(' '$count)');
+  }
+
+  void beginIfStatement(Token token) {
+    doPrint('beginIfStatement(' '$token)');
+    indent++;
+  }
+
+  void endIfStatement(Token ifToken, Token elseToken) {
+    indent--;
+    doPrint('endIfStatement(' '$ifToken, ' '$elseToken)');
+  }
+
+  void beginThenStatement(Token token) {
+    doPrint('beginThenStatement(' '$token)');
+    indent++;
+  }
+
+  void endThenStatement(Token token) {
+    indent--;
+    doPrint('endThenStatement(' '$token)');
+  }
+
+  void beginElseStatement(Token token) {
+    doPrint('beginElseStatement(' '$token)');
+    indent++;
+  }
+
+  void endElseStatement(Token token) {
+    indent--;
+    doPrint('endElseStatement(' '$token)');
+  }
+
+  void beginImport(Token importKeyword) {
+    doPrint('beginImport(' '$importKeyword)');
+    indent++;
+  }
+
+  void handleImportPrefix(Token deferredKeyword, Token asKeyword) {
+    doPrint('handleImportPrefix(' '$deferredKeyword, ' '$asKeyword)');
+  }
+
+  void endImport(Token importKeyword, Token semicolon) {
+    indent--;
+    doPrint('endImport(' '$importKeyword, ' '$semicolon)');
+  }
+
+  void handleRecoverImport(Token semicolon) {
+    doPrint('handleRecoverImport(' '$semicolon)');
+  }
+
+  void beginConditionalUris(Token token) {
+    doPrint('beginConditionalUris(' '$token)');
+    indent++;
+  }
+
+  void endConditionalUris(int count) {
+    indent--;
+    doPrint('endConditionalUris(' '$count)');
+  }
+
+  void beginConditionalUri(Token ifKeyword) {
+    doPrint('beginConditionalUri(' '$ifKeyword)');
+    indent++;
+  }
+
+  void endConditionalUri(Token ifKeyword, Token leftParen, Token equalSign) {
+    indent--;
+    doPrint('endConditionalUri(' '$ifKeyword, ' '$leftParen, ' '$equalSign)');
+  }
+
+  void handleDottedName(int count, Token firstIdentifier) {
+    doPrint('handleDottedName(' '$count, ' '$firstIdentifier)');
+  }
+
+  void beginImplicitCreationExpression(Token token) {
+    doPrint('beginImplicitCreationExpression(' '$token)');
+    indent++;
+  }
+
+  void endImplicitCreationExpression(Token token) {
+    indent--;
+    doPrint('endImplicitCreationExpression(' '$token)');
+  }
+
+  void beginInitializedIdentifier(Token token) {
+    doPrint('beginInitializedIdentifier(' '$token)');
+    indent++;
+  }
+
+  void endInitializedIdentifier(Token nameToken) {
+    indent--;
+    doPrint('endInitializedIdentifier(' '$nameToken)');
+  }
+
+  void beginFieldInitializer(Token token) {
+    doPrint('beginFieldInitializer(' '$token)');
+    indent++;
+  }
+
+  void endFieldInitializer(Token assignment, Token token) {
+    indent--;
+    doPrint('endFieldInitializer(' '$assignment, ' '$token)');
+  }
+
+  void handleNoFieldInitializer(Token token) {
+    doPrint('handleNoFieldInitializer(' '$token)');
+  }
+
+  void beginVariableInitializer(Token token) {
+    doPrint('beginVariableInitializer(' '$token)');
+    indent++;
+  }
+
+  void endVariableInitializer(Token assignmentOperator) {
+    indent--;
+    doPrint('endVariableInitializer(' '$assignmentOperator)');
+  }
+
+  void handleNoVariableInitializer(Token token) {
+    doPrint('handleNoVariableInitializer(' '$token)');
+  }
+
+  void beginInitializer(Token token) {
+    doPrint('beginInitializer(' '$token)');
+    indent++;
+  }
+
+  void endInitializer(Token token) {
+    indent--;
+    doPrint('endInitializer(' '$token)');
+  }
+
+  void beginInitializers(Token token) {
+    doPrint('beginInitializers(' '$token)');
+    indent++;
+  }
+
+  void endInitializers(int count, Token beginToken, Token endToken) {
+    indent--;
+    doPrint('endInitializers(' '$count, ' '$beginToken, ' '$endToken)');
+  }
+
+  void handleNoInitializers() {
+    doPrint('handleNoInitializers()');
+  }
+
+  void handleInvalidExpression(Token token) {
+    doPrint('handleInvalidExpression(' '$token)');
+  }
+
+  void handleInvalidFunctionBody(Token token) {
+    doPrint('handleInvalidFunctionBody(' '$token)');
+  }
+
+  void handleInvalidTypeReference(Token token) {
+    doPrint('handleInvalidTypeReference(' '$token)');
+  }
+
+  void handleLabel(Token token) {
+    doPrint('handleLabel(' '$token)');
+  }
+
+  void beginLabeledStatement(Token token, int labelCount) {
+    doPrint('beginLabeledStatement(' '$token, ' '$labelCount)');
+    indent++;
+  }
+
+  void endLabeledStatement(int labelCount) {
+    indent--;
+    doPrint('endLabeledStatement(' '$labelCount)');
+  }
+
+  void beginLibraryName(Token token) {
+    doPrint('beginLibraryName(' '$token)');
+    indent++;
+  }
+
+  void endLibraryName(Token libraryKeyword, Token semicolon) {
+    indent--;
+    doPrint('endLibraryName(' '$libraryKeyword, ' '$semicolon)');
+  }
+
+  void handleLiteralMapEntry(Token colon, Token endToken) {
+    doPrint('handleLiteralMapEntry(' '$colon, ' '$endToken)');
+  }
+
+  void beginLiteralString(Token token) {
+    doPrint('beginLiteralString(' '$token)');
+    indent++;
+  }
+
+  void handleInterpolationExpression(Token leftBracket, Token rightBracket) {
+    doPrint('handleInterpolationExpression(' '$leftBracket, ' '$rightBracket)');
+  }
+
+  void endLiteralString(int interpolationCount, Token endToken) {
+    indent--;
+    doPrint('endLiteralString(' '$interpolationCount, ' '$endToken)');
+  }
+
+  void handleStringJuxtaposition(int literalCount) {
+    doPrint('handleStringJuxtaposition(' '$literalCount)');
+  }
+
+  void beginMember() {
+    doPrint('beginMember()');
+    indent++;
+  }
+
+  void handleInvalidMember(Token endToken) {
+    doPrint('handleInvalidMember(' '$endToken)');
+  }
+
+  void endMember() {
+    indent--;
+    doPrint('endMember()');
+  }
+
+  void beginMethod(Token externalToken, Token staticToken, Token covariantToken,
+      Token varFinalOrConst, Token getOrSet, Token name) {
+    doPrint('beginMethod('
+        '$externalToken, '
+        '$staticToken, '
+        '$covariantToken, '
+        '$varFinalOrConst, '
+        '$getOrSet, '
+        '$name)');
+    indent++;
+  }
+
+  void endClassMethod(Token getOrSet, Token beginToken, Token beginParam,
+      Token beginInitializers, Token endToken) {
+    indent--;
+    doPrint('endClassMethod('
+        '$getOrSet, '
+        '$beginToken, '
+        '$beginParam, '
+        '$beginInitializers, '
+        '$endToken)');
+  }
+
+  void endMixinMethod(Token getOrSet, Token beginToken, Token beginParam,
+      Token beginInitializers, Token endToken) {
+    indent--;
+    doPrint('endMixinMethod('
+        '$getOrSet, '
+        '$beginToken, '
+        '$beginParam, '
+        '$beginInitializers, '
+        '$endToken)');
+  }
+
+  void endExtensionMethod(Token getOrSet, Token beginToken, Token beginParam,
+      Token beginInitializers, Token endToken) {
+    indent--;
+    doPrint('endExtensionMethod('
+        '$getOrSet, '
+        '$beginToken, '
+        '$beginParam, '
+        '$beginInitializers, '
+        '$endToken)');
+  }
+
+  void endClassConstructor(Token getOrSet, Token beginToken, Token beginParam,
+      Token beginInitializers, Token endToken) {
+    indent--;
+    doPrint('endClassConstructor('
+        '$getOrSet, '
+        '$beginToken, '
+        '$beginParam, '
+        '$beginInitializers, '
+        '$endToken)');
+  }
+
+  void endMixinConstructor(Token getOrSet, Token beginToken, Token beginParam,
+      Token beginInitializers, Token endToken) {
+    indent--;
+    doPrint('endMixinConstructor('
+        '$getOrSet, '
+        '$beginToken, '
+        '$beginParam, '
+        '$beginInitializers, '
+        '$endToken)');
+  }
+
+  void endExtensionConstructor(Token getOrSet, Token beginToken,
+      Token beginParam, Token beginInitializers, Token endToken) {
+    indent--;
+    doPrint('endExtensionConstructor('
+        '$getOrSet, '
+        '$beginToken, '
+        '$beginParam, '
+        '$beginInitializers, '
+        '$endToken)');
+  }
+
+  void beginMetadataStar(Token token) {
+    doPrint('beginMetadataStar(' '$token)');
+    indent++;
+  }
+
+  void endMetadataStar(int count) {
+    indent--;
+    doPrint('endMetadataStar(' '$count)');
+  }
+
+  void beginMetadata(Token token) {
+    doPrint('beginMetadata(' '$token)');
+    indent++;
+  }
+
+  void endMetadata(Token beginToken, Token periodBeforeName, Token endToken) {
+    indent--;
+    doPrint('endMetadata(' '$beginToken, ' '$periodBeforeName, ' '$endToken)');
+  }
+
+  void beginOptionalFormalParameters(Token token) {
+    doPrint('beginOptionalFormalParameters(' '$token)');
+    indent++;
+  }
+
+  void endOptionalFormalParameters(
+      int count, Token beginToken, Token endToken) {
+    indent--;
+    doPrint(
+        'endOptionalFormalParameters(' '$count, ' '$beginToken, ' '$endToken)');
+  }
+
+  void beginPart(Token token) {
+    doPrint('beginPart(' '$token)');
+    indent++;
+  }
+
+  void endPart(Token partKeyword, Token semicolon) {
+    indent--;
+    doPrint('endPart(' '$partKeyword, ' '$semicolon)');
+  }
+
+  void beginPartOf(Token token) {
+    doPrint('beginPartOf(' '$token)');
+    indent++;
+  }
+
+  void endPartOf(
+      Token partKeyword, Token ofKeyword, Token semicolon, bool hasName) {
+    indent--;
+    doPrint('endPartOf('
+        '$partKeyword, '
+        '$ofKeyword, '
+        '$semicolon, '
+        '$hasName)');
+  }
+
+  void beginRedirectingFactoryBody(Token token) {
+    doPrint('beginRedirectingFactoryBody(' '$token)');
+    indent++;
+  }
+
+  void endRedirectingFactoryBody(Token beginToken, Token endToken) {
+    indent--;
+    doPrint('endRedirectingFactoryBody(' '$beginToken, ' '$endToken)');
+  }
+
+  void beginReturnStatement(Token token) {
+    doPrint('beginReturnStatement(' '$token)');
+    indent++;
+  }
+
+  void handleNativeFunctionBody(Token nativeToken, Token semicolon) {
+    doPrint('handleNativeFunctionBody(' '$nativeToken, ' '$semicolon)');
+  }
+
+  void handleNativeFunctionBodyIgnored(Token nativeToken, Token semicolon) {
+    doPrint('handleNativeFunctionBodyIgnored(' '$nativeToken, ' '$semicolon)');
+  }
+
+  void handleNativeFunctionBodySkipped(Token nativeToken, Token semicolon) {
+    doPrint('handleNativeFunctionBodySkipped(' '$nativeToken, ' '$semicolon)');
+  }
+
+  void handleEmptyFunctionBody(Token semicolon) {
+    doPrint('handleEmptyFunctionBody(' '$semicolon)');
+  }
+
+  void handleExpressionFunctionBody(Token arrowToken, Token endToken) {
+    doPrint('handleExpressionFunctionBody(' '$arrowToken, ' '$endToken)');
+  }
+
+  void endReturnStatement(
+      bool hasExpression, Token beginToken, Token endToken) {
+    indent--;
+    doPrint(
+        'endReturnStatement(' '$hasExpression, ' '$beginToken, ' '$endToken)');
+  }
+
+  void handleSend(Token beginToken, Token endToken) {
+    doPrint('handleSend(' '$beginToken, ' '$endToken)');
+  }
+
+  void beginShow(Token showKeyword) {
+    doPrint('beginShow(' '$showKeyword)');
+    indent++;
+  }
+
+  void endShow(Token showKeyword) {
+    indent--;
+    doPrint('endShow(' '$showKeyword)');
+  }
+
+  void beginSwitchStatement(Token token) {
+    doPrint('beginSwitchStatement(' '$token)');
+    indent++;
+  }
+
+  void endSwitchStatement(Token switchKeyword, Token endToken) {
+    indent--;
+    doPrint('endSwitchStatement(' '$switchKeyword, ' '$endToken)');
+  }
+
+  void beginSwitchBlock(Token token) {
+    doPrint('beginSwitchBlock(' '$token)');
+    indent++;
+  }
+
+  void endSwitchBlock(int caseCount, Token beginToken, Token endToken) {
+    indent--;
+    doPrint('endSwitchBlock(' '$caseCount, ' '$beginToken, ' '$endToken)');
+  }
+
+  void beginLiteralSymbol(Token token) {
+    doPrint('beginLiteralSymbol(' '$token)');
+    indent++;
+  }
+
+  void endLiteralSymbol(Token hashToken, int identifierCount) {
+    indent--;
+    doPrint('endLiteralSymbol(' '$hashToken, ' '$identifierCount)');
+  }
+
+  void handleThrowExpression(Token throwToken, Token endToken) {
+    doPrint('handleThrowExpression(' '$throwToken, ' '$endToken)');
+  }
+
+  void beginRethrowStatement(Token token) {
+    doPrint('beginRethrowStatement(' '$token)');
+    indent++;
+  }
+
+  void endRethrowStatement(Token rethrowToken, Token endToken) {
+    indent--;
+    doPrint('endRethrowStatement(' '$rethrowToken, ' '$endToken)');
+  }
+
+  void endTopLevelDeclaration(Token token) {
+    indent--;
+    doPrint('endTopLevelDeclaration(' '$token)');
+  }
+
+  void handleInvalidTopLevelDeclaration(Token endToken) {
+    doPrint('handleInvalidTopLevelDeclaration(' '$endToken)');
+  }
+
+  void beginTopLevelMember(Token token) {
+    doPrint('beginTopLevelMember(' '$token)');
+    indent++;
+  }
+
+  void endTopLevelFields(
+      Token staticToken,
+      Token covariantToken,
+      Token lateToken,
+      Token varFinalOrConst,
+      int count,
+      Token beginToken,
+      Token endToken) {
+    indent--;
+    doPrint('endTopLevelFields('
+        '$staticToken, '
+        '$covariantToken, '
+        '$lateToken, '
+        '$varFinalOrConst, '
+        '$count, '
+        '$beginToken, '
+        '$endToken)');
+  }
+
+  void beginTopLevelMethod(Token lastConsumed, Token externalToken) {
+    doPrint('beginTopLevelMethod(' '$lastConsumed, ' '$externalToken)');
+    indent++;
+  }
+
+  void endTopLevelMethod(Token beginToken, Token getOrSet, Token endToken) {
+    indent--;
+    doPrint('endTopLevelMethod(' '$beginToken, ' '$getOrSet, ' '$endToken)');
+  }
+
+  void beginTryStatement(Token token) {
+    doPrint('beginTryStatement(' '$token)');
+    indent++;
+  }
+
+  void handleCaseMatch(Token caseKeyword, Token colon) {
+    doPrint('handleCaseMatch(' '$caseKeyword, ' '$colon)');
+  }
+
+  void beginCatchClause(Token token) {
+    doPrint('beginCatchClause(' '$token)');
+    indent++;
+  }
+
+  void endCatchClause(Token token) {
+    indent--;
+    doPrint('endCatchClause(' '$token)');
+  }
+
+  void handleCatchBlock(Token onKeyword, Token catchKeyword, Token comma) {
+    doPrint('handleCatchBlock(' '$onKeyword, ' '$catchKeyword, ' '$comma)');
+  }
+
+  void handleFinallyBlock(Token finallyKeyword) {
+    doPrint('handleFinallyBlock(' '$finallyKeyword)');
+  }
+
+  void endTryStatement(int catchCount, Token tryKeyword, Token finallyKeyword) {
+    indent--;
+    doPrint(
+        'endTryStatement(' '$catchCount, ' '$tryKeyword, ' '$finallyKeyword)');
+  }
+
+  void handleType(Token beginToken, Token questionMark) {
+    doPrint('handleType(' '$beginToken, ' '$questionMark)');
+  }
+
+  void handleNonNullAssertExpression(Token bang) {
+    doPrint('handleNonNullAssertExpression(' '$bang)');
+  }
+
+  void reportErrorIfNullableType(Token questionMark) {
+    doPrint('reportErrorIfNullableType(' '$questionMark)');
+  }
+
+  void reportNonNullableModifierError(Token modifierToken) {
+    doPrint('reportNonNullableModifierError(' '$modifierToken)');
+  }
+
+  void reportNonNullAssertExpressionNotEnabled(Token bang) {
+    doPrint('reportNonNullAssertExpressionNotEnabled(' '$bang)');
+  }
+
+  void handleNoName(Token token) {
+    doPrint('handleNoName(' '$token)');
+  }
+
+  void beginFunctionType(Token beginToken) {
+    doPrint('beginFunctionType(' '$beginToken)');
+    indent++;
+  }
+
+  void endFunctionType(Token functionToken, Token questionMark) {
+    indent--;
+    doPrint('endFunctionType(' '$functionToken, ' '$questionMark)');
+  }
+
+  void beginTypeArguments(Token token) {
+    doPrint('beginTypeArguments(' '$token)');
+    indent++;
+  }
+
+  void endTypeArguments(int count, Token beginToken, Token endToken) {
+    indent--;
+    doPrint('endTypeArguments(' '$count, ' '$beginToken, ' '$endToken)');
+  }
+
+  void handleInvalidTypeArguments(Token token) {
+    doPrint('handleInvalidTypeArguments(' '$token)');
+  }
+
+  void handleNoTypeArguments(Token token) {
+    doPrint('handleNoTypeArguments(' '$token)');
+  }
+
+  void beginTypeVariable(Token token) {
+    doPrint('beginTypeVariable(' '$token)');
+    indent++;
+  }
+
+  void handleTypeVariablesDefined(Token token, int count) {
+    doPrint('handleTypeVariablesDefined(' '$token, ' '$count)');
+  }
+
+  void endTypeVariable(
+      Token token, int index, Token extendsOrSuper, Token variance) {
+    indent--;
+    doPrint('endTypeVariable('
+        '$token, '
+        '$index, '
+        '$extendsOrSuper, '
+        '$variance)');
+  }
+
+  void beginTypeVariables(Token token) {
+    doPrint('beginTypeVariables(' '$token)');
+    indent++;
+  }
+
+  void endTypeVariables(Token beginToken, Token endToken) {
+    indent--;
+    doPrint('endTypeVariables(' '$beginToken, ' '$endToken)');
+  }
+
+  void handleVarianceModifier(Token variance) {
+    doPrint('handleVarianceModifier(' '$variance)');
+  }
+
+  void reportVarianceModifierNotEnabled(Token variance) {
+    doPrint('reportVarianceModifierNotEnabled(' '$variance)');
+  }
+
+  void beginFunctionExpression(Token token) {
+    doPrint('beginFunctionExpression(' '$token)');
+    indent++;
+  }
+
+  void endFunctionExpression(Token beginToken, Token token) {
+    indent--;
+    doPrint('endFunctionExpression(' '$beginToken, ' '$token)');
+  }
+
+  void beginVariablesDeclaration(
+      Token token, Token lateToken, Token varFinalOrConst) {
+    doPrint('beginVariablesDeclaration('
+        '$token, '
+        '$lateToken, '
+        '$varFinalOrConst)');
+    indent++;
+  }
+
+  void endVariablesDeclaration(int count, Token endToken) {
+    indent--;
+    doPrint('endVariablesDeclaration(' '$count, ' '$endToken)');
+  }
+
+  void beginWhileStatement(Token token) {
+    doPrint('beginWhileStatement(' '$token)');
+    indent++;
+  }
+
+  void endWhileStatement(Token whileKeyword, Token endToken) {
+    indent--;
+    doPrint('endWhileStatement(' '$whileKeyword, ' '$endToken)');
+  }
+
+  void handleAsOperator(Token operator) {
+    doPrint('handleAsOperator(' '$operator)');
+  }
+
+  void handleAssignmentExpression(Token token) {
+    doPrint('handleAssignmentExpression(' '$token)');
+  }
+
+  void beginBinaryExpression(Token token) {
+    doPrint('beginBinaryExpression(' '$token)');
+    indent++;
+  }
+
+  void endBinaryExpression(Token token) {
+    indent--;
+    doPrint('endBinaryExpression(' '$token)');
+  }
+
+  void beginConditionalExpression(Token question) {
+    doPrint('beginConditionalExpression(' '$question)');
+    indent++;
+  }
+
+  void handleConditionalExpressionColon() {
+    doPrint('handleConditionalExpressionColon()');
+  }
+
+  void endConditionalExpression(Token question, Token colon) {
+    indent--;
+    doPrint('endConditionalExpression(' '$question, ' '$colon)');
+  }
+
+  void beginConstExpression(Token constKeyword) {
+    doPrint('beginConstExpression(' '$constKeyword)');
+    indent++;
+  }
+
+  void endConstExpression(Token token) {
+    indent--;
+    doPrint('endConstExpression(' '$token)');
+  }
+
+  void beginForControlFlow(Token awaitToken, Token forToken) {
+    doPrint('beginForControlFlow(' '$awaitToken, ' '$forToken)');
+    indent++;
+  }
+
+  void endForControlFlow(Token token) {
+    indent--;
+    doPrint('endForControlFlow(' '$token)');
+  }
+
+  void endForInControlFlow(Token token) {
+    indent--;
+    doPrint('endForInControlFlow(' '$token)');
+  }
+
+  void beginIfControlFlow(Token ifToken) {
+    doPrint('beginIfControlFlow(' '$ifToken)');
+    indent++;
+  }
+
+  void beginThenControlFlow(Token token) {
+    doPrint('beginThenControlFlow(' '$token)');
+    indent++;
+  }
+
+  void handleElseControlFlow(Token elseToken) {
+    doPrint('handleElseControlFlow(' '$elseToken)');
+  }
+
+  void endIfControlFlow(Token token) {
+    indent--;
+    doPrint('endIfControlFlow(' '$token)');
+  }
+
+  void endIfElseControlFlow(Token token) {
+    indent--;
+    doPrint('endIfElseControlFlow(' '$token)');
+  }
+
+  void handleSpreadExpression(Token spreadToken) {
+    doPrint('handleSpreadExpression(' '$spreadToken)');
+  }
+
+  void beginFunctionTypedFormalParameter(Token token) {
+    doPrint('beginFunctionTypedFormalParameter(' '$token)');
+    indent++;
+  }
+
+  void endFunctionTypedFormalParameter(Token nameToken, Token question) {
+    indent--;
+    doPrint('endFunctionTypedFormalParameter(' '$nameToken, ' '$question)');
+  }
+
+  void handleIdentifier(Token token, IdentifierContext context) {
+    doPrint('handleIdentifier(' '$token, ' '$context)');
+  }
+
+  void handleIndexedExpression(
+      Token openSquareBracket, Token closeSquareBracket) {
+    doPrint('handleIndexedExpression('
+        '$openSquareBracket, '
+        '$closeSquareBracket)');
+  }
+
+  void handleIsOperator(Token isOperator, Token not) {
+    doPrint('handleIsOperator(' '$isOperator, ' '$not)');
+  }
+
+  void handleLiteralBool(Token token) {
+    doPrint('handleLiteralBool(' '$token)');
+  }
+
+  void handleBreakStatement(
+      bool hasTarget, Token breakKeyword, Token endToken) {
+    doPrint(
+        'handleBreakStatement(' '$hasTarget, ' '$breakKeyword, ' '$endToken)');
+  }
+
+  void handleContinueStatement(
+      bool hasTarget, Token continueKeyword, Token endToken) {
+    doPrint('handleContinueStatement('
+        '$hasTarget, '
+        '$continueKeyword, '
+        '$endToken)');
+  }
+
+  void handleEmptyStatement(Token token) {
+    doPrint('handleEmptyStatement(' '$token)');
+  }
+
+  void beginAssert(Token assertKeyword, Assert kind) {
+    doPrint('beginAssert(' '$assertKeyword, ' '$kind)');
+    indent++;
+  }
+
+  void endAssert(Token assertKeyword, Assert kind, Token leftParenthesis,
+      Token commaToken, Token semicolonToken) {
+    indent--;
+    doPrint('endAssert('
+        '$assertKeyword, '
+        '$kind, '
+        '$leftParenthesis, '
+        '$commaToken, '
+        '$semicolonToken)');
+  }
+
+  void handleLiteralDouble(Token token) {
+    doPrint('handleLiteralDouble(' '$token)');
+  }
+
+  void handleLiteralInt(Token token) {
+    doPrint('handleLiteralInt(' '$token)');
+  }
+
+  void handleLiteralList(
+      int count, Token leftBracket, Token constKeyword, Token rightBracket) {
+    doPrint('handleLiteralList('
+        '$count, '
+        '$leftBracket, '
+        '$constKeyword, '
+        '$rightBracket)');
+  }
+
+  void handleLiteralSetOrMap(
+    int count,
+    Token leftBrace,
+    Token constKeyword,
+    Token rightBrace,
+    bool hasSetEntry,
+  ) {
+    doPrint('handleLiteralSetOrMap('
+        '$count, '
+        '$leftBrace, '
+        '$constKeyword, '
+        '$rightBrace, '
+        '$hasSetEntry)');
+  }
+
+  void handleLiteralNull(Token token) {
+    doPrint('handleLiteralNull(' '$token)');
+  }
+
+  void handleNativeClause(Token nativeToken, bool hasName) {
+    doPrint('handleNativeClause(' '$nativeToken, ' '$hasName)');
+  }
+
+  void handleNamedArgument(Token colon) {
+    doPrint('handleNamedArgument(' '$colon)');
+  }
+
+  void beginNewExpression(Token token) {
+    doPrint('beginNewExpression(' '$token)');
+    indent++;
+  }
+
+  void endNewExpression(Token token) {
+    indent--;
+    doPrint('endNewExpression(' '$token)');
+  }
+
+  void handleNoArguments(Token token) {
+    doPrint('handleNoArguments(' '$token)');
+  }
+
+  void handleNoConstructorReferenceContinuationAfterTypeArguments(Token token) {
+    doPrint('handleNoConstructorReferenceContinuationAfterTypeArguments('
+        '$token)');
+  }
+
+  void handleNoType(Token lastConsumed) {
+    doPrint('handleNoType(' '$lastConsumed)');
+  }
+
+  void handleNoTypeVariables(Token token) {
+    doPrint('handleNoTypeVariables(' '$token)');
+  }
+
+  void handleOperator(Token token) {
+    doPrint('handleOperator(' '$token)');
+  }
+
+  void handleSymbolVoid(Token token) {
+    doPrint('handleSymbolVoid(' '$token)');
+  }
+
+  void handleOperatorName(Token operatorKeyword, Token token) {
+    doPrint('handleOperatorName(' '$operatorKeyword, ' '$token)');
+  }
+
+  void handleInvalidOperatorName(Token operatorKeyword, Token token) {
+    doPrint('handleInvalidOperatorName(' '$operatorKeyword, ' '$token)');
+  }
+
+  void handleParenthesizedCondition(Token token) {
+    doPrint('handleParenthesizedCondition(' '$token)');
+  }
+
+  void handleParenthesizedExpression(Token token) {
+    doPrint('handleParenthesizedExpression(' '$token)');
+  }
+
+  void handleQualified(Token period) {
+    doPrint('handleQualified(' '$period)');
+  }
+
+  void handleStringPart(Token token) {
+    doPrint('handleStringPart(' '$token)');
+  }
+
+  void handleSuperExpression(Token token, IdentifierContext context) {
+    doPrint('handleSuperExpression(' '$token, ' '$context)');
+  }
+
+  void beginSwitchCase(int labelCount, int expressionCount, Token firstToken) {
+    doPrint(
+        'beginSwitchCase(' '$labelCount, ' '$expressionCount, ' '$firstToken)');
+    indent++;
+  }
+
+  void endSwitchCase(
+      int labelCount,
+      int expressionCount,
+      Token defaultKeyword,
+      Token colonAfterDefault,
+      int statementCount,
+      Token firstToken,
+      Token endToken) {
+    indent--;
+    doPrint('endSwitchCase('
+        '$labelCount, '
+        '$expressionCount, '
+        '$defaultKeyword, '
+        '$colonAfterDefault, '
+        '$statementCount, '
+        '$firstToken, '
+        '$endToken)');
+  }
+
+  void handleThisExpression(Token token, IdentifierContext context) {
+    doPrint('handleThisExpression(' '$token, ' '$context)');
+  }
+
+  void handleUnaryPostfixAssignmentExpression(Token token) {
+    doPrint('handleUnaryPostfixAssignmentExpression(' '$token)');
+  }
+
+  void handleUnaryPrefixExpression(Token token) {
+    doPrint('handleUnaryPrefixExpression(' '$token)');
+  }
+
+  void handleUnaryPrefixAssignmentExpression(Token token) {
+    doPrint('handleUnaryPrefixAssignmentExpression(' '$token)');
+  }
+
+  void beginFormalParameterDefaultValueExpression() {
+    doPrint('beginFormalParameterDefaultValueExpression()');
+    indent++;
+  }
+
+  void endFormalParameterDefaultValueExpression() {
+    indent--;
+    doPrint('endFormalParameterDefaultValueExpression()');
+  }
+
+  void handleValuedFormalParameter(Token equals, Token token) {
+    doPrint('handleValuedFormalParameter(' '$equals, ' '$token)');
+  }
+
+  void handleFormalParameterWithoutValue(Token token) {
+    doPrint('handleFormalParameterWithoutValue(' '$token)');
+  }
+
+  void handleVoidKeyword(Token token) {
+    doPrint('handleVoidKeyword(' '$token)');
+  }
+
+  void beginYieldStatement(Token token) {
+    doPrint('beginYieldStatement(' '$token)');
+    indent++;
+  }
+
+  void endYieldStatement(Token yieldToken, Token starToken, Token endToken) {
+    indent--;
+    doPrint('endYieldStatement(' '$yieldToken, ' '$starToken, ' '$endToken)');
+  }
+
+  void handleRecoverableError(
+      Message message, Token startToken, Token endToken) {
+    doPrint(
+        'handleRecoverableError(' '$message, ' '$startToken, ' '$endToken)');
+  }
+
+  void handleErrorToken(ErrorToken token) {
+    doPrint('handleErrorToken(' '$token)');
+  }
+
+  void handleUnescapeError(
+      Message message, Token location, int stringOffset, int length) {
+    doPrint('handleUnescapeError('
+        '$message, '
+        '$location, '
+        '$stringOffset, '
+        '$length)');
+  }
+
+  void handleInvalidStatement(Token token, Message message) {
+    doPrint('handleInvalidStatement(' '$token, ' '$message)');
+  }
+
+  void handleScript(Token token) {
+    doPrint('handleScript(' '$token)');
+  }
+
+  void discardTypeReplacedWithCommentTypeAssign() {
+    doPrint('discardTypeReplacedWithCommentTypeAssign()');
+  }
+
+  void handleCommentReferenceText(String referenceSource, int referenceOffset) {
+    doPrint(
+        'handleCommentReferenceText(' '$referenceSource, ' '$referenceOffset)');
+  }
+
+  void handleCommentReference(
+      Token newKeyword, Token prefix, Token period, Token token) {
+    doPrint('handleCommentReference('
+        '$newKeyword, '
+        '$prefix, '
+        '$period, '
+        '$token)');
+  }
+
+  void handleNoCommentReference() {
+    doPrint('handleNoCommentReference()');
+  }
+}
diff --git a/pkg/front_end/test/parser_test_listener_creator.dart b/pkg/front_end/test/parser_test_listener_creator.dart
new file mode 100644
index 0000000..1d625bf
--- /dev/null
+++ b/pkg/front_end/test/parser_test_listener_creator.dart
@@ -0,0 +1,140 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+import 'dart:typed_data';
+
+import 'package:front_end/src/fasta/parser.dart';
+import 'package:front_end/src/fasta/parser/formal_parameter_kind.dart';
+import 'package:front_end/src/fasta/parser/listener.dart';
+import 'package:front_end/src/fasta/parser/member_kind.dart';
+import 'package:front_end/src/fasta/scanner/utf8_bytes_scanner.dart';
+import 'package:front_end/src/scanner/token.dart';
+
+main() {
+  File f = new File.fromUri(
+      Platform.script.resolve("../lib/src/fasta/parser/listener.dart"));
+  List<int> rawBytes = f.readAsBytesSync();
+
+  Uint8List bytes = new Uint8List(rawBytes.length + 1);
+  bytes.setRange(0, rawBytes.length, rawBytes);
+
+  Utf8BytesScanner scanner = new Utf8BytesScanner(bytes, includeComments: true);
+  Token firstToken = scanner.tokenize();
+
+  print("""
+// 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:front_end/src/fasta/messages.dart';
+import 'package:front_end/src/fasta/parser/assert.dart';
+import 'package:front_end/src/fasta/parser/declaration_kind.dart';
+import 'package:front_end/src/fasta/parser/formal_parameter_kind.dart';
+import 'package:front_end/src/fasta/parser/identifier_context.dart';
+import 'package:front_end/src/fasta/parser/listener.dart';
+import 'package:front_end/src/fasta/parser/member_kind.dart';
+import 'package:front_end/src/fasta/scanner/error_token.dart';
+import 'package:front_end/src/scanner/token.dart';
+
+// THIS FILE IS AUTO GENERATED BY 'test/parser_test_listener_creator.dart'
+
+class ParserTestListener implements Listener {
+  int indent = 0;
+  StringBuffer sb = new StringBuffer();
+
+  void doPrint(String s) {
+    sb.writeln(("  " * indent) + s);
+  }
+  """);
+
+  ParserCreatorListener listener = new ParserCreatorListener();
+  ClassMemberParser parser = new ClassMemberParser(listener);
+  parser.parseUnit(firstToken);
+
+  print("""
+  }
+  """);
+}
+
+class ParserCreatorListener extends Listener {
+  bool insideListenerClass = false;
+  String currentMethodName;
+  List<String> parameters = <String>[];
+
+  void beginClassDeclaration(Token begin, Token abstractToken, Token name) {
+    if (name.lexeme == "Listener") insideListenerClass = true;
+  }
+
+  void endClassDeclaration(Token beginToken, Token endToken) {
+    insideListenerClass = false;
+  }
+
+  void beginMethod(Token externalToken, Token staticToken, Token covariantToken,
+      Token varFinalOrConst, Token getOrSet, Token name) {
+    currentMethodName = name.lexeme;
+  }
+
+  void endClassMethod(Token getOrSet, Token beginToken, Token beginParam,
+      Token beginInitializers, Token endToken) {
+    if (insideListenerClass) {
+      Token token = beginToken;
+      Token latestToken;
+      while (true) {
+        if (latestToken != null && latestToken.charEnd < token.charOffset) {
+          stdout.write(" ");
+        }
+        stdout.write(token.lexeme);
+        if ((token is BeginToken &&
+                token.type == TokenType.OPEN_CURLY_BRACKET) ||
+            token is SimpleToken && token.type == TokenType.FUNCTION) {
+          break;
+        }
+        if (token == endToken) {
+          throw token.runtimeType;
+        }
+        latestToken = token;
+        token = token.next;
+      }
+
+      if (token is SimpleToken && token.type == TokenType.FUNCTION) {
+        stdout.write(" null;");
+      } else {
+        stdout.write("\n");
+        if (currentMethodName.startsWith("end")) {
+          stdout.write("indent--;\n");
+        }
+        stdout.write("doPrint('$currentMethodName(");
+        String separator = "";
+        for (int i = 0; i < parameters.length; i++) {
+          stdout.write(separator);
+          stdout.write(r"''$");
+          stdout.write(parameters[i]);
+          separator = ", ";
+        }
+        stdout.write(")');\n");
+
+        if (currentMethodName.startsWith("begin")) {
+          stdout.write("indent++;\n");
+        }
+
+        stdout.write("}");
+      }
+      stdout.write("\n\n");
+    }
+    parameters.clear();
+    currentMethodName = null;
+  }
+
+  void endFormalParameter(
+      Token thisKeyword,
+      Token periodAfterThis,
+      Token nameToken,
+      Token initializerStart,
+      Token initializerEnd,
+      FormalParameterKind kind,
+      MemberKind memberKind) {
+    parameters.add(nameToken.lexeme);
+  }
+}
diff --git a/pkg/front_end/test/spell_checking_list_tests.txt b/pkg/front_end/test/spell_checking_list_tests.txt
index 22cb2ac..e017d56 100644
--- a/pkg/front_end/test/spell_checking_list_tests.txt
+++ b/pkg/front_end/test/spell_checking_list_tests.txt
@@ -22,6 +22,7 @@
 approximation
 asserter
 auth
+auto
 autobianchi
 b0x
 b1x
diff --git a/pkg/front_end/testcases/extensions/check_bounds.dart b/pkg/front_end/testcases/extensions/check_bounds.dart
new file mode 100644
index 0000000..60a157d
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/check_bounds.dart
@@ -0,0 +1,46 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class A {}
+class B extends A {}
+
+class Class<T extends A> {}
+
+extension Extension<T extends B> on Class<T> {
+  method() {}
+  genericMethod<S extends B>(S s) {}
+}
+
+main() {
+
+}
+
+test() {
+  A a;
+
+  Class<A> classA = new Class<A>();
+  classA.method();
+  Extension(classA).method();
+  Extension<A>(classA).method();
+  Extension<B>(classA).method();
+
+  Class<B> classB = new Class<B>();
+  classB.method();
+  Extension(classB).method();
+  Extension<A>(classB).method();
+  Extension<B>(classB).method();
+
+  classB.genericMethod(a);
+  classB.genericMethod<A>(a);
+  classB.genericMethod<B>(a);
+  Extension(classB).genericMethod(a);
+  Extension(classB).genericMethod<A>(a);
+  Extension(classB).genericMethod<B>(a);
+  Extension<A>(classB).genericMethod(a);
+  Extension<A>(classB).genericMethod<A>(a);
+  Extension<A>(classB).genericMethod<B>(a);
+  Extension<B>(classB).genericMethod(a);
+  Extension<B>(classB).genericMethod<A>(a);
+  Extension<B>(classB).genericMethod<B>(a);
+}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/extensions/check_bounds.dart.outline.expect b/pkg/front_end/testcases/extensions/check_bounds.dart.outline.expect
new file mode 100644
index 0000000..f5164e8
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/check_bounds.dart.outline.expect
@@ -0,0 +1,34 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A*
+    ;
+}
+class B extends self::A {
+  synthetic constructor •() → self::B*
+    ;
+}
+class Class<T extends self::A* = self::A*> extends core::Object {
+  synthetic constructor •() → self::Class<self::Class::T*>*
+    ;
+}
+extension Extension<T extends self::B* = dynamic> on self::Class<T*>* {
+  method method = self::Extension|method;
+  tearoff method = self::Extension|get#method;
+  method genericMethod = self::Extension|genericMethod;
+  tearoff genericMethod = self::Extension|get#genericMethod;
+}
+static method Extension|method<T extends self::B* = dynamic>(final self::Class<self::Extension|method::T*>* #this) → dynamic
+  ;
+static method Extension|get#method<T extends self::B* = dynamic>(final self::Class<self::Extension|get#method::T*>* #this) → () →* dynamic
+  return () → dynamic => self::Extension|method<self::Extension|get#method::T*>(#this);
+static method Extension|genericMethod<T extends self::B* = dynamic, S extends self::B* = dynamic>(final self::Class<self::Extension|genericMethod::T*>* #this, self::Extension|genericMethod::S* s) → dynamic
+  ;
+static method Extension|get#genericMethod<T extends self::B* = dynamic>(final self::Class<self::Extension|get#genericMethod::T*>* #this) → <S extends self::B* = dynamic>(S*) →* dynamic
+  return <S extends self::B* = dynamic>(S* s) → dynamic => self::Extension|genericMethod<self::Extension|get#genericMethod::T*, S*>(#this, s);
+static method main() → dynamic
+  ;
+static method test() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/extensions/check_bounds.dart.strong.expect b/pkg/front_end/testcases/extensions/check_bounds.dart.strong.expect
new file mode 100644
index 0000000..b551a0a
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/check_bounds.dart.strong.expect
@@ -0,0 +1,162 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/extensions/check_bounds.dart:23:10: Error: The method 'method' isn't defined for the class 'Class<A>'.
+//  - 'Class' is from 'pkg/front_end/testcases/extensions/check_bounds.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/extensions/check_bounds.dart'.
+// Try correcting the name to the name of an existing method, or defining a method named 'method'.
+//   classA.method();
+//          ^^^^^^
+//
+// pkg/front_end/testcases/extensions/check_bounds.dart:24:3: Error: Inferred type argument 'A' doesn't conform to the bound 'B' of the type variable 'T' on 'Extension|method'.
+//  - 'A' is from 'pkg/front_end/testcases/extensions/check_bounds.dart'.
+//  - 'B' is from 'pkg/front_end/testcases/extensions/check_bounds.dart'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//   Extension(classA).method();
+//   ^
+// pkg/front_end/testcases/extensions/check_bounds.dart:10:21: Context: This is the type variable whose bound isn't conformed to.
+// extension Extension<T extends B> on Class<T> {
+//                     ^
+//
+// pkg/front_end/testcases/extensions/check_bounds.dart:25:3: Error: Inferred type argument 'A' doesn't conform to the bound 'B' of the type variable 'T' on 'Extension|method'.
+//  - 'A' is from 'pkg/front_end/testcases/extensions/check_bounds.dart'.
+//  - 'B' is from 'pkg/front_end/testcases/extensions/check_bounds.dart'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//   Extension<A>(classA).method();
+//   ^
+// pkg/front_end/testcases/extensions/check_bounds.dart:10:21: Context: This is the type variable whose bound isn't conformed to.
+// extension Extension<T extends B> on Class<T> {
+//                     ^
+//
+// pkg/front_end/testcases/extensions/check_bounds.dart:31:3: Error: Inferred type argument 'A' doesn't conform to the bound 'B' of the type variable 'T' on 'Extension|method'.
+//  - 'A' is from 'pkg/front_end/testcases/extensions/check_bounds.dart'.
+//  - 'B' is from 'pkg/front_end/testcases/extensions/check_bounds.dart'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//   Extension<A>(classB).method();
+//   ^
+// pkg/front_end/testcases/extensions/check_bounds.dart:10:21: Context: This is the type variable whose bound isn't conformed to.
+// extension Extension<T extends B> on Class<T> {
+//                     ^
+//
+// pkg/front_end/testcases/extensions/check_bounds.dart:34:10: Error: Type argument 'A' doesn't conform to the bound 'B' of the type variable 'S' on 'Extension|genericMethod'.
+//  - 'A' is from 'pkg/front_end/testcases/extensions/check_bounds.dart'.
+//  - 'B' is from 'pkg/front_end/testcases/extensions/check_bounds.dart'.
+// Try changing type arguments so that they conform to the bounds.
+//   classB.genericMethod(a);
+//          ^
+// pkg/front_end/testcases/extensions/check_bounds.dart:12:17: Context: This is the type variable whose bound isn't conformed to.
+//   genericMethod<S extends B>(S s) {}
+//                 ^
+//
+// pkg/front_end/testcases/extensions/check_bounds.dart:35:10: Error: Type argument 'A' doesn't conform to the bound 'B' of the type variable 'S' on 'Extension|genericMethod'.
+//  - 'A' is from 'pkg/front_end/testcases/extensions/check_bounds.dart'.
+//  - 'B' is from 'pkg/front_end/testcases/extensions/check_bounds.dart'.
+// Try changing type arguments so that they conform to the bounds.
+//   classB.genericMethod<A>(a);
+//          ^
+// pkg/front_end/testcases/extensions/check_bounds.dart:12:17: Context: This is the type variable whose bound isn't conformed to.
+//   genericMethod<S extends B>(S s) {}
+//                 ^
+//
+// pkg/front_end/testcases/extensions/check_bounds.dart:37:3: Error: Inferred type argument 'A' doesn't conform to the bound 'B' of the type variable 'S' on 'Extension|genericMethod'.
+//  - 'A' is from 'pkg/front_end/testcases/extensions/check_bounds.dart'.
+//  - 'B' is from 'pkg/front_end/testcases/extensions/check_bounds.dart'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//   Extension(classB).genericMethod(a);
+//   ^
+// pkg/front_end/testcases/extensions/check_bounds.dart:12:17: Context: This is the type variable whose bound isn't conformed to.
+//   genericMethod<S extends B>(S s) {}
+//                 ^
+//
+// pkg/front_end/testcases/extensions/check_bounds.dart:40:3: Error: Inferred type argument 'A' doesn't conform to the bound 'B' of the type variable 'T' on 'Extension|genericMethod'.
+//  - 'A' is from 'pkg/front_end/testcases/extensions/check_bounds.dart'.
+//  - 'B' is from 'pkg/front_end/testcases/extensions/check_bounds.dart'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//   Extension<A>(classB).genericMethod(a);
+//   ^
+// pkg/front_end/testcases/extensions/check_bounds.dart:10:21: Context: This is the type variable whose bound isn't conformed to.
+// extension Extension<T extends B> on Class<T> {
+//                     ^
+//
+// pkg/front_end/testcases/extensions/check_bounds.dart:40:3: Error: Inferred type argument 'A' doesn't conform to the bound 'B' of the type variable 'S' on 'Extension|genericMethod'.
+//  - 'A' is from 'pkg/front_end/testcases/extensions/check_bounds.dart'.
+//  - 'B' is from 'pkg/front_end/testcases/extensions/check_bounds.dart'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//   Extension<A>(classB).genericMethod(a);
+//   ^
+// pkg/front_end/testcases/extensions/check_bounds.dart:12:17: Context: This is the type variable whose bound isn't conformed to.
+//   genericMethod<S extends B>(S s) {}
+//                 ^
+//
+// pkg/front_end/testcases/extensions/check_bounds.dart:43:3: Error: Inferred type argument 'A' doesn't conform to the bound 'B' of the type variable 'S' on 'Extension|genericMethod'.
+//  - 'A' is from 'pkg/front_end/testcases/extensions/check_bounds.dart'.
+//  - 'B' is from 'pkg/front_end/testcases/extensions/check_bounds.dart'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//   Extension<B>(classB).genericMethod(a);
+//   ^
+// pkg/front_end/testcases/extensions/check_bounds.dart:12:17: Context: This is the type variable whose bound isn't conformed to.
+//   genericMethod<S extends B>(S s) {}
+//                 ^
+//
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A*
+    : super core::Object::•()
+    ;
+}
+class B extends self::A {
+  synthetic constructor •() → self::B*
+    : super self::A::•()
+    ;
+}
+class Class<T extends self::A* = self::A*> extends core::Object {
+  synthetic constructor •() → self::Class<self::Class::T*>*
+    : super core::Object::•()
+    ;
+}
+extension Extension<T extends self::B* = dynamic> on self::Class<T*>* {
+  method method = self::Extension|method;
+  tearoff method = self::Extension|get#method;
+  method genericMethod = self::Extension|genericMethod;
+  tearoff genericMethod = self::Extension|get#genericMethod;
+}
+static method Extension|method<T extends self::B* = dynamic>(final self::Class<self::Extension|method::T*>* #this) → dynamic {}
+static method Extension|get#method<T extends self::B* = dynamic>(final self::Class<self::Extension|get#method::T*>* #this) → () →* dynamic
+  return () → dynamic => self::Extension|method<self::Extension|get#method::T*>(#this);
+static method Extension|genericMethod<T extends self::B* = dynamic, S extends self::B* = dynamic>(final self::Class<self::Extension|genericMethod::T*>* #this, self::Extension|genericMethod::S* s) → dynamic {}
+static method Extension|get#genericMethod<T extends self::B* = dynamic>(final self::Class<self::Extension|get#genericMethod::T*>* #this) → <S extends self::B* = dynamic>(S*) →* dynamic
+  return <S extends self::B* = dynamic>(S* s) → dynamic => self::Extension|genericMethod<self::Extension|get#genericMethod::T*, S*>(#this, s);
+static method main() → dynamic {}
+static method test() → dynamic {
+  self::A* a;
+  self::Class<self::A*>* classA = new self::Class::•<self::A*>();
+  invalid-expression "pkg/front_end/testcases/extensions/check_bounds.dart:23:10: Error: The method 'method' isn't defined for the class 'Class<A>'.
+ - 'Class' is from 'pkg/front_end/testcases/extensions/check_bounds.dart'.
+ - 'A' is from 'pkg/front_end/testcases/extensions/check_bounds.dart'.
+Try correcting the name to the name of an existing method, or defining a method named 'method'.
+  classA.method();
+         ^^^^^^";
+  self::Extension|method<self::A*>(classA);
+  self::Extension|method<self::A*>(classA);
+  self::Extension|method<self::B*>(classA as{TypeError} self::Class<self::B*>*);
+  self::Class<self::B*>* classB = new self::Class::•<self::B*>();
+  self::Extension|method<self::B*>(classB);
+  self::Extension|method<self::B*>(classB);
+  self::Extension|method<self::A*>(classB);
+  self::Extension|method<self::B*>(classB);
+  self::Extension|genericMethod<self::B*, self::A*>(classB, a);
+  self::Extension|genericMethod<self::B*, self::A*>(classB, a);
+  self::Extension|genericMethod<self::B*, self::B*>(classB, a as{TypeError} self::B*);
+  self::Extension|genericMethod<self::B*, self::A*>(classB, a);
+  self::Extension|genericMethod<self::B*, self::A*>(classB, a);
+  self::Extension|genericMethod<self::B*, self::B*>(classB, a as{TypeError} self::B*);
+  self::Extension|genericMethod<self::A*, self::A*>(classB, a);
+  self::Extension|genericMethod<self::A*, self::A*>(classB, a);
+  self::Extension|genericMethod<self::A*, self::B*>(classB, a as{TypeError} self::B*);
+  self::Extension|genericMethod<self::B*, self::A*>(classB, a);
+  self::Extension|genericMethod<self::B*, self::A*>(classB, a);
+  self::Extension|genericMethod<self::B*, self::B*>(classB, a as{TypeError} self::B*);
+}
diff --git a/pkg/front_end/testcases/extensions/check_bounds.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/check_bounds.dart.strong.transformed.expect
new file mode 100644
index 0000000..b551a0a
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/check_bounds.dart.strong.transformed.expect
@@ -0,0 +1,162 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/extensions/check_bounds.dart:23:10: Error: The method 'method' isn't defined for the class 'Class<A>'.
+//  - 'Class' is from 'pkg/front_end/testcases/extensions/check_bounds.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/extensions/check_bounds.dart'.
+// Try correcting the name to the name of an existing method, or defining a method named 'method'.
+//   classA.method();
+//          ^^^^^^
+//
+// pkg/front_end/testcases/extensions/check_bounds.dart:24:3: Error: Inferred type argument 'A' doesn't conform to the bound 'B' of the type variable 'T' on 'Extension|method'.
+//  - 'A' is from 'pkg/front_end/testcases/extensions/check_bounds.dart'.
+//  - 'B' is from 'pkg/front_end/testcases/extensions/check_bounds.dart'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//   Extension(classA).method();
+//   ^
+// pkg/front_end/testcases/extensions/check_bounds.dart:10:21: Context: This is the type variable whose bound isn't conformed to.
+// extension Extension<T extends B> on Class<T> {
+//                     ^
+//
+// pkg/front_end/testcases/extensions/check_bounds.dart:25:3: Error: Inferred type argument 'A' doesn't conform to the bound 'B' of the type variable 'T' on 'Extension|method'.
+//  - 'A' is from 'pkg/front_end/testcases/extensions/check_bounds.dart'.
+//  - 'B' is from 'pkg/front_end/testcases/extensions/check_bounds.dart'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//   Extension<A>(classA).method();
+//   ^
+// pkg/front_end/testcases/extensions/check_bounds.dart:10:21: Context: This is the type variable whose bound isn't conformed to.
+// extension Extension<T extends B> on Class<T> {
+//                     ^
+//
+// pkg/front_end/testcases/extensions/check_bounds.dart:31:3: Error: Inferred type argument 'A' doesn't conform to the bound 'B' of the type variable 'T' on 'Extension|method'.
+//  - 'A' is from 'pkg/front_end/testcases/extensions/check_bounds.dart'.
+//  - 'B' is from 'pkg/front_end/testcases/extensions/check_bounds.dart'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//   Extension<A>(classB).method();
+//   ^
+// pkg/front_end/testcases/extensions/check_bounds.dart:10:21: Context: This is the type variable whose bound isn't conformed to.
+// extension Extension<T extends B> on Class<T> {
+//                     ^
+//
+// pkg/front_end/testcases/extensions/check_bounds.dart:34:10: Error: Type argument 'A' doesn't conform to the bound 'B' of the type variable 'S' on 'Extension|genericMethod'.
+//  - 'A' is from 'pkg/front_end/testcases/extensions/check_bounds.dart'.
+//  - 'B' is from 'pkg/front_end/testcases/extensions/check_bounds.dart'.
+// Try changing type arguments so that they conform to the bounds.
+//   classB.genericMethod(a);
+//          ^
+// pkg/front_end/testcases/extensions/check_bounds.dart:12:17: Context: This is the type variable whose bound isn't conformed to.
+//   genericMethod<S extends B>(S s) {}
+//                 ^
+//
+// pkg/front_end/testcases/extensions/check_bounds.dart:35:10: Error: Type argument 'A' doesn't conform to the bound 'B' of the type variable 'S' on 'Extension|genericMethod'.
+//  - 'A' is from 'pkg/front_end/testcases/extensions/check_bounds.dart'.
+//  - 'B' is from 'pkg/front_end/testcases/extensions/check_bounds.dart'.
+// Try changing type arguments so that they conform to the bounds.
+//   classB.genericMethod<A>(a);
+//          ^
+// pkg/front_end/testcases/extensions/check_bounds.dart:12:17: Context: This is the type variable whose bound isn't conformed to.
+//   genericMethod<S extends B>(S s) {}
+//                 ^
+//
+// pkg/front_end/testcases/extensions/check_bounds.dart:37:3: Error: Inferred type argument 'A' doesn't conform to the bound 'B' of the type variable 'S' on 'Extension|genericMethod'.
+//  - 'A' is from 'pkg/front_end/testcases/extensions/check_bounds.dart'.
+//  - 'B' is from 'pkg/front_end/testcases/extensions/check_bounds.dart'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//   Extension(classB).genericMethod(a);
+//   ^
+// pkg/front_end/testcases/extensions/check_bounds.dart:12:17: Context: This is the type variable whose bound isn't conformed to.
+//   genericMethod<S extends B>(S s) {}
+//                 ^
+//
+// pkg/front_end/testcases/extensions/check_bounds.dart:40:3: Error: Inferred type argument 'A' doesn't conform to the bound 'B' of the type variable 'T' on 'Extension|genericMethod'.
+//  - 'A' is from 'pkg/front_end/testcases/extensions/check_bounds.dart'.
+//  - 'B' is from 'pkg/front_end/testcases/extensions/check_bounds.dart'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//   Extension<A>(classB).genericMethod(a);
+//   ^
+// pkg/front_end/testcases/extensions/check_bounds.dart:10:21: Context: This is the type variable whose bound isn't conformed to.
+// extension Extension<T extends B> on Class<T> {
+//                     ^
+//
+// pkg/front_end/testcases/extensions/check_bounds.dart:40:3: Error: Inferred type argument 'A' doesn't conform to the bound 'B' of the type variable 'S' on 'Extension|genericMethod'.
+//  - 'A' is from 'pkg/front_end/testcases/extensions/check_bounds.dart'.
+//  - 'B' is from 'pkg/front_end/testcases/extensions/check_bounds.dart'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//   Extension<A>(classB).genericMethod(a);
+//   ^
+// pkg/front_end/testcases/extensions/check_bounds.dart:12:17: Context: This is the type variable whose bound isn't conformed to.
+//   genericMethod<S extends B>(S s) {}
+//                 ^
+//
+// pkg/front_end/testcases/extensions/check_bounds.dart:43:3: Error: Inferred type argument 'A' doesn't conform to the bound 'B' of the type variable 'S' on 'Extension|genericMethod'.
+//  - 'A' is from 'pkg/front_end/testcases/extensions/check_bounds.dart'.
+//  - 'B' is from 'pkg/front_end/testcases/extensions/check_bounds.dart'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//   Extension<B>(classB).genericMethod(a);
+//   ^
+// pkg/front_end/testcases/extensions/check_bounds.dart:12:17: Context: This is the type variable whose bound isn't conformed to.
+//   genericMethod<S extends B>(S s) {}
+//                 ^
+//
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A*
+    : super core::Object::•()
+    ;
+}
+class B extends self::A {
+  synthetic constructor •() → self::B*
+    : super self::A::•()
+    ;
+}
+class Class<T extends self::A* = self::A*> extends core::Object {
+  synthetic constructor •() → self::Class<self::Class::T*>*
+    : super core::Object::•()
+    ;
+}
+extension Extension<T extends self::B* = dynamic> on self::Class<T*>* {
+  method method = self::Extension|method;
+  tearoff method = self::Extension|get#method;
+  method genericMethod = self::Extension|genericMethod;
+  tearoff genericMethod = self::Extension|get#genericMethod;
+}
+static method Extension|method<T extends self::B* = dynamic>(final self::Class<self::Extension|method::T*>* #this) → dynamic {}
+static method Extension|get#method<T extends self::B* = dynamic>(final self::Class<self::Extension|get#method::T*>* #this) → () →* dynamic
+  return () → dynamic => self::Extension|method<self::Extension|get#method::T*>(#this);
+static method Extension|genericMethod<T extends self::B* = dynamic, S extends self::B* = dynamic>(final self::Class<self::Extension|genericMethod::T*>* #this, self::Extension|genericMethod::S* s) → dynamic {}
+static method Extension|get#genericMethod<T extends self::B* = dynamic>(final self::Class<self::Extension|get#genericMethod::T*>* #this) → <S extends self::B* = dynamic>(S*) →* dynamic
+  return <S extends self::B* = dynamic>(S* s) → dynamic => self::Extension|genericMethod<self::Extension|get#genericMethod::T*, S*>(#this, s);
+static method main() → dynamic {}
+static method test() → dynamic {
+  self::A* a;
+  self::Class<self::A*>* classA = new self::Class::•<self::A*>();
+  invalid-expression "pkg/front_end/testcases/extensions/check_bounds.dart:23:10: Error: The method 'method' isn't defined for the class 'Class<A>'.
+ - 'Class' is from 'pkg/front_end/testcases/extensions/check_bounds.dart'.
+ - 'A' is from 'pkg/front_end/testcases/extensions/check_bounds.dart'.
+Try correcting the name to the name of an existing method, or defining a method named 'method'.
+  classA.method();
+         ^^^^^^";
+  self::Extension|method<self::A*>(classA);
+  self::Extension|method<self::A*>(classA);
+  self::Extension|method<self::B*>(classA as{TypeError} self::Class<self::B*>*);
+  self::Class<self::B*>* classB = new self::Class::•<self::B*>();
+  self::Extension|method<self::B*>(classB);
+  self::Extension|method<self::B*>(classB);
+  self::Extension|method<self::A*>(classB);
+  self::Extension|method<self::B*>(classB);
+  self::Extension|genericMethod<self::B*, self::A*>(classB, a);
+  self::Extension|genericMethod<self::B*, self::A*>(classB, a);
+  self::Extension|genericMethod<self::B*, self::B*>(classB, a as{TypeError} self::B*);
+  self::Extension|genericMethod<self::B*, self::A*>(classB, a);
+  self::Extension|genericMethod<self::B*, self::A*>(classB, a);
+  self::Extension|genericMethod<self::B*, self::B*>(classB, a as{TypeError} self::B*);
+  self::Extension|genericMethod<self::A*, self::A*>(classB, a);
+  self::Extension|genericMethod<self::A*, self::A*>(classB, a);
+  self::Extension|genericMethod<self::A*, self::B*>(classB, a as{TypeError} self::B*);
+  self::Extension|genericMethod<self::B*, self::A*>(classB, a);
+  self::Extension|genericMethod<self::B*, self::A*>(classB, a);
+  self::Extension|genericMethod<self::B*, self::B*>(classB, a as{TypeError} self::B*);
+}
diff --git a/pkg/front_end/testcases/extensions/extension_call.dart b/pkg/front_end/testcases/extensions/extension_call.dart
new file mode 100644
index 0000000..026883a
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/extension_call.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.
+
+class Class<T> {
+  T method(T a) => a;
+}
+
+extension Extension<T> on Class<T> {
+  T call(T a) => method(a);
+}
+
+main() {
+  Class<int> c = new Class<int>();
+  expect(42, c(42));
+  expect(87, Extension(c)(87));
+  expect(123, Extension<int>(c)(123));
+  expect(42, c.call(42));
+  expect(87, Extension(c).call(87));
+  expect(123, Extension<int>(c).call(123));
+}
+
+expect(expected, actual) {
+  if (expected != actual) {
+    throw 'Mismatch: expected=$expected, actual=$actual';
+  }
+}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/extensions/extension_call.dart.outline.expect b/pkg/front_end/testcases/extensions/extension_call.dart.outline.expect
new file mode 100644
index 0000000..21fa0dd
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/extension_call.dart.outline.expect
@@ -0,0 +1,22 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Class<T extends core::Object* = dynamic> extends core::Object {
+  synthetic constructor •() → self::Class<self::Class::T*>*
+    ;
+  method method(generic-covariant-impl self::Class::T* a) → self::Class::T*
+    ;
+}
+extension Extension<T extends core::Object* = dynamic> on self::Class<T*>* {
+  method call = self::Extension|call;
+  tearoff call = self::Extension|get#call;
+}
+static method Extension|call<T extends core::Object* = dynamic>(final self::Class<self::Extension|call::T*>* #this, self::Extension|call::T* a) → self::Extension|call::T*
+  ;
+static method Extension|get#call<T extends core::Object* = dynamic>(final self::Class<self::Extension|get#call::T*>* #this) → (self::Extension|get#call::T*) →* self::Extension|get#call::T*
+  return (self::Extension|get#call::T* a) → self::Extension|get#call::T* => self::Extension|call<self::Extension|get#call::T*>(#this, a);
+static method main() → dynamic
+  ;
+static method expect(dynamic expected, dynamic actual) → dynamic
+  ;
diff --git a/pkg/front_end/testcases/extensions/extension_call.dart.strong.expect b/pkg/front_end/testcases/extensions/extension_call.dart.strong.expect
new file mode 100644
index 0000000..599862a
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/extension_call.dart.strong.expect
@@ -0,0 +1,33 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Class<T extends core::Object* = dynamic> extends core::Object {
+  synthetic constructor •() → self::Class<self::Class::T*>*
+    : super core::Object::•()
+    ;
+  method method(generic-covariant-impl self::Class::T* a) → self::Class::T*
+    return a;
+}
+extension Extension<T extends core::Object* = dynamic> on self::Class<T*>* {
+  method call = self::Extension|call;
+  tearoff call = self::Extension|get#call;
+}
+static method Extension|call<T extends core::Object* = dynamic>(final self::Class<self::Extension|call::T*>* #this, self::Extension|call::T* a) → self::Extension|call::T*
+  return #this.{self::Class::method}(a);
+static method Extension|get#call<T extends core::Object* = dynamic>(final self::Class<self::Extension|get#call::T*>* #this) → (self::Extension|get#call::T*) →* self::Extension|get#call::T*
+  return (self::Extension|get#call::T* a) → self::Extension|get#call::T* => self::Extension|call<self::Extension|get#call::T*>(#this, a);
+static method main() → dynamic {
+  self::Class<core::int*>* c = new self::Class::•<core::int*>();
+  self::expect(42, self::Extension|call<core::int*>(c, 42));
+  self::expect(87, self::Extension|call<core::int*>(c, 87));
+  self::expect(123, self::Extension|call<core::int*>(c, 123));
+  self::expect(42, self::Extension|call<core::int*>(c, 42));
+  self::expect(87, self::Extension|call<core::int*>(c, 87));
+  self::expect(123, self::Extension|call<core::int*>(c, 123));
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+  if(!expected.{core::Object::==}(actual)) {
+    throw "Mismatch: expected=${expected}, actual=${actual}";
+  }
+}
diff --git a/pkg/front_end/testcases/extensions/extension_call.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/extension_call.dart.strong.transformed.expect
new file mode 100644
index 0000000..599862a
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/extension_call.dart.strong.transformed.expect
@@ -0,0 +1,33 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Class<T extends core::Object* = dynamic> extends core::Object {
+  synthetic constructor •() → self::Class<self::Class::T*>*
+    : super core::Object::•()
+    ;
+  method method(generic-covariant-impl self::Class::T* a) → self::Class::T*
+    return a;
+}
+extension Extension<T extends core::Object* = dynamic> on self::Class<T*>* {
+  method call = self::Extension|call;
+  tearoff call = self::Extension|get#call;
+}
+static method Extension|call<T extends core::Object* = dynamic>(final self::Class<self::Extension|call::T*>* #this, self::Extension|call::T* a) → self::Extension|call::T*
+  return #this.{self::Class::method}(a);
+static method Extension|get#call<T extends core::Object* = dynamic>(final self::Class<self::Extension|get#call::T*>* #this) → (self::Extension|get#call::T*) →* self::Extension|get#call::T*
+  return (self::Extension|get#call::T* a) → self::Extension|get#call::T* => self::Extension|call<self::Extension|get#call::T*>(#this, a);
+static method main() → dynamic {
+  self::Class<core::int*>* c = new self::Class::•<core::int*>();
+  self::expect(42, self::Extension|call<core::int*>(c, 42));
+  self::expect(87, self::Extension|call<core::int*>(c, 87));
+  self::expect(123, self::Extension|call<core::int*>(c, 123));
+  self::expect(42, self::Extension|call<core::int*>(c, 42));
+  self::expect(87, self::Extension|call<core::int*>(c, 87));
+  self::expect(123, self::Extension|call<core::int*>(c, 123));
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+  if(!expected.{core::Object::==}(actual)) {
+    throw "Mismatch: expected=${expected}, actual=${actual}";
+  }
+}
diff --git a/pkg/front_end/testcases/extensions/extension_constructor.dart b/pkg/front_end/testcases/extensions/extension_constructor.dart
new file mode 100644
index 0000000..5cd257d
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/extension_constructor.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class Class {}
+
+extension Extension on Class {
+  Extension() {}
+  Extension.named() {}
+  factory Extension.fact() => null;
+  factory Extension.redirect() = Extension;
+
+  method() {}
+}
+
+main() {}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/extensions/extension_constructor.dart.outline.expect b/pkg/front_end/testcases/extensions/extension_constructor.dart.outline.expect
new file mode 100644
index 0000000..76431a3
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/extension_constructor.dart.outline.expect
@@ -0,0 +1,55 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/extensions/extension_constructor.dart:8:3: Error: Extensions can't declare constructors.
+// Try removing the constructor declaration.
+//   Extension() {}
+//   ^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/extension_constructor.dart:9:3: Error: Extensions can't declare constructors.
+// Try removing the constructor declaration.
+//   Extension.named() {}
+//   ^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/extension_constructor.dart:10:3: Error: Extensions can't declare constructors.
+// Try removing the constructor declaration.
+//   factory Extension.fact() => null;
+//   ^^^^^^^
+//
+// pkg/front_end/testcases/extensions/extension_constructor.dart:11:3: Error: Extensions can't declare constructors.
+// Try removing the constructor declaration.
+//   factory Extension.redirect() = Extension;
+//   ^^^^^^^
+//
+// pkg/front_end/testcases/extensions/extension_constructor.dart:10:11: Error: 'Extension' isn't a type.
+//   factory Extension.fact() => null;
+//           ^^^^^^^^^
+// pkg/front_end/testcases/extensions/extension_constructor.dart:7:11: Context: This isn't a type.
+// extension Extension on Class {
+//           ^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/extension_constructor.dart:11:11: Error: 'Extension' isn't a type.
+//   factory Extension.redirect() = Extension;
+//           ^^^^^^^^^
+// pkg/front_end/testcases/extensions/extension_constructor.dart:7:11: Context: This isn't a type.
+// extension Extension on Class {
+//           ^^^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  synthetic constructor •() → self::Class*
+    ;
+}
+extension Extension on self::Class* {
+  method method = self::Extension|method;
+  tearoff method = self::Extension|get#method;
+}
+static method Extension|method(final self::Class* #this) → dynamic
+  ;
+static method Extension|get#method(final self::Class* #this) → () →* dynamic
+  return () → dynamic => self::Extension|method(#this);
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/extensions/extension_constructor.dart.strong.expect b/pkg/front_end/testcases/extensions/extension_constructor.dart.strong.expect
new file mode 100644
index 0000000..b043e9d
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/extension_constructor.dart.strong.expect
@@ -0,0 +1,54 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/extensions/extension_constructor.dart:8:3: Error: Extensions can't declare constructors.
+// Try removing the constructor declaration.
+//   Extension() {}
+//   ^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/extension_constructor.dart:9:3: Error: Extensions can't declare constructors.
+// Try removing the constructor declaration.
+//   Extension.named() {}
+//   ^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/extension_constructor.dart:10:3: Error: Extensions can't declare constructors.
+// Try removing the constructor declaration.
+//   factory Extension.fact() => null;
+//   ^^^^^^^
+//
+// pkg/front_end/testcases/extensions/extension_constructor.dart:11:3: Error: Extensions can't declare constructors.
+// Try removing the constructor declaration.
+//   factory Extension.redirect() = Extension;
+//   ^^^^^^^
+//
+// pkg/front_end/testcases/extensions/extension_constructor.dart:10:11: Error: 'Extension' isn't a type.
+//   factory Extension.fact() => null;
+//           ^^^^^^^^^
+// pkg/front_end/testcases/extensions/extension_constructor.dart:7:11: Context: This isn't a type.
+// extension Extension on Class {
+//           ^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/extension_constructor.dart:11:11: Error: 'Extension' isn't a type.
+//   factory Extension.redirect() = Extension;
+//           ^^^^^^^^^
+// pkg/front_end/testcases/extensions/extension_constructor.dart:7:11: Context: This isn't a type.
+// extension Extension on Class {
+//           ^^^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  synthetic constructor •() → self::Class*
+    : super core::Object::•()
+    ;
+}
+extension Extension on self::Class* {
+  method method = self::Extension|method;
+  tearoff method = self::Extension|get#method;
+}
+static method Extension|method(final self::Class* #this) → dynamic {}
+static method Extension|get#method(final self::Class* #this) → () →* dynamic
+  return () → dynamic => self::Extension|method(#this);
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/extensions/extension_constructor.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/extension_constructor.dart.strong.transformed.expect
new file mode 100644
index 0000000..b043e9d
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/extension_constructor.dart.strong.transformed.expect
@@ -0,0 +1,54 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/extensions/extension_constructor.dart:8:3: Error: Extensions can't declare constructors.
+// Try removing the constructor declaration.
+//   Extension() {}
+//   ^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/extension_constructor.dart:9:3: Error: Extensions can't declare constructors.
+// Try removing the constructor declaration.
+//   Extension.named() {}
+//   ^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/extension_constructor.dart:10:3: Error: Extensions can't declare constructors.
+// Try removing the constructor declaration.
+//   factory Extension.fact() => null;
+//   ^^^^^^^
+//
+// pkg/front_end/testcases/extensions/extension_constructor.dart:11:3: Error: Extensions can't declare constructors.
+// Try removing the constructor declaration.
+//   factory Extension.redirect() = Extension;
+//   ^^^^^^^
+//
+// pkg/front_end/testcases/extensions/extension_constructor.dart:10:11: Error: 'Extension' isn't a type.
+//   factory Extension.fact() => null;
+//           ^^^^^^^^^
+// pkg/front_end/testcases/extensions/extension_constructor.dart:7:11: Context: This isn't a type.
+// extension Extension on Class {
+//           ^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/extension_constructor.dart:11:11: Error: 'Extension' isn't a type.
+//   factory Extension.redirect() = Extension;
+//           ^^^^^^^^^
+// pkg/front_end/testcases/extensions/extension_constructor.dart:7:11: Context: This isn't a type.
+// extension Extension on Class {
+//           ^^^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  synthetic constructor •() → self::Class*
+    : super core::Object::•()
+    ;
+}
+extension Extension on self::Class* {
+  method method = self::Extension|method;
+  tearoff method = self::Extension|get#method;
+}
+static method Extension|method(final self::Class* #this) → dynamic {}
+static method Extension|get#method(final self::Class* #this) → () →* dynamic
+  return () → dynamic => self::Extension|method(#this);
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/extensions/extension_setter.dart b/pkg/front_end/testcases/extensions/extension_setter.dart
index de0ed9e..79ab6ce 100644
--- a/pkg/front_end/testcases/extensions/extension_setter.dart
+++ b/pkg/front_end/testcases/extensions/extension_setter.dart
@@ -71,6 +71,12 @@
   }
 }
 
+class GenericClass<T> {}
+
+extension GenericExtension<T> on GenericClass<T> {
+  set setter(T value) {}
+}
+
 main() {
   var c = new Class();
   expect(null, c.field);
@@ -191,9 +197,10 @@
 
   new Class().testInternal();
 
+  GenericClass<int> genericClass = new GenericClass<int>();
+  expect(1, GenericExtension(genericClass).setter = 1);
 }
 
-
 expect(expected, actual) {
   if (expected != actual) {
     throw 'Mismatch: expected=$expected, actual=$actual';
diff --git a/pkg/front_end/testcases/extensions/extension_setter.dart.outline.expect b/pkg/front_end/testcases/extensions/extension_setter.dart.outline.expect
index 15b272e..0c3a704 100644
--- a/pkg/front_end/testcases/extensions/extension_setter.dart.outline.expect
+++ b/pkg/front_end/testcases/extensions/extension_setter.dart.outline.expect
@@ -7,6 +7,10 @@
   synthetic constructor •() → self::Class*
     ;
 }
+class GenericClass<T extends core::Object* = dynamic> extends core::Object {
+  synthetic constructor •() → self::GenericClass<self::GenericClass::T*>*
+    ;
+}
 extension Extension on self::Class* {
   get simpleSetter = self::Extension|get#simpleSetter;
   get mutatingSetter = self::Extension|get#mutatingSetter;
@@ -19,6 +23,9 @@
   set setterWithReturn = self::Extension|set#setterWithReturn;
   set setterWithClosure = self::Extension|set#setterWithClosure;
 }
+extension GenericExtension<T extends core::Object* = dynamic> on self::GenericClass<T*>* {
+  set setter = self::GenericExtension|set#setter;
+}
 static method Extension|get#simpleSetter(final self::Class* #this) → core::int*
   ;
 static method Extension|set#simpleSetter(final self::Class* #this, core::int* value) → void
@@ -39,6 +46,8 @@
   ;
 static method Extension|get#testInternal(final self::Class* #this) → () →* dynamic
   return () → dynamic => self::Extension|testInternal(#this);
+static method GenericExtension|set#setter<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|set#setter::T*>* #this, self::GenericExtension|set#setter::T* value) → void
+  ;
 static method main() → dynamic
   ;
 static method expect(dynamic expected, dynamic actual) → dynamic
diff --git a/pkg/front_end/testcases/extensions/extension_setter.dart.strong.expect b/pkg/front_end/testcases/extensions/extension_setter.dart.strong.expect
index f487199..0eb2783 100644
--- a/pkg/front_end/testcases/extensions/extension_setter.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/extension_setter.dart.strong.expect
@@ -8,6 +8,11 @@
     : super core::Object::•()
     ;
 }
+class GenericClass<T extends core::Object* = dynamic> extends core::Object {
+  synthetic constructor •() → self::GenericClass<self::GenericClass::T*>*
+    : super core::Object::•()
+    ;
+}
 extension Extension on self::Class* {
   get simpleSetter = self::Extension|get#simpleSetter;
   get mutatingSetter = self::Extension|get#mutatingSetter;
@@ -20,6 +25,9 @@
   set setterWithReturn = self::Extension|set#setterWithReturn;
   set setterWithClosure = self::Extension|set#setterWithClosure;
 }
+extension GenericExtension<T extends core::Object* = dynamic> on self::GenericClass<T*>* {
+  set setter = self::GenericExtension|set#setter;
+}
 static method Extension|get#simpleSetter(final self::Class* #this) → core::int*
   return #this.{self::Class::field};
 static method Extension|set#simpleSetter(final self::Class* #this, core::int* value) → void {
@@ -76,6 +84,7 @@
 }
 static method Extension|get#testInternal(final self::Class* #this) → () →* dynamic
   return () → dynamic => self::Extension|testInternal(#this);
+static method GenericExtension|set#setter<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|set#setter::T*>* #this, self::GenericExtension|set#setter::T* value) → void {}
 static method main() → dynamic {
   self::Class* c = new self::Class::•();
   self::expect(null, c.{self::Class::field});
@@ -184,6 +193,8 @@
   let final self::Class* #t129 = c in #t129.{core::Object::==}(null) ?{core::Null?} null : #t129.{self::Class::field} = null;
   self::expect(2, let final self::Class* #t130 = c in #t130.{core::Object::==}(null) ?{core::int*} null : let final core::int* #t131 = self::Extension|get#simpleSetter(#t130) in #t131.{core::num::==}(null) ?{core::int*} let final core::int* #t132 = 2 in let final void #t133 = self::Extension|set#simpleSetter(#t130, #t132) in #t132 : #t131);
   self::Extension|testInternal(new self::Class::•());
+  self::GenericClass<core::int*>* genericClass = new self::GenericClass::•<core::int*>();
+  self::expect(1, let final self::GenericClass<core::int*>* #t134 = genericClass in let final core::int* #t135 = 1 in let final void #t136 = self::GenericExtension|set#setter<core::int*>(#t134, #t135) in #t135);
 }
 static method expect(dynamic expected, dynamic actual) → dynamic {
   if(!expected.{core::Object::==}(actual)) {
diff --git a/pkg/front_end/testcases/extensions/extension_setter.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/extension_setter.dart.strong.transformed.expect
index f487199..0eb2783 100644
--- a/pkg/front_end/testcases/extensions/extension_setter.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/extension_setter.dart.strong.transformed.expect
@@ -8,6 +8,11 @@
     : super core::Object::•()
     ;
 }
+class GenericClass<T extends core::Object* = dynamic> extends core::Object {
+  synthetic constructor •() → self::GenericClass<self::GenericClass::T*>*
+    : super core::Object::•()
+    ;
+}
 extension Extension on self::Class* {
   get simpleSetter = self::Extension|get#simpleSetter;
   get mutatingSetter = self::Extension|get#mutatingSetter;
@@ -20,6 +25,9 @@
   set setterWithReturn = self::Extension|set#setterWithReturn;
   set setterWithClosure = self::Extension|set#setterWithClosure;
 }
+extension GenericExtension<T extends core::Object* = dynamic> on self::GenericClass<T*>* {
+  set setter = self::GenericExtension|set#setter;
+}
 static method Extension|get#simpleSetter(final self::Class* #this) → core::int*
   return #this.{self::Class::field};
 static method Extension|set#simpleSetter(final self::Class* #this, core::int* value) → void {
@@ -76,6 +84,7 @@
 }
 static method Extension|get#testInternal(final self::Class* #this) → () →* dynamic
   return () → dynamic => self::Extension|testInternal(#this);
+static method GenericExtension|set#setter<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|set#setter::T*>* #this, self::GenericExtension|set#setter::T* value) → void {}
 static method main() → dynamic {
   self::Class* c = new self::Class::•();
   self::expect(null, c.{self::Class::field});
@@ -184,6 +193,8 @@
   let final self::Class* #t129 = c in #t129.{core::Object::==}(null) ?{core::Null?} null : #t129.{self::Class::field} = null;
   self::expect(2, let final self::Class* #t130 = c in #t130.{core::Object::==}(null) ?{core::int*} null : let final core::int* #t131 = self::Extension|get#simpleSetter(#t130) in #t131.{core::num::==}(null) ?{core::int*} let final core::int* #t132 = 2 in let final void #t133 = self::Extension|set#simpleSetter(#t130, #t132) in #t132 : #t131);
   self::Extension|testInternal(new self::Class::•());
+  self::GenericClass<core::int*>* genericClass = new self::GenericClass::•<core::int*>();
+  self::expect(1, let final self::GenericClass<core::int*>* #t134 = genericClass in let final core::int* #t135 = 1 in let final void #t136 = self::GenericExtension|set#setter<core::int*>(#t134, #t135) in #t135);
 }
 static method expect(dynamic expected, dynamic actual) → dynamic {
   if(!expected.{core::Object::==}(actual)) {
diff --git a/pkg/front_end/testcases/extensions/extension_setter_error.dart b/pkg/front_end/testcases/extensions/extension_setter_error.dart
new file mode 100644
index 0000000..db67de0
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/extension_setter_error.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class GenericClass<T> {}
+
+extension GenericExtension<T> on GenericClass<T> {
+  set setter(T value) {}
+}
+
+error() {
+  GenericClass<int> genericClass = new GenericClass<int>();
+  expect(null, GenericExtension<double>(genericClass).setter = null);
+}
+
+
+expect(expected, actual) {
+  if (expected != actual) {
+    throw 'Mismatch: expected=$expected, actual=$actual';
+  }
+}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/extensions/extension_setter_error.dart.outline.expect b/pkg/front_end/testcases/extensions/extension_setter_error.dart.outline.expect
new file mode 100644
index 0000000..bdf566f
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/extension_setter_error.dart.outline.expect
@@ -0,0 +1,17 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class GenericClass<T extends core::Object* = dynamic> extends core::Object {
+  synthetic constructor •() → self::GenericClass<self::GenericClass::T*>*
+    ;
+}
+extension GenericExtension<T extends core::Object* = dynamic> on self::GenericClass<T*>* {
+  set setter = self::GenericExtension|set#setter;
+}
+static method GenericExtension|set#setter<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|set#setter::T*>* #this, self::GenericExtension|set#setter::T* value) → void
+  ;
+static method error() → dynamic
+  ;
+static method expect(dynamic expected, dynamic actual) → dynamic
+  ;
diff --git a/pkg/front_end/testcases/extensions/extension_setter_error.dart.strong.expect b/pkg/front_end/testcases/extensions/extension_setter_error.dart.strong.expect
new file mode 100644
index 0000000..569b235
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/extension_setter_error.dart.strong.expect
@@ -0,0 +1,35 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/extensions/extension_setter_error.dart:13:41: Error: A value of type 'GenericClass<int>' can't be assigned to a variable of type 'GenericClass<double>'.
+//  - 'GenericClass' is from 'pkg/front_end/testcases/extensions/extension_setter_error.dart'.
+// Try changing the type of the left hand side, or casting the right hand side to 'GenericClass<double>'.
+//   expect(null, GenericExtension<double>(genericClass).setter = null);
+//                                         ^
+//
+import self as self;
+import "dart:core" as core;
+
+class GenericClass<T extends core::Object* = dynamic> extends core::Object {
+  synthetic constructor •() → self::GenericClass<self::GenericClass::T*>*
+    : super core::Object::•()
+    ;
+}
+extension GenericExtension<T extends core::Object* = dynamic> on self::GenericClass<T*>* {
+  set setter = self::GenericExtension|set#setter;
+}
+static method GenericExtension|set#setter<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|set#setter::T*>* #this, self::GenericExtension|set#setter::T* value) → void {}
+static method error() → dynamic {
+  self::GenericClass<core::int*>* genericClass = new self::GenericClass::•<core::int*>();
+  self::expect(null, let final self::GenericClass<core::int*>* #t1 = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/extensions/extension_setter_error.dart:13:41: Error: A value of type 'GenericClass<int>' can't be assigned to a variable of type 'GenericClass<double>'.
+ - 'GenericClass' is from 'pkg/front_end/testcases/extensions/extension_setter_error.dart'.
+Try changing the type of the left hand side, or casting the right hand side to 'GenericClass<double>'.
+  expect(null, GenericExtension<double>(genericClass).setter = null);
+                                        ^" in genericClass as{TypeError} self::GenericClass<core::double*>* in let final core::Null? #t3 = null in let final void #t4 = self::GenericExtension|set#setter<core::double*>(#t1, #t3) in #t3);
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+  if(!expected.{core::Object::==}(actual)) {
+    throw "Mismatch: expected=${expected}, actual=${actual}";
+  }
+}
diff --git a/pkg/front_end/testcases/extensions/index.dart b/pkg/front_end/testcases/extensions/index.dart
index 582d067..0e19617 100644
--- a/pkg/front_end/testcases/extensions/index.dart
+++ b/pkg/front_end/testcases/extensions/index.dart
@@ -15,6 +15,12 @@
 }
 
 main() {
+ implicit();
+ explicitWithTypeArguments();
+ explicitInferredTypeArguments();
+}
+
+implicit() {
   MapLike<int, String> map1 = new MapLike();
   expect(null, map1[0]);
   map1.put(0, '0');
@@ -41,7 +47,64 @@
   expect(6, map2[0]);
   expect(5, --map2[0]);
   expect(5, map2[0]);
+}
 
+explicitWithTypeArguments() {
+  MapLike<int, String> map1 = new MapLike();
+  expect(null, Extension<int, String>(map1)[0]);
+  map1.put(0, '0');
+  expect('0', Extension<int, String>(map1)[0]);
+  expect(null, Extension<int, String>(map1)[1]);
+  Extension<int, String>(map1)[1] = '1';
+  expect('1', Extension<int, String>(map1)[1]);
+  expect('2', Extension<int, String>(map1)[1] = '2');
+  expect('2', Extension<int, String>(map1)[1]);
+  Extension<int, String>(map1)[1] ??= '3';
+  expect('2', Extension<int, String>(map1)[1]);
+  expect('2', Extension<int, String>(map1)[1] ??= '4');
+  expect('2', Extension<int, String>(map1)[1]);
+  Extension<int, String>(map1)[2] ??= '2';
+  expect('2', Extension<int, String>(map1)[2]);
+  expect('3', Extension<int, String>(map1)[3] ??= '3');
+  expect('3', Extension<int, String>(map1)[3]);
+
+  MapLike<int, int> map2 = new MapLike();
+  expect(1, Extension<int, int>(map2)[0] = 1);
+  expect(3, Extension<int, int>(map2)[0] += 2);
+  expect(5, Extension<int, int>(map2)[0] += 2);
+  expect(5, Extension<int, int>(map2)[0]++);
+  expect(6, Extension<int, int>(map2)[0]);
+  expect(5, --Extension<int, int>(map2)[0]);
+  expect(5, Extension<int, int>(map2)[0]);
+}
+
+explicitInferredTypeArguments() {
+  MapLike<int, String> map1 = new MapLike();
+  expect(null, Extension(map1)[0]);
+  map1.put(0, '0');
+  expect('0', Extension(map1)[0]);
+  expect(null, Extension(map1)[1]);
+  Extension(map1)[1] = '1';
+  expect('1', Extension(map1)[1]);
+  expect('2', Extension(map1)[1] = '2');
+  expect('2', Extension(map1)[1]);
+  Extension(map1)[1] ??= '3';
+  expect('2', Extension(map1)[1]);
+  expect('2', Extension(map1)[1] ??= '4');
+  expect('2', Extension(map1)[1]);
+  Extension(map1)[2] ??= '2';
+  expect('2', Extension(map1)[2]);
+  expect('3', Extension(map1)[3] ??= '3');
+  expect('3', Extension(map1)[3]);
+
+  MapLike<int, int> map2 = new MapLike();
+  expect(1, Extension(map2)[0] = 1);
+  expect(3, Extension(map2)[0] += 2);
+  expect(5, Extension(map2)[0] += 2);
+  expect(5, Extension(map2)[0]++);
+  expect(6, Extension(map2)[0]);
+  expect(5, --Extension(map2)[0]);
+  expect(5, Extension(map2)[0]);
 }
 
 expect(expected, actual) {
diff --git a/pkg/front_end/testcases/extensions/index.dart.outline.expect b/pkg/front_end/testcases/extensions/index.dart.outline.expect
index c9b2e9d..f94d2d2 100644
--- a/pkg/front_end/testcases/extensions/index.dart.outline.expect
+++ b/pkg/front_end/testcases/extensions/index.dart.outline.expect
@@ -21,5 +21,11 @@
   ;
 static method main() → dynamic
   ;
+static method implicit() → dynamic
+  ;
+static method explicitWithTypeArguments() → dynamic
+  ;
+static method explicitInferredTypeArguments() → dynamic
+  ;
 static method expect(dynamic expected, dynamic actual) → dynamic
   ;
diff --git a/pkg/front_end/testcases/extensions/index.dart.strong.expect b/pkg/front_end/testcases/extensions/index.dart.strong.expect
index 4f14d3dc..cc8481e 100644
--- a/pkg/front_end/testcases/extensions/index.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/index.dart.strong.expect
@@ -21,6 +21,11 @@
 static method Extension|[]=<K extends core::Object* = dynamic, V extends core::Object* = dynamic>(final self::MapLike<self::Extension|[]=::K*, self::Extension|[]=::V*>* #this, self::Extension|[]=::K* key, self::Extension|[]=::V* value) → void
   return #this.{self::MapLike::put}(key, value);
 static method main() → dynamic {
+  self::implicit();
+  self::explicitWithTypeArguments();
+  self::explicitInferredTypeArguments();
+}
+static method implicit() → dynamic {
   self::MapLike<core::int*, core::String*>* map1 = new self::MapLike::•<core::int*, core::String*>();
   self::expect(null, self::Extension|[]<core::int*, core::String*>(map1, 0));
   map1.{self::MapLike::put}(0, "0");
@@ -47,6 +52,60 @@
   self::expect(5, let final self::MapLike<core::int*, core::int*>* #t39 = map2 in let final core::int* #t40 = 0 in let final core::int* #t41 = self::Extension|[]<core::int*, core::int*>(#t39, #t40).{core::num::-}(1) in let final void #t42 = self::Extension|[]=<core::int*, core::int*>(#t39, #t40, #t41) in #t41);
   self::expect(5, self::Extension|[]<core::int*, core::int*>(map2, 0));
 }
+static method explicitWithTypeArguments() → dynamic {
+  self::MapLike<core::int*, core::String*>* map1 = new self::MapLike::•<core::int*, core::String*>();
+  self::expect(null, self::Extension|[]<core::int*, core::String*>(map1, 0));
+  map1.{self::MapLike::put}(0, "0");
+  self::expect("0", self::Extension|[]<core::int*, core::String*>(map1, 0));
+  self::expect(null, self::Extension|[]<core::int*, core::String*>(map1, 1));
+  self::Extension|[]=<core::int*, core::String*>(map1, 1, "1");
+  self::expect("1", self::Extension|[]<core::int*, core::String*>(map1, 1));
+  self::expect("2", let final self::MapLike<core::int*, core::String*>* #t43 = map1 in let final core::int* #t44 = 1 in let final core::String* #t45 = "2" in let final void #t46 = self::Extension|[]=<core::int*, core::String*>(#t43, #t44, #t45) in #t45);
+  self::expect("2", self::Extension|[]<core::int*, core::String*>(map1, 1));
+  let final self::MapLike<core::int*, core::String*>* #t47 = map1 in let final core::int* #t48 = 1 in self::Extension|[]<core::int*, core::String*>(#t47, #t48).{core::String::==}(null) ?{core::String*} self::Extension|[]=<core::int*, core::String*>(#t47, #t48, "3") : null;
+  self::expect("2", self::Extension|[]<core::int*, core::String*>(map1, 1));
+  self::expect("2", let final self::MapLike<core::int*, core::String*>* #t49 = map1 in let final core::int* #t50 = 1 in let final core::String* #t51 = self::Extension|[]<core::int*, core::String*>(#t49, #t50) in #t51.{core::String::==}(null) ?{core::String*} let final core::String* #t52 = "4" in let final void #t53 = self::Extension|[]=<core::int*, core::String*>(#t49, #t50, #t52) in #t52 : #t51);
+  self::expect("2", self::Extension|[]<core::int*, core::String*>(map1, 1));
+  let final self::MapLike<core::int*, core::String*>* #t54 = map1 in let final core::int* #t55 = 2 in self::Extension|[]<core::int*, core::String*>(#t54, #t55).{core::String::==}(null) ?{core::String*} self::Extension|[]=<core::int*, core::String*>(#t54, #t55, "2") : null;
+  self::expect("2", self::Extension|[]<core::int*, core::String*>(map1, 2));
+  self::expect("3", let final self::MapLike<core::int*, core::String*>* #t56 = map1 in let final core::int* #t57 = 3 in let final core::String* #t58 = self::Extension|[]<core::int*, core::String*>(#t56, #t57) in #t58.{core::String::==}(null) ?{core::String*} let final core::String* #t59 = "3" in let final void #t60 = self::Extension|[]=<core::int*, core::String*>(#t56, #t57, #t59) in #t59 : #t58);
+  self::expect("3", self::Extension|[]<core::int*, core::String*>(map1, 3));
+  self::MapLike<core::int*, core::int*>* map2 = new self::MapLike::•<core::int*, core::int*>();
+  self::expect(1, let final self::MapLike<core::int*, core::int*>* #t61 = map2 in let final core::int* #t62 = 0 in let final core::int* #t63 = 1 in let final void #t64 = self::Extension|[]=<core::int*, core::int*>(#t61, #t62, #t63) in #t63);
+  self::expect(3, let final core::Object* #t65 = map2 in let final core::int* #t66 = 0 in let final core::int* #t67 = self::Extension|[]<core::int*, core::int*>(#t65, #t66).{core::num::+}(2) in let final void #t68 = self::Extension|[]=<core::int*, core::int*>(#t65, #t66, #t67) in #t67);
+  self::expect(5, let final core::Object* #t69 = map2 in let final core::int* #t70 = 0 in let final core::int* #t71 = self::Extension|[]<core::int*, core::int*>(#t69, #t70).{core::num::+}(2) in let final void #t72 = self::Extension|[]=<core::int*, core::int*>(#t69, #t70, #t71) in #t71);
+  self::expect(5, let final core::Object* #t73 = map2 in let final core::int* #t74 = 0 in let final core::int* #t75 = self::Extension|[]<core::int*, core::int*>(#t73, #t74) in let final void #t76 = self::Extension|[]=<core::int*, core::int*>(#t73, #t74, #t75.{core::num::+}(1)) in #t75);
+  self::expect(6, self::Extension|[]<core::int*, core::int*>(map2, 0));
+  self::expect(5, let final core::Object* #t77 = map2 in let final core::int* #t78 = 0 in let final core::int* #t79 = self::Extension|[]<core::int*, core::int*>(#t77, #t78).{core::num::-}(1) in let final void #t80 = self::Extension|[]=<core::int*, core::int*>(#t77, #t78, #t79) in #t79);
+  self::expect(5, self::Extension|[]<core::int*, core::int*>(map2, 0));
+}
+static method explicitInferredTypeArguments() → dynamic {
+  self::MapLike<core::int*, core::String*>* map1 = new self::MapLike::•<core::int*, core::String*>();
+  self::expect(null, self::Extension|[]<core::int*, core::String*>(map1, 0));
+  map1.{self::MapLike::put}(0, "0");
+  self::expect("0", self::Extension|[]<core::int*, core::String*>(map1, 0));
+  self::expect(null, self::Extension|[]<core::int*, core::String*>(map1, 1));
+  self::Extension|[]=<core::int*, core::String*>(map1, 1, "1");
+  self::expect("1", self::Extension|[]<core::int*, core::String*>(map1, 1));
+  self::expect("2", let final self::MapLike<core::int*, core::String*>* #t81 = map1 in let final core::int* #t82 = 1 in let final core::String* #t83 = "2" in let final void #t84 = self::Extension|[]=<core::int*, core::String*>(#t81, #t82, #t83) in #t83);
+  self::expect("2", self::Extension|[]<core::int*, core::String*>(map1, 1));
+  let final self::MapLike<core::int*, core::String*>* #t85 = map1 in let final core::int* #t86 = 1 in self::Extension|[]<core::int*, core::String*>(#t85, #t86).{core::String::==}(null) ?{core::String*} self::Extension|[]=<core::int*, core::String*>(#t85, #t86, "3") : null;
+  self::expect("2", self::Extension|[]<core::int*, core::String*>(map1, 1));
+  self::expect("2", let final self::MapLike<core::int*, core::String*>* #t87 = map1 in let final core::int* #t88 = 1 in let final core::String* #t89 = self::Extension|[]<core::int*, core::String*>(#t87, #t88) in #t89.{core::String::==}(null) ?{core::String*} let final core::String* #t90 = "4" in let final void #t91 = self::Extension|[]=<core::int*, core::String*>(#t87, #t88, #t90) in #t90 : #t89);
+  self::expect("2", self::Extension|[]<core::int*, core::String*>(map1, 1));
+  let final self::MapLike<core::int*, core::String*>* #t92 = map1 in let final core::int* #t93 = 2 in self::Extension|[]<core::int*, core::String*>(#t92, #t93).{core::String::==}(null) ?{core::String*} self::Extension|[]=<core::int*, core::String*>(#t92, #t93, "2") : null;
+  self::expect("2", self::Extension|[]<core::int*, core::String*>(map1, 2));
+  self::expect("3", let final self::MapLike<core::int*, core::String*>* #t94 = map1 in let final core::int* #t95 = 3 in let final core::String* #t96 = self::Extension|[]<core::int*, core::String*>(#t94, #t95) in #t96.{core::String::==}(null) ?{core::String*} let final core::String* #t97 = "3" in let final void #t98 = self::Extension|[]=<core::int*, core::String*>(#t94, #t95, #t97) in #t97 : #t96);
+  self::expect("3", self::Extension|[]<core::int*, core::String*>(map1, 3));
+  self::MapLike<core::int*, core::int*>* map2 = new self::MapLike::•<core::int*, core::int*>();
+  self::expect(1, let final self::MapLike<core::int*, core::int*>* #t99 = map2 in let final core::int* #t100 = 0 in let final core::int* #t101 = 1 in let final void #t102 = self::Extension|[]=<core::int*, core::int*>(#t99, #t100, #t101) in #t101);
+  self::expect(3, let final core::Object* #t103 = map2 in let final core::int* #t104 = 0 in let final core::int* #t105 = self::Extension|[]<core::int*, core::int*>(#t103, #t104).{core::num::+}(2) in let final void #t106 = self::Extension|[]=<core::int*, core::int*>(#t103, #t104, #t105) in #t105);
+  self::expect(5, let final core::Object* #t107 = map2 in let final core::int* #t108 = 0 in let final core::int* #t109 = self::Extension|[]<core::int*, core::int*>(#t107, #t108).{core::num::+}(2) in let final void #t110 = self::Extension|[]=<core::int*, core::int*>(#t107, #t108, #t109) in #t109);
+  self::expect(5, let final core::Object* #t111 = map2 in let final core::int* #t112 = 0 in let final core::int* #t113 = self::Extension|[]<core::int*, core::int*>(#t111, #t112) in let final void #t114 = self::Extension|[]=<core::int*, core::int*>(#t111, #t112, #t113.{core::num::+}(1)) in #t113);
+  self::expect(6, self::Extension|[]<core::int*, core::int*>(map2, 0));
+  self::expect(5, let final core::Object* #t115 = map2 in let final core::int* #t116 = 0 in let final core::int* #t117 = self::Extension|[]<core::int*, core::int*>(#t115, #t116).{core::num::-}(1) in let final void #t118 = self::Extension|[]=<core::int*, core::int*>(#t115, #t116, #t117) in #t117);
+  self::expect(5, self::Extension|[]<core::int*, core::int*>(map2, 0));
+}
 static method expect(dynamic expected, dynamic actual) → dynamic {
   if(!expected.{core::Object::==}(actual)) {
     throw "Mismatch: expected=${expected}, actual=${actual}";
diff --git a/pkg/front_end/testcases/extensions/index.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/index.dart.strong.transformed.expect
index 4f14d3dc..cc8481e 100644
--- a/pkg/front_end/testcases/extensions/index.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/index.dart.strong.transformed.expect
@@ -21,6 +21,11 @@
 static method Extension|[]=<K extends core::Object* = dynamic, V extends core::Object* = dynamic>(final self::MapLike<self::Extension|[]=::K*, self::Extension|[]=::V*>* #this, self::Extension|[]=::K* key, self::Extension|[]=::V* value) → void
   return #this.{self::MapLike::put}(key, value);
 static method main() → dynamic {
+  self::implicit();
+  self::explicitWithTypeArguments();
+  self::explicitInferredTypeArguments();
+}
+static method implicit() → dynamic {
   self::MapLike<core::int*, core::String*>* map1 = new self::MapLike::•<core::int*, core::String*>();
   self::expect(null, self::Extension|[]<core::int*, core::String*>(map1, 0));
   map1.{self::MapLike::put}(0, "0");
@@ -47,6 +52,60 @@
   self::expect(5, let final self::MapLike<core::int*, core::int*>* #t39 = map2 in let final core::int* #t40 = 0 in let final core::int* #t41 = self::Extension|[]<core::int*, core::int*>(#t39, #t40).{core::num::-}(1) in let final void #t42 = self::Extension|[]=<core::int*, core::int*>(#t39, #t40, #t41) in #t41);
   self::expect(5, self::Extension|[]<core::int*, core::int*>(map2, 0));
 }
+static method explicitWithTypeArguments() → dynamic {
+  self::MapLike<core::int*, core::String*>* map1 = new self::MapLike::•<core::int*, core::String*>();
+  self::expect(null, self::Extension|[]<core::int*, core::String*>(map1, 0));
+  map1.{self::MapLike::put}(0, "0");
+  self::expect("0", self::Extension|[]<core::int*, core::String*>(map1, 0));
+  self::expect(null, self::Extension|[]<core::int*, core::String*>(map1, 1));
+  self::Extension|[]=<core::int*, core::String*>(map1, 1, "1");
+  self::expect("1", self::Extension|[]<core::int*, core::String*>(map1, 1));
+  self::expect("2", let final self::MapLike<core::int*, core::String*>* #t43 = map1 in let final core::int* #t44 = 1 in let final core::String* #t45 = "2" in let final void #t46 = self::Extension|[]=<core::int*, core::String*>(#t43, #t44, #t45) in #t45);
+  self::expect("2", self::Extension|[]<core::int*, core::String*>(map1, 1));
+  let final self::MapLike<core::int*, core::String*>* #t47 = map1 in let final core::int* #t48 = 1 in self::Extension|[]<core::int*, core::String*>(#t47, #t48).{core::String::==}(null) ?{core::String*} self::Extension|[]=<core::int*, core::String*>(#t47, #t48, "3") : null;
+  self::expect("2", self::Extension|[]<core::int*, core::String*>(map1, 1));
+  self::expect("2", let final self::MapLike<core::int*, core::String*>* #t49 = map1 in let final core::int* #t50 = 1 in let final core::String* #t51 = self::Extension|[]<core::int*, core::String*>(#t49, #t50) in #t51.{core::String::==}(null) ?{core::String*} let final core::String* #t52 = "4" in let final void #t53 = self::Extension|[]=<core::int*, core::String*>(#t49, #t50, #t52) in #t52 : #t51);
+  self::expect("2", self::Extension|[]<core::int*, core::String*>(map1, 1));
+  let final self::MapLike<core::int*, core::String*>* #t54 = map1 in let final core::int* #t55 = 2 in self::Extension|[]<core::int*, core::String*>(#t54, #t55).{core::String::==}(null) ?{core::String*} self::Extension|[]=<core::int*, core::String*>(#t54, #t55, "2") : null;
+  self::expect("2", self::Extension|[]<core::int*, core::String*>(map1, 2));
+  self::expect("3", let final self::MapLike<core::int*, core::String*>* #t56 = map1 in let final core::int* #t57 = 3 in let final core::String* #t58 = self::Extension|[]<core::int*, core::String*>(#t56, #t57) in #t58.{core::String::==}(null) ?{core::String*} let final core::String* #t59 = "3" in let final void #t60 = self::Extension|[]=<core::int*, core::String*>(#t56, #t57, #t59) in #t59 : #t58);
+  self::expect("3", self::Extension|[]<core::int*, core::String*>(map1, 3));
+  self::MapLike<core::int*, core::int*>* map2 = new self::MapLike::•<core::int*, core::int*>();
+  self::expect(1, let final self::MapLike<core::int*, core::int*>* #t61 = map2 in let final core::int* #t62 = 0 in let final core::int* #t63 = 1 in let final void #t64 = self::Extension|[]=<core::int*, core::int*>(#t61, #t62, #t63) in #t63);
+  self::expect(3, let final core::Object* #t65 = map2 in let final core::int* #t66 = 0 in let final core::int* #t67 = self::Extension|[]<core::int*, core::int*>(#t65, #t66).{core::num::+}(2) in let final void #t68 = self::Extension|[]=<core::int*, core::int*>(#t65, #t66, #t67) in #t67);
+  self::expect(5, let final core::Object* #t69 = map2 in let final core::int* #t70 = 0 in let final core::int* #t71 = self::Extension|[]<core::int*, core::int*>(#t69, #t70).{core::num::+}(2) in let final void #t72 = self::Extension|[]=<core::int*, core::int*>(#t69, #t70, #t71) in #t71);
+  self::expect(5, let final core::Object* #t73 = map2 in let final core::int* #t74 = 0 in let final core::int* #t75 = self::Extension|[]<core::int*, core::int*>(#t73, #t74) in let final void #t76 = self::Extension|[]=<core::int*, core::int*>(#t73, #t74, #t75.{core::num::+}(1)) in #t75);
+  self::expect(6, self::Extension|[]<core::int*, core::int*>(map2, 0));
+  self::expect(5, let final core::Object* #t77 = map2 in let final core::int* #t78 = 0 in let final core::int* #t79 = self::Extension|[]<core::int*, core::int*>(#t77, #t78).{core::num::-}(1) in let final void #t80 = self::Extension|[]=<core::int*, core::int*>(#t77, #t78, #t79) in #t79);
+  self::expect(5, self::Extension|[]<core::int*, core::int*>(map2, 0));
+}
+static method explicitInferredTypeArguments() → dynamic {
+  self::MapLike<core::int*, core::String*>* map1 = new self::MapLike::•<core::int*, core::String*>();
+  self::expect(null, self::Extension|[]<core::int*, core::String*>(map1, 0));
+  map1.{self::MapLike::put}(0, "0");
+  self::expect("0", self::Extension|[]<core::int*, core::String*>(map1, 0));
+  self::expect(null, self::Extension|[]<core::int*, core::String*>(map1, 1));
+  self::Extension|[]=<core::int*, core::String*>(map1, 1, "1");
+  self::expect("1", self::Extension|[]<core::int*, core::String*>(map1, 1));
+  self::expect("2", let final self::MapLike<core::int*, core::String*>* #t81 = map1 in let final core::int* #t82 = 1 in let final core::String* #t83 = "2" in let final void #t84 = self::Extension|[]=<core::int*, core::String*>(#t81, #t82, #t83) in #t83);
+  self::expect("2", self::Extension|[]<core::int*, core::String*>(map1, 1));
+  let final self::MapLike<core::int*, core::String*>* #t85 = map1 in let final core::int* #t86 = 1 in self::Extension|[]<core::int*, core::String*>(#t85, #t86).{core::String::==}(null) ?{core::String*} self::Extension|[]=<core::int*, core::String*>(#t85, #t86, "3") : null;
+  self::expect("2", self::Extension|[]<core::int*, core::String*>(map1, 1));
+  self::expect("2", let final self::MapLike<core::int*, core::String*>* #t87 = map1 in let final core::int* #t88 = 1 in let final core::String* #t89 = self::Extension|[]<core::int*, core::String*>(#t87, #t88) in #t89.{core::String::==}(null) ?{core::String*} let final core::String* #t90 = "4" in let final void #t91 = self::Extension|[]=<core::int*, core::String*>(#t87, #t88, #t90) in #t90 : #t89);
+  self::expect("2", self::Extension|[]<core::int*, core::String*>(map1, 1));
+  let final self::MapLike<core::int*, core::String*>* #t92 = map1 in let final core::int* #t93 = 2 in self::Extension|[]<core::int*, core::String*>(#t92, #t93).{core::String::==}(null) ?{core::String*} self::Extension|[]=<core::int*, core::String*>(#t92, #t93, "2") : null;
+  self::expect("2", self::Extension|[]<core::int*, core::String*>(map1, 2));
+  self::expect("3", let final self::MapLike<core::int*, core::String*>* #t94 = map1 in let final core::int* #t95 = 3 in let final core::String* #t96 = self::Extension|[]<core::int*, core::String*>(#t94, #t95) in #t96.{core::String::==}(null) ?{core::String*} let final core::String* #t97 = "3" in let final void #t98 = self::Extension|[]=<core::int*, core::String*>(#t94, #t95, #t97) in #t97 : #t96);
+  self::expect("3", self::Extension|[]<core::int*, core::String*>(map1, 3));
+  self::MapLike<core::int*, core::int*>* map2 = new self::MapLike::•<core::int*, core::int*>();
+  self::expect(1, let final self::MapLike<core::int*, core::int*>* #t99 = map2 in let final core::int* #t100 = 0 in let final core::int* #t101 = 1 in let final void #t102 = self::Extension|[]=<core::int*, core::int*>(#t99, #t100, #t101) in #t101);
+  self::expect(3, let final core::Object* #t103 = map2 in let final core::int* #t104 = 0 in let final core::int* #t105 = self::Extension|[]<core::int*, core::int*>(#t103, #t104).{core::num::+}(2) in let final void #t106 = self::Extension|[]=<core::int*, core::int*>(#t103, #t104, #t105) in #t105);
+  self::expect(5, let final core::Object* #t107 = map2 in let final core::int* #t108 = 0 in let final core::int* #t109 = self::Extension|[]<core::int*, core::int*>(#t107, #t108).{core::num::+}(2) in let final void #t110 = self::Extension|[]=<core::int*, core::int*>(#t107, #t108, #t109) in #t109);
+  self::expect(5, let final core::Object* #t111 = map2 in let final core::int* #t112 = 0 in let final core::int* #t113 = self::Extension|[]<core::int*, core::int*>(#t111, #t112) in let final void #t114 = self::Extension|[]=<core::int*, core::int*>(#t111, #t112, #t113.{core::num::+}(1)) in #t113);
+  self::expect(6, self::Extension|[]<core::int*, core::int*>(map2, 0));
+  self::expect(5, let final core::Object* #t115 = map2 in let final core::int* #t116 = 0 in let final core::int* #t117 = self::Extension|[]<core::int*, core::int*>(#t115, #t116).{core::num::-}(1) in let final void #t118 = self::Extension|[]=<core::int*, core::int*>(#t115, #t116, #t117) in #t117);
+  self::expect(5, self::Extension|[]<core::int*, core::int*>(map2, 0));
+}
 static method expect(dynamic expected, dynamic actual) → dynamic {
   if(!expected.{core::Object::==}(actual)) {
     throw "Mismatch: expected=${expected}, actual=${actual}";
diff --git a/pkg/front_end/testcases/extensions/invalid_explicit_access.dart.strong.expect b/pkg/front_end/testcases/extensions/invalid_explicit_access.dart.strong.expect
index b24b206..86beef5 100644
--- a/pkg/front_end/testcases/extensions/invalid_explicit_access.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/invalid_explicit_access.dart.strong.expect
@@ -30,9 +30,9 @@
 //   Extension(c1).foo = null;
 //   ^^^
 //
-// pkg/front_end/testcases/extensions/invalid_explicit_access.dart:31:3: Error: Getter not found: 'foo'.
+// pkg/front_end/testcases/extensions/invalid_explicit_access.dart:31:17: Error: Method not found: 'foo'.
 //   Extension(c1).foo();
-//   ^^^
+//                 ^^^
 //
 // pkg/front_end/testcases/extensions/invalid_explicit_access.dart:32:3: Error: Too few positional arguments: 2 required, 1 given.
 //   Extension(c1).method();
@@ -180,9 +180,9 @@
   invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_access.dart:30:3: Error: Setter not found: 'foo'.
   Extension(c1).foo = null;
   ^^^";
-  invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_access.dart:31:3: Error: Getter not found: 'foo'.
+  invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_access.dart:31:17: Error: Method not found: 'foo'.
   Extension(c1).foo();
-  ^^^";
+                ^^^";
   invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_access.dart:32:3: Error: Too few positional arguments: 2 required, 1 given.
   Extension(c1).method();
   ^";
diff --git a/pkg/front_end/testcases/extensions/invalid_explicit_access.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/invalid_explicit_access.dart.strong.transformed.expect
index b24b206..86beef5 100644
--- a/pkg/front_end/testcases/extensions/invalid_explicit_access.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/invalid_explicit_access.dart.strong.transformed.expect
@@ -30,9 +30,9 @@
 //   Extension(c1).foo = null;
 //   ^^^
 //
-// pkg/front_end/testcases/extensions/invalid_explicit_access.dart:31:3: Error: Getter not found: 'foo'.
+// pkg/front_end/testcases/extensions/invalid_explicit_access.dart:31:17: Error: Method not found: 'foo'.
 //   Extension(c1).foo();
-//   ^^^
+//                 ^^^
 //
 // pkg/front_end/testcases/extensions/invalid_explicit_access.dart:32:3: Error: Too few positional arguments: 2 required, 1 given.
 //   Extension(c1).method();
@@ -180,9 +180,9 @@
   invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_access.dart:30:3: Error: Setter not found: 'foo'.
   Extension(c1).foo = null;
   ^^^";
-  invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_access.dart:31:3: Error: Getter not found: 'foo'.
+  invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_access.dart:31:17: Error: Method not found: 'foo'.
   Extension(c1).foo();
-  ^^^";
+                ^^^";
   invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_access.dart:32:3: Error: Too few positional arguments: 2 required, 1 given.
   Extension(c1).method();
   ^";
diff --git a/pkg/front_end/testcases/extensions/tear_offs.dart b/pkg/front_end/testcases/extensions/tear_offs.dart
new file mode 100644
index 0000000..3d7e5a6
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/tear_offs.dart
@@ -0,0 +1,33 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class Class {}
+
+extension Extension on Class {
+  T id<T>(T t) => t;
+
+  T Function<T>(T) get getter => id;
+
+  method() {
+    String Function(String) stringId = id;
+  }
+
+  errors() {
+    int Function(int) intId = getter;
+  }
+}
+
+
+main() {
+  Class c = new Class();
+  int Function(int) intId = c.id;
+  double Function(double) doubleId = Extension(c).id;
+}
+
+errors() {
+  Class c = new Class();
+  num Function(num) numId = c.getter;
+  bool Function(bool) boolId = Extension(c).getter;
+}
+
diff --git a/pkg/front_end/testcases/extensions/tear_offs.dart.outline.expect b/pkg/front_end/testcases/extensions/tear_offs.dart.outline.expect
new file mode 100644
index 0000000..7ad8711
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/tear_offs.dart.outline.expect
@@ -0,0 +1,35 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  synthetic constructor •() → self::Class*
+    ;
+}
+extension Extension on self::Class* {
+  method id = self::Extension|id;
+  tearoff id = self::Extension|get#id;
+  get getter = self::Extension|get#getter;
+  method method = self::Extension|method;
+  tearoff method = self::Extension|get#method;
+  method errors = self::Extension|errors;
+  tearoff errors = self::Extension|get#errors;
+}
+static method Extension|id<T extends core::Object* = dynamic>(final self::Class* #this, self::Extension|id::T* t) → self::Extension|id::T*
+  ;
+static method Extension|get#id(final self::Class* #this) → <T extends core::Object* = dynamic>(T*) →* T*
+  return <T extends core::Object* = dynamic>(T* t) → T* => self::Extension|id<T*>(#this, t);
+static method Extension|get#getter(final self::Class* #this) → <T extends core::Object* = dynamic>(T*) →* T*
+  ;
+static method Extension|method(final self::Class* #this) → dynamic
+  ;
+static method Extension|get#method(final self::Class* #this) → () →* dynamic
+  return () → dynamic => self::Extension|method(#this);
+static method Extension|errors(final self::Class* #this) → dynamic
+  ;
+static method Extension|get#errors(final self::Class* #this) → () →* dynamic
+  return () → dynamic => self::Extension|errors(#this);
+static method main() → dynamic
+  ;
+static method errors() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/extensions/tear_offs.dart.strong.expect b/pkg/front_end/testcases/extensions/tear_offs.dart.strong.expect
new file mode 100644
index 0000000..86c38ea
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/tear_offs.dart.strong.expect
@@ -0,0 +1,71 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/extensions/tear_offs.dart:17:31: Error: A value of type 'T Function<T>(T)' can't be assigned to a variable of type 'int Function(int)'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int Function(int)'.
+//     int Function(int) intId = getter;
+//                               ^
+//
+// pkg/front_end/testcases/extensions/tear_offs.dart:30:31: Error: A value of type 'T Function<T>(T)' can't be assigned to a variable of type 'num Function(num)'.
+// Try changing the type of the left hand side, or casting the right hand side to 'num Function(num)'.
+//   num Function(num) numId = c.getter;
+//                               ^
+//
+// pkg/front_end/testcases/extensions/tear_offs.dart:31:32: Error: A value of type 'T Function<T>(T)' can't be assigned to a variable of type 'bool Function(bool)'.
+// Try changing the type of the left hand side, or casting the right hand side to 'bool Function(bool)'.
+//   bool Function(bool) boolId = Extension(c).getter;
+//                                ^
+//
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  synthetic constructor •() → self::Class*
+    : super core::Object::•()
+    ;
+}
+extension Extension on self::Class* {
+  method id = self::Extension|id;
+  tearoff id = self::Extension|get#id;
+  get getter = self::Extension|get#getter;
+  method method = self::Extension|method;
+  tearoff method = self::Extension|get#method;
+  method errors = self::Extension|errors;
+  tearoff errors = self::Extension|get#errors;
+}
+static method Extension|id<T extends core::Object* = dynamic>(final self::Class* #this, self::Extension|id::T* t) → self::Extension|id::T*
+  return t;
+static method Extension|get#id(final self::Class* #this) → <T extends core::Object* = dynamic>(T*) →* T*
+  return <T extends core::Object* = dynamic>(T* t) → T* => self::Extension|id<T*>(#this, t);
+static method Extension|get#getter(final self::Class* #this) → <T extends core::Object* = dynamic>(T*) →* T*
+  return self::Extension|get#id(#this);
+static method Extension|method(final self::Class* #this) → dynamic {
+  (core::String*) →* core::String* stringId = self::Extension|get#id(#this)<core::String*>;
+}
+static method Extension|get#method(final self::Class* #this) → () →* dynamic
+  return () → dynamic => self::Extension|method(#this);
+static method Extension|errors(final self::Class* #this) → dynamic {
+  (core::int*) →* core::int* intId = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/extensions/tear_offs.dart:17:31: Error: A value of type 'T Function<T>(T)' can't be assigned to a variable of type 'int Function(int)'.
+Try changing the type of the left hand side, or casting the right hand side to 'int Function(int)'.
+    int Function(int) intId = getter;
+                              ^" in self::Extension|get#getter(#this) as{TypeError} (core::int*) →* core::int*;
+}
+static method Extension|get#errors(final self::Class* #this) → () →* dynamic
+  return () → dynamic => self::Extension|errors(#this);
+static method main() → dynamic {
+  self::Class* c = new self::Class::•();
+  (core::int*) →* core::int* intId = self::Extension|get#id(c)<core::int*>;
+  (core::double*) →* core::double* doubleId = self::Extension|get#id(c)<core::double*>;
+}
+static method errors() → dynamic {
+  self::Class* c = new self::Class::•();
+  (core::num*) →* core::num* numId = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/extensions/tear_offs.dart:30:31: Error: A value of type 'T Function<T>(T)' can't be assigned to a variable of type 'num Function(num)'.
+Try changing the type of the left hand side, or casting the right hand side to 'num Function(num)'.
+  num Function(num) numId = c.getter;
+                              ^" in self::Extension|get#getter(c) as{TypeError} (core::num*) →* core::num*;
+  (core::bool*) →* core::bool* boolId = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/extensions/tear_offs.dart:31:32: Error: A value of type 'T Function<T>(T)' can't be assigned to a variable of type 'bool Function(bool)'.
+Try changing the type of the left hand side, or casting the right hand side to 'bool Function(bool)'.
+  bool Function(bool) boolId = Extension(c).getter;
+                               ^" in self::Extension|get#getter(c) as{TypeError} (core::bool*) →* core::bool*;
+}
diff --git a/pkg/front_end/testcases/extensions/tear_offs.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/tear_offs.dart.strong.transformed.expect
new file mode 100644
index 0000000..86c38ea
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/tear_offs.dart.strong.transformed.expect
@@ -0,0 +1,71 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/extensions/tear_offs.dart:17:31: Error: A value of type 'T Function<T>(T)' can't be assigned to a variable of type 'int Function(int)'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int Function(int)'.
+//     int Function(int) intId = getter;
+//                               ^
+//
+// pkg/front_end/testcases/extensions/tear_offs.dart:30:31: Error: A value of type 'T Function<T>(T)' can't be assigned to a variable of type 'num Function(num)'.
+// Try changing the type of the left hand side, or casting the right hand side to 'num Function(num)'.
+//   num Function(num) numId = c.getter;
+//                               ^
+//
+// pkg/front_end/testcases/extensions/tear_offs.dart:31:32: Error: A value of type 'T Function<T>(T)' can't be assigned to a variable of type 'bool Function(bool)'.
+// Try changing the type of the left hand side, or casting the right hand side to 'bool Function(bool)'.
+//   bool Function(bool) boolId = Extension(c).getter;
+//                                ^
+//
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  synthetic constructor •() → self::Class*
+    : super core::Object::•()
+    ;
+}
+extension Extension on self::Class* {
+  method id = self::Extension|id;
+  tearoff id = self::Extension|get#id;
+  get getter = self::Extension|get#getter;
+  method method = self::Extension|method;
+  tearoff method = self::Extension|get#method;
+  method errors = self::Extension|errors;
+  tearoff errors = self::Extension|get#errors;
+}
+static method Extension|id<T extends core::Object* = dynamic>(final self::Class* #this, self::Extension|id::T* t) → self::Extension|id::T*
+  return t;
+static method Extension|get#id(final self::Class* #this) → <T extends core::Object* = dynamic>(T*) →* T*
+  return <T extends core::Object* = dynamic>(T* t) → T* => self::Extension|id<T*>(#this, t);
+static method Extension|get#getter(final self::Class* #this) → <T extends core::Object* = dynamic>(T*) →* T*
+  return self::Extension|get#id(#this);
+static method Extension|method(final self::Class* #this) → dynamic {
+  (core::String*) →* core::String* stringId = self::Extension|get#id(#this)<core::String*>;
+}
+static method Extension|get#method(final self::Class* #this) → () →* dynamic
+  return () → dynamic => self::Extension|method(#this);
+static method Extension|errors(final self::Class* #this) → dynamic {
+  (core::int*) →* core::int* intId = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/extensions/tear_offs.dart:17:31: Error: A value of type 'T Function<T>(T)' can't be assigned to a variable of type 'int Function(int)'.
+Try changing the type of the left hand side, or casting the right hand side to 'int Function(int)'.
+    int Function(int) intId = getter;
+                              ^" in self::Extension|get#getter(#this) as{TypeError} (core::int*) →* core::int*;
+}
+static method Extension|get#errors(final self::Class* #this) → () →* dynamic
+  return () → dynamic => self::Extension|errors(#this);
+static method main() → dynamic {
+  self::Class* c = new self::Class::•();
+  (core::int*) →* core::int* intId = self::Extension|get#id(c)<core::int*>;
+  (core::double*) →* core::double* doubleId = self::Extension|get#id(c)<core::double*>;
+}
+static method errors() → dynamic {
+  self::Class* c = new self::Class::•();
+  (core::num*) →* core::num* numId = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/extensions/tear_offs.dart:30:31: Error: A value of type 'T Function<T>(T)' can't be assigned to a variable of type 'num Function(num)'.
+Try changing the type of the left hand side, or casting the right hand side to 'num Function(num)'.
+  num Function(num) numId = c.getter;
+                              ^" in self::Extension|get#getter(c) as{TypeError} (core::num*) →* core::num*;
+  (core::bool*) →* core::bool* boolId = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/extensions/tear_offs.dart:31:32: Error: A value of type 'T Function<T>(T)' can't be assigned to a variable of type 'bool Function(bool)'.
+Try changing the type of the left hand side, or casting the right hand side to 'bool Function(bool)'.
+  bool Function(bool) boolId = Extension(c).getter;
+                               ^" in self::Extension|get#getter(c) as{TypeError} (core::bool*) →* core::bool*;
+}
diff --git a/pkg/front_end/testcases/general/magic_const.dart.strong.expect b/pkg/front_end/testcases/general/magic_const.dart.strong.expect
index de74647..7f979c6 100644
--- a/pkg/front_end/testcases/general/magic_const.dart.strong.expect
+++ b/pkg/front_end/testcases/general/magic_const.dart.strong.expect
@@ -1,16 +1,3 @@
-//
-// Problems in component:
-//
-// pkg/front_end/testcases/general/magic_const.dart:15:39: Error: Constant evaluation error:
-// foo({a: Constant(), b: Constant(), c: []}) {}
-//                                       ^
-// pkg/front_end/testcases/general/magic_const.dart:15:39: Context: Can't have a non-constant List literal within a const context.
-// foo({a: Constant(), b: Constant(), c: []}) {}
-//                                       ^
-// pkg/front_end/testcases/general/magic_const.dart:15:36: Context: While analyzing:
-// foo({a: Constant(), b: Constant(), c: []}) {}
-//                                    ^
-//
 library;
 //
 // Problems in library:
@@ -48,7 +35,7 @@
     : super core::Object::•()
     ;
 }
-static method foo({dynamic a = #C1, dynamic b = #C1, dynamic c = invalid-expression "Can't have a non-constant List literal within a const context."}) → dynamic {}
+static method foo({dynamic a = #C1, dynamic b = #C1, dynamic c = invalid-expression "Non-constant list literal"}) → dynamic {}
 static method test() → dynamic {
   invalid-expression "pkg/front_end/testcases/general/magic_const.dart:18:9: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
 Try using a constructor or factory that is 'const'.
diff --git a/pkg/front_end/testcases/general/magic_const.dart.strong.transformed.expect b/pkg/front_end/testcases/general/magic_const.dart.strong.transformed.expect
index de74647..7f979c6 100644
--- a/pkg/front_end/testcases/general/magic_const.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/magic_const.dart.strong.transformed.expect
@@ -1,16 +1,3 @@
-//
-// Problems in component:
-//
-// pkg/front_end/testcases/general/magic_const.dart:15:39: Error: Constant evaluation error:
-// foo({a: Constant(), b: Constant(), c: []}) {}
-//                                       ^
-// pkg/front_end/testcases/general/magic_const.dart:15:39: Context: Can't have a non-constant List literal within a const context.
-// foo({a: Constant(), b: Constant(), c: []}) {}
-//                                       ^
-// pkg/front_end/testcases/general/magic_const.dart:15:36: Context: While analyzing:
-// foo({a: Constant(), b: Constant(), c: []}) {}
-//                                    ^
-//
 library;
 //
 // Problems in library:
@@ -48,7 +35,7 @@
     : super core::Object::•()
     ;
 }
-static method foo({dynamic a = #C1, dynamic b = #C1, dynamic c = invalid-expression "Can't have a non-constant List literal within a const context."}) → dynamic {}
+static method foo({dynamic a = #C1, dynamic b = #C1, dynamic c = invalid-expression "Non-constant list literal"}) → dynamic {}
 static method test() → dynamic {
   invalid-expression "pkg/front_end/testcases/general/magic_const.dart:18:9: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
 Try using a constructor or factory that is 'const'.
diff --git a/pkg/front_end/testcases/inference/unresolved_super.dart.strong.expect b/pkg/front_end/testcases/inference/unresolved_super.dart.strong.expect
index d7d9a11..1f4d51b 100644
--- a/pkg/front_end/testcases/inference/unresolved_super.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/unresolved_super.dart.strong.expect
@@ -4,7 +4,7 @@
 //
 // pkg/front_end/testcases/inference/unresolved_super.dart:16:37: Error: Superclass has no method named '[]='.
 //     var /*@type=dynamic*/ v5 = super[0] = /*@typeArgs=dynamic*/ f();
-//                                     ^^^
+//                                     ^
 //
 import self as self;
 import "dart:core" as core;
@@ -16,7 +16,7 @@
   method test() → void {
     dynamic v5 = let final core::int* #t1 = 0 in let final dynamic #t2 = self::f<dynamic>() in let final void #t3 = invalid-expression "pkg/front_end/testcases/inference/unresolved_super.dart:16:37: Error: Superclass has no method named '[]='.
     var /*@type=dynamic*/ v5 = super[0] = /*@typeArgs=dynamic*/ f();
-                                    ^^^" in #t2;
+                                    ^" in #t2;
   }
 }
 static method f<T extends core::Object* = dynamic>() → self::f::T*
diff --git a/pkg/front_end/testcases/inference/unresolved_super.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/unresolved_super.dart.strong.transformed.expect
index d7d9a11..1f4d51b 100644
--- a/pkg/front_end/testcases/inference/unresolved_super.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/unresolved_super.dart.strong.transformed.expect
@@ -4,7 +4,7 @@
 //
 // pkg/front_end/testcases/inference/unresolved_super.dart:16:37: Error: Superclass has no method named '[]='.
 //     var /*@type=dynamic*/ v5 = super[0] = /*@typeArgs=dynamic*/ f();
-//                                     ^^^
+//                                     ^
 //
 import self as self;
 import "dart:core" as core;
@@ -16,7 +16,7 @@
   method test() → void {
     dynamic v5 = let final core::int* #t1 = 0 in let final dynamic #t2 = self::f<dynamic>() in let final void #t3 = invalid-expression "pkg/front_end/testcases/inference/unresolved_super.dart:16:37: Error: Superclass has no method named '[]='.
     var /*@type=dynamic*/ v5 = super[0] = /*@typeArgs=dynamic*/ f();
-                                    ^^^" in #t2;
+                                    ^" in #t2;
   }
 }
 static method f<T extends core::Object* = dynamic>() → self::f::T*
diff --git a/pkg/front_end/testcases/old_dills/dart2js.version.34.compile.1.dill b/pkg/front_end/testcases/old_dills/dart2js.version.34.compile.1.dill
new file mode 100644
index 0000000..6af2b34
--- /dev/null
+++ b/pkg/front_end/testcases/old_dills/dart2js.version.34.compile.1.dill
Binary files differ
diff --git a/pkg/front_end/testcases/rasta/mandatory_parameter_initializer.dart.strong.expect b/pkg/front_end/testcases/rasta/mandatory_parameter_initializer.dart.strong.expect
index 9096c74..9989711 100644
--- a/pkg/front_end/testcases/rasta/mandatory_parameter_initializer.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/mandatory_parameter_initializer.dart.strong.expect
@@ -1,16 +1,3 @@
-//
-// Problems in component:
-//
-// pkg/front_end/testcases/rasta/mandatory_parameter_initializer.dart:5:18: Error: Constant evaluation error:
-// main(arguments = [x]) {
-//                  ^
-// pkg/front_end/testcases/rasta/mandatory_parameter_initializer.dart:5:18: Context: Can't have a non-constant List literal within a const context.
-// main(arguments = [x]) {
-//                  ^
-// pkg/front_end/testcases/rasta/mandatory_parameter_initializer.dart:5:6: Context: While analyzing:
-// main(arguments = [x]) {
-//      ^
-//
 library;
 //
 // Problems in library:
@@ -31,4 +18,4 @@
 //
 import self as self;
 
-static method main(dynamic arguments = invalid-expression "Can't have a non-constant List literal within a const context.") → dynamic {}
+static method main(dynamic arguments = invalid-expression "Non-constant list literal") → dynamic {}
diff --git a/pkg/front_end/testcases/rasta/mandatory_parameter_initializer.dart.strong.transformed.expect b/pkg/front_end/testcases/rasta/mandatory_parameter_initializer.dart.strong.transformed.expect
index 9096c74..9989711 100644
--- a/pkg/front_end/testcases/rasta/mandatory_parameter_initializer.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/rasta/mandatory_parameter_initializer.dart.strong.transformed.expect
@@ -1,16 +1,3 @@
-//
-// Problems in component:
-//
-// pkg/front_end/testcases/rasta/mandatory_parameter_initializer.dart:5:18: Error: Constant evaluation error:
-// main(arguments = [x]) {
-//                  ^
-// pkg/front_end/testcases/rasta/mandatory_parameter_initializer.dart:5:18: Context: Can't have a non-constant List literal within a const context.
-// main(arguments = [x]) {
-//                  ^
-// pkg/front_end/testcases/rasta/mandatory_parameter_initializer.dart:5:6: Context: While analyzing:
-// main(arguments = [x]) {
-//      ^
-//
 library;
 //
 // Problems in library:
@@ -31,4 +18,4 @@
 //
 import self as self;
 
-static method main(dynamic arguments = invalid-expression "Can't have a non-constant List literal within a const context.") → dynamic {}
+static method main(dynamic arguments = invalid-expression "Non-constant list literal") → dynamic {}
diff --git a/pkg/front_end/testcases/strong.status b/pkg/front_end/testcases/strong.status
index 91148be..e02ba42 100644
--- a/pkg/front_end/testcases/strong.status
+++ b/pkg/front_end/testcases/strong.status
@@ -6,6 +6,7 @@
 # Kernel ASTs directly, that is, code in pkg/fasta/lib/src/kernel/ with
 # strong-mode enabled.
 
+extensions/extension_setter_error: TypeCheckError
 extensions/instance_access_of_static: RuntimeError
 extensions/invalid_explicit_access: RuntimeError
 extensions/static_access_of_instance: RuntimeError
diff --git a/pkg/front_end/testcases/text_serialization.status b/pkg/front_end/testcases/text_serialization.status
index 95610cc..6bafcf8 100644
--- a/pkg/front_end/testcases/text_serialization.status
+++ b/pkg/front_end/testcases/text_serialization.status
@@ -10,6 +10,7 @@
 expression/eval: TextSerializationFailure # Was: Pass
 expression/main: TextSerializationFailure # Was: Pass
 extensions/annotations: TextSerializationFailure
+extensions/check_bounds: TextSerializationFailure
 extensions/compounds: TextSerializationFailure
 extensions/conflicts: TextSerializationFailure
 extensions/default_values: TextSerializationFailure
@@ -21,8 +22,11 @@
 extensions/explicit_generic_extension_access: TextSerializationFailure
 extensions/explicit_invalid_access: TextSerializationFailure
 extensions/explicit_this: TextSerializationFailure
+extensions/extension_call: TextSerializationFailure
+extensions/extension_constructor: TextSerializationFailure
 extensions/extension_methods: TextSerializationFailure
 extensions/extension_setter: TextSerializationFailure
+extensions/extension_setter_error: TypeCheckError
 extensions/getter_setter_conflict: TextSerializationFailure
 extensions/if_null: TextSerializationFailure
 extensions/implicit_extension_inference: TextSerializationFailure
@@ -43,6 +47,7 @@
 extensions/other_kinds: TextSerializationFailure
 extensions/static_access: TextSerializationFailure
 extensions/static_access_of_instance: TextSerializationFailure
+extensions/tear_offs: TextSerializationFailure
 extensions/type_variables: TextSerializationFailure
 extensions/unnamed_extensions: TextSerializationFailure
 extensions/use_this: TextSerializationFailure
@@ -1113,4 +1118,6 @@
 runtime_checks_new/stub_from_interface_covariant_from_interface: TextSerializationFailure # Was: Pass
 runtime_checks_new/stub_from_interface_covariant_from_super: TextSerializationFailure # Was: Pass
 set_literals/disambiguation_rule: TextSerializationFailure # Was: RuntimeError
+variance/class_type_parameter_modifier: TextSerializationFailure
+variance/mixin_type_parameter_modifier: TextSerializationFailure
 top_level_variance_test: TextSerializationFailure
diff --git a/pkg/front_end/testcases/variance/class_type_parameter_modifier.dart b/pkg/front_end/testcases/variance/class_type_parameter_modifier.dart
new file mode 100644
index 0000000..71aa5cf
--- /dev/null
+++ b/pkg/front_end/testcases/variance/class_type_parameter_modifier.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<out X, in Y, inout Z> {}
+
+main() {
+  A a = new A();
+}
diff --git a/pkg/front_end/testcases/variance/class_type_parameter_modifier.dart.outline.expect b/pkg/front_end/testcases/variance/class_type_parameter_modifier.dart.outline.expect
new file mode 100644
index 0000000..05b61d8
--- /dev/null
+++ b/pkg/front_end/testcases/variance/class_type_parameter_modifier.dart.outline.expect
@@ -0,0 +1,10 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A<X extends core::Object* = dynamic, contravariant Y extends core::Object* = dynamic, invariant Z extends core::Object* = dynamic> extends core::Object {
+  synthetic constructor •() → self::A<self::A::X*, self::A::Y*, self::A::Z*>*
+    ;
+}
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/variance/class_type_parameter_modifier.dart.strong.expect b/pkg/front_end/testcases/variance/class_type_parameter_modifier.dart.strong.expect
new file mode 100644
index 0000000..cb21b6a
--- /dev/null
+++ b/pkg/front_end/testcases/variance/class_type_parameter_modifier.dart.strong.expect
@@ -0,0 +1,12 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A<X extends core::Object* = dynamic, contravariant Y extends core::Object* = dynamic, invariant Z extends core::Object* = dynamic> extends core::Object {
+  synthetic constructor •() → self::A<self::A::X*, self::A::Y*, self::A::Z*>*
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {
+  self::A<dynamic, dynamic, dynamic>* a = new self::A::•<dynamic, dynamic, dynamic>();
+}
diff --git a/pkg/front_end/testcases/variance/class_type_parameter_modifier.dart.strong.transformed.expect b/pkg/front_end/testcases/variance/class_type_parameter_modifier.dart.strong.transformed.expect
new file mode 100644
index 0000000..cb21b6a
--- /dev/null
+++ b/pkg/front_end/testcases/variance/class_type_parameter_modifier.dart.strong.transformed.expect
@@ -0,0 +1,12 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A<X extends core::Object* = dynamic, contravariant Y extends core::Object* = dynamic, invariant Z extends core::Object* = dynamic> extends core::Object {
+  synthetic constructor •() → self::A<self::A::X*, self::A::Y*, self::A::Z*>*
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {
+  self::A<dynamic, dynamic, dynamic>* a = new self::A::•<dynamic, dynamic, dynamic>();
+}
diff --git a/pkg/front_end/testcases/variance/mixin_type_parameter_modifier.dart b/pkg/front_end/testcases/variance/mixin_type_parameter_modifier.dart
new file mode 100644
index 0000000..2aefefb
--- /dev/null
+++ b/pkg/front_end/testcases/variance/mixin_type_parameter_modifier.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 {}
+
+mixin B<inout X, out Y, in Z> on A {}
+
+main() {}
diff --git a/pkg/front_end/testcases/variance/mixin_type_parameter_modifier.dart.outline.expect b/pkg/front_end/testcases/variance/mixin_type_parameter_modifier.dart.outline.expect
new file mode 100644
index 0000000..44fe61a
--- /dev/null
+++ b/pkg/front_end/testcases/variance/mixin_type_parameter_modifier.dart.outline.expect
@@ -0,0 +1,12 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A*
+    ;
+}
+abstract class B<invariant X extends core::Object* = dynamic, Y extends core::Object* = dynamic, contravariant Z extends core::Object* = dynamic> extends self::A {
+}
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/variance/mixin_type_parameter_modifier.dart.strong.expect b/pkg/front_end/testcases/variance/mixin_type_parameter_modifier.dart.strong.expect
new file mode 100644
index 0000000..0c6c3cdf
--- /dev/null
+++ b/pkg/front_end/testcases/variance/mixin_type_parameter_modifier.dart.strong.expect
@@ -0,0 +1,12 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A*
+    : super core::Object::•()
+    ;
+}
+abstract class B<invariant X extends core::Object* = dynamic, Y extends core::Object* = dynamic, contravariant Z extends core::Object* = dynamic> extends self::A {
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/variance/mixin_type_parameter_modifier.dart.strong.transformed.expect b/pkg/front_end/testcases/variance/mixin_type_parameter_modifier.dart.strong.transformed.expect
new file mode 100644
index 0000000..0c6c3cdf
--- /dev/null
+++ b/pkg/front_end/testcases/variance/mixin_type_parameter_modifier.dart.strong.transformed.expect
@@ -0,0 +1,12 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A*
+    : super core::Object::•()
+    ;
+}
+abstract class B<invariant X extends core::Object* = dynamic, Y extends core::Object* = dynamic, contravariant Z extends core::Object* = dynamic> extends self::A {
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/variance/test.options b/pkg/front_end/testcases/variance/test.options
new file mode 100644
index 0000000..3ce5008
--- /dev/null
+++ b/pkg/front_end/testcases/variance/test.options
@@ -0,0 +1 @@
+--enable-experiment=variance
diff --git a/pkg/front_end/testing.json b/pkg/front_end/testing.json
index 2c8c9b8..5262250 100644
--- a/pkg/front_end/testing.json
+++ b/pkg/front_end/testing.json
@@ -177,6 +177,17 @@
       "exclude": []
     },
     {
+      "name": "parser_test",
+      "kind": "Chain",
+      "source": "test/parser_test.dart",
+      "path": "parser_testcases/",
+      "status": "parser_testcases/parser.status",
+      "pattern": [
+        "\\.dart$"
+      ],
+      "exclude": []
+    },
+    {
       "name": "lint_test",
       "kind": "Chain",
       "source": "test/lint_test.dart",
diff --git a/pkg/kernel/binary.md b/pkg/kernel/binary.md
index 5152615..d8a353e 100644
--- a/pkg/kernel/binary.md
+++ b/pkg/kernel/binary.md
@@ -143,7 +143,7 @@
 
 type ComponentFile {
   UInt32 magic = 0x90ABCDEF;
-  UInt32 formatVersion = 33;
+  UInt32 formatVersion = 34;
   List<String> problemsAsJson; // Described in problems.md.
   Library[] libraries;
   UriSource sourceMap;
@@ -1236,6 +1236,8 @@
 
 enum Nullability { nullable = 0, nonNullable = 1, neither = 2, legacy = 3, }
 
+enum Variance { unrelated = 0, covariant = 1, contravariant = 2, invariant = 3, }
+
 abstract type DartType extends Node {}
 
 type BottomType extends DartType {
@@ -1332,6 +1334,7 @@
   // Note: there is no tag on TypeParameter
   Byte flags (isGenericCovariantImpl);
   List<Expression> annotations;
+  Byte variance; // Index into the Variance enum above
   StringReference name; // Cosmetic, may be empty, not unique.
   DartType bound; // 'dynamic' if no explicit bound was given.
   Option<DartType> defaultType; // type used when the parameter is not passed
diff --git a/pkg/kernel/lib/ast.dart b/pkg/kernel/lib/ast.dart
index 1f1835c..cd777e3 100644
--- a/pkg/kernel/lib/ast.dart
+++ b/pkg/kernel/lib/ast.dart
@@ -6003,6 +6003,18 @@
     if (a == invariant || b == invariant) return invariant;
     return a == b ? covariant : contravariant;
   }
+
+  static int fromString(String variance) {
+    if (variance == "in") {
+      return contravariant;
+    } else if (variance == "inout") {
+      return invariant;
+    } else if (variance == "out") {
+      return covariant;
+    } else {
+      return unrelated;
+    }
+  }
 }
 
 /// Declaration of a type variable.
diff --git a/pkg/kernel/lib/binary/ast_from_binary.dart b/pkg/kernel/lib/binary/ast_from_binary.dart
index f8585a5..f717ce2 100644
--- a/pkg/kernel/lib/binary/ast_from_binary.dart
+++ b/pkg/kernel/lib/binary/ast_from_binary.dart
@@ -2184,10 +2184,10 @@
   void readTypeParameter(TypeParameter node) {
     node.flags = readByte();
     node.annotations = readAnnotationList(node);
+    node.variance = readByte();
     node.name = readStringOrNullIfEmpty();
     node.bound = readDartType();
     node.defaultType = readDartTypeOption();
-    node.variance = Variance.covariant;
   }
 
   Arguments readArguments() {
diff --git a/pkg/kernel/lib/binary/ast_to_binary.dart b/pkg/kernel/lib/binary/ast_to_binary.dart
index 9e34e8c..8abfe1b 100644
--- a/pkg/kernel/lib/binary/ast_to_binary.dart
+++ b/pkg/kernel/lib/binary/ast_to_binary.dart
@@ -2121,6 +2121,7 @@
   void visitTypeParameter(TypeParameter node) {
     writeByte(node.flags);
     writeAnnotationList(node.annotations);
+    writeByte(node.variance);
     writeStringReference(node.name ?? '');
     writeNode(node.bound);
     writeOptionalNode(node.defaultType);
diff --git a/pkg/kernel/lib/binary/tag.dart b/pkg/kernel/lib/binary/tag.dart
index 33091c0..1768aae 100644
--- a/pkg/kernel/lib/binary/tag.dart
+++ b/pkg/kernel/lib/binary/tag.dart
@@ -148,7 +148,7 @@
   /// Internal version of kernel binary format.
   /// Bump it when making incompatible changes in kernel binaries.
   /// Keep in sync with runtime/vm/kernel_binary.h, pkg/kernel/binary.md.
-  static const int BinaryFormatVersion = 33;
+  static const int BinaryFormatVersion = 34;
 }
 
 abstract class ConstantTag {
diff --git a/pkg/nnbd_migration/lib/instrumentation.dart b/pkg/nnbd_migration/lib/instrumentation.dart
index a108610..7689928 100644
--- a/pkg/nnbd_migration/lib/instrumentation.dart
+++ b/pkg/nnbd_migration/lib/instrumentation.dart
@@ -179,6 +179,9 @@
   /// After migration is complete, this getter can be used to query whether
   /// the type associated with this node was determined to be nullable.
   bool get isNullable;
+
+  /// The edges that caused this node to have the nullability that it has.
+  Iterable<EdgeInfo> get upstreamEdges;
 }
 
 /// Information exposed to the migration client about a single step in the
diff --git a/pkg/nnbd_migration/lib/nnbd_migration.dart b/pkg/nnbd_migration/lib/nnbd_migration.dart
index 546590f..f200e92 100644
--- a/pkg/nnbd_migration/lib/nnbd_migration.dart
+++ b/pkg/nnbd_migration/lib/nnbd_migration.dart
@@ -36,14 +36,17 @@
   factory NullabilityFixDescription.addRequired(
           String className, String functionName, String paramName) =>
       NullabilityFixDescription._(
-          appliedMessage: "Add 'required' keyword to parameter $paramName in " +
-              (className == null ? functionName : '$className.$functionName'));
+          appliedMessage:
+              "Add 'required' keyword to parameter '$paramName' in " +
+                  (className == null
+                      ? functionName
+                      : "'$className.$functionName'"));
 
   /// An explicit type mentioned in the source program needs to be made
   /// nullable.
   factory NullabilityFixDescription.makeTypeNullable(String type) =>
       NullabilityFixDescription._(
-        appliedMessage: 'Changed type $type to be nullable',
+        appliedMessage: "Changed type '$type' to be nullable",
       );
 
   const NullabilityFixDescription._({@required this.appliedMessage});
diff --git a/pkg/nnbd_migration/lib/src/conditional_discard.dart b/pkg/nnbd_migration/lib/src/conditional_discard.dart
index 0295834..8495d47 100644
--- a/pkg/nnbd_migration/lib/src/conditional_discard.dart
+++ b/pkg/nnbd_migration/lib/src/conditional_discard.dart
@@ -50,7 +50,6 @@
   /// to `true` is reachable after migration.
   bool get keepTrue => trueGuard == null || trueGuard.isNullable;
 
-  @override
   Iterable<FixReasonInfo> get reasons sync* {
     if (!keepTrue) yield falseGuard;
     if (!keepFalse) yield trueGuard;
diff --git a/pkg/nnbd_migration/lib/src/decorated_type.dart b/pkg/nnbd_migration/lib/src/decorated_type.dart
index 8cb67ac..d599c48 100644
--- a/pkg/nnbd_migration/lib/src/decorated_type.dart
+++ b/pkg/nnbd_migration/lib/src/decorated_type.dart
@@ -3,11 +3,14 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/nullability_suffix.dart';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/type_algebra.dart';
+import 'package:analyzer/src/dart/element/type_algebra.dart' as type_algebra;
 import 'package:analyzer/src/generated/resolver.dart';
+import 'package:analyzer/src/generated/utilities_dart.dart';
 import 'package:nnbd_migration/instrumentation.dart';
 import 'package:nnbd_migration/src/nullability_node.dart';
 
@@ -346,6 +349,84 @@
     return _substitute(substitution, undecoratedResult);
   }
 
+  /// Convert this decorated type into the [DartType] that it will represent
+  /// after the code has been migrated.
+  ///
+  /// This method should be used after nullability propagation; it makes use of
+  /// the nullabilities associated with nullability nodes to determine which
+  /// types should be nullable and which types should not.
+  DartType toFinalType(TypeProvider typeProvider) {
+    var type = this.type;
+    if (type.isVoid || type.isDynamic) return type;
+    if (type.isBottom || type.isDartCoreNull) {
+      if (node.isNullable) {
+        return (typeProvider.nullType as TypeImpl)
+            .withNullability(NullabilitySuffix.none);
+      } else {
+        return BottomTypeImpl.instance;
+      }
+    }
+    var nullabilitySuffix =
+        node.isNullable ? NullabilitySuffix.question : NullabilitySuffix.none;
+    if (type is FunctionType) {
+      var newTypeFormals = <TypeParameterElementImpl>[];
+      var typeFormalSubstitution = <TypeParameterElement, DartType>{};
+      for (var typeFormal in typeFormals) {
+        var newTypeFormal = TypeParameterElementImpl.synthetic(typeFormal.name);
+        newTypeFormals.add(newTypeFormal);
+        typeFormalSubstitution[typeFormal] = TypeParameterTypeImpl(
+            newTypeFormal,
+            nullabilitySuffix: NullabilitySuffix.none);
+      }
+      for (int i = 0; i < newTypeFormals.length; i++) {
+        newTypeFormals[i].bound = type_algebra.substitute(
+            typeFormalBounds[i].toFinalType(typeProvider),
+            typeFormalSubstitution);
+      }
+      var parameters = <ParameterElement>[];
+      for (int i = 0; i < type.parameters.length; i++) {
+        var origParameter = type.parameters[i];
+        ParameterKind parameterKind;
+        DecoratedType parameterType;
+        var name = origParameter.name;
+        if (origParameter.isNamed) {
+          // TODO(paulberry): infer ParameterKind.NAMED_REQUIRED when
+          // appropriate. See https://github.com/dart-lang/sdk/issues/38596.
+          parameterKind = ParameterKind.NAMED;
+          parameterType = namedParameters[name];
+        } else {
+          parameterKind = origParameter.isOptional
+              ? ParameterKind.POSITIONAL
+              : ParameterKind.REQUIRED;
+          parameterType = positionalParameters[i];
+        }
+        parameters.add(ParameterElementImpl.synthetic(
+            name,
+            type_algebra.substitute(parameterType.toFinalType(typeProvider),
+                typeFormalSubstitution),
+            parameterKind));
+      }
+      return FunctionTypeImpl.synthetic(
+          type_algebra.substitute(
+              returnType.toFinalType(typeProvider), typeFormalSubstitution),
+          newTypeFormals,
+          parameters,
+          nullabilitySuffix: nullabilitySuffix);
+    } else if (type is InterfaceType) {
+      return InterfaceTypeImpl.explicit(type.element,
+          [for (var arg in typeArguments) arg.toFinalType(typeProvider)],
+          nullabilitySuffix: nullabilitySuffix);
+    } else if (type is TypeParameterType) {
+      return TypeParameterTypeImpl(type.element,
+          nullabilitySuffix: nullabilitySuffix);
+    } else {
+      // The above cases should cover all possible types.  On the off chance
+      // they don't, fall back on returning DecoratedType.type.
+      assert(false, 'Unexpected type (${type.runtimeType})');
+      return type;
+    }
+  }
+
   @override
   String toString() {
     var trailing = node == null ? '' : node.debugSuffix;
diff --git a/pkg/nnbd_migration/lib/src/decorated_type_operations.dart b/pkg/nnbd_migration/lib/src/decorated_type_operations.dart
index 088cc91..3e9f14e 100644
--- a/pkg/nnbd_migration/lib/src/decorated_type_operations.dart
+++ b/pkg/nnbd_migration/lib/src/decorated_type_operations.dart
@@ -11,7 +11,7 @@
 
 /// [TypeOperations] that works with [DecoratedType]s.
 class DecoratedTypeOperations
-    implements TypeOperations<VariableElement, DecoratedType> {
+    implements TypeOperations<PromotableElement, DecoratedType> {
   final TypeSystem _typeSystem;
   final VariableRepository _variableRepository;
   final NullabilityGraph _graph;
@@ -20,11 +20,6 @@
       this._typeSystem, this._variableRepository, this._graph);
 
   @override
-  bool isLocalVariable(VariableElement element) {
-    return element is LocalVariableElement;
-  }
-
-  @override
   bool isSameType(DecoratedType type1, DecoratedType type2) {
     return type1 == type2;
   }
@@ -40,7 +35,7 @@
   }
 
   @override
-  DecoratedType variableType(VariableElement variable) {
+  DecoratedType variableType(PromotableElement variable) {
     return _variableRepository.decoratedElementType(variable);
   }
 }
diff --git a/pkg/nnbd_migration/lib/src/edge_builder.dart b/pkg/nnbd_migration/lib/src/edge_builder.dart
index 1663b16..7fa652c 100644
--- a/pkg/nnbd_migration/lib/src/edge_builder.dart
+++ b/pkg/nnbd_migration/lib/src/edge_builder.dart
@@ -111,12 +111,12 @@
 
   /// If we are visiting a function body or initializer, instance of flow
   /// analysis.  Otherwise `null`.
-  FlowAnalysis<Statement, Expression, VariableElement, DecoratedType>
+  FlowAnalysis<Statement, Expression, PromotableElement, DecoratedType>
       _flowAnalysis;
 
   /// If we are visiting a function body or initializer, assigned variable
   /// information  used in flow analysis.  Otherwise `null`.
-  AssignedVariables<AstNode, VariableElement> _assignedVariables;
+  AssignedVariables<AstNode, PromotableElement> _assignedVariables;
 
   /// For convenience, a [DecoratedType] representing non-nullable `Object`.
   final DecoratedType _notNullType;
@@ -192,10 +192,9 @@
   List<String> _objectGetNames;
 
   EdgeBuilder(this._typeProvider, this._typeSystem, this._variables,
-      this._graph, this.source, this.listener,
+      this._graph, this.source, this.listener, this._decoratedClassHierarchy,
       {this.instrumentation})
-      : _decoratedClassHierarchy = DecoratedClassHierarchy(_variables, _graph),
-        _inheritanceManager = InheritanceManager3(_typeSystem),
+      : _inheritanceManager = InheritanceManager3(_typeSystem),
         _notNullType = DecoratedType(_typeProvider.objectType, _graph.never),
         _nonNullableBoolType =
             DecoratedType(_typeProvider.boolType, _graph.never),
@@ -261,7 +260,7 @@
   }
 
   @override
-  DecoratedType visitAssertStatement(AssertStatement node) {
+  DecoratedType visitAssertInitializer(AssertInitializer node) {
     _checkExpressionNotNull(node.condition);
     if (identical(_conditionInfo?.condition, node.condition)) {
       var intentNode = _conditionInfo.trueDemonstratesNonNullIntent;
@@ -276,7 +275,7 @@
   }
 
   @override
-  DecoratedType visitAssertInitializer(AssertInitializer node) {
+  DecoratedType visitAssertStatement(AssertStatement node) {
     _checkExpressionNotNull(node.condition);
     if (identical(_conditionInfo?.condition, node.condition)) {
       var intentNode = _conditionInfo.trueDemonstratesNonNullIntent;
@@ -340,7 +339,7 @@
           // TODO(paulberry): figure out what the rules for isPure should be.
           isPure = true;
           var element = leftOperand.staticElement;
-          if (element is VariableElement) {
+          if (element is PromotableElement) {
             _flowAnalysis.conditionEqNull(node, element, notEqual: notEqual);
           }
         }
@@ -383,18 +382,14 @@
       _variables.recordDecoratedExpressionType(node, expressionType);
       return expressionType;
     } else if (operatorType.isUserDefinableOperator) {
-      _checkExpressionNotNull(node.leftOperand);
+      var targetType = _checkExpressionNotNull(node.leftOperand);
       var callee = node.staticElement;
-      assert(!(callee is ClassMemberElement &&
-          (callee.enclosingElement as ClassElement)
-              .typeParameters
-              .isNotEmpty)); // TODO(paulberry)
       if (callee == null) {
         node.rightOperand.accept(this);
         return _dynamicType;
       } else {
-        var calleeType = getOrComputeElementType(callee);
-        // TODO(paulberry): substitute if necessary
+        var calleeType =
+            getOrComputeElementType(callee, targetType: targetType);
         assert(calleeType.positionalParameters.length > 0); // TODO(paulberry)
         _handleAssignment(node.rightOperand,
             destinationType: calleeType.positionalParameters[0]);
@@ -443,8 +438,7 @@
       node.stackTraceParameter
     ]) {
       if (identifier != null) {
-        _flowAnalysis.add(identifier.staticElement as VariableElement,
-            assigned: true);
+        _flowAnalysis.write(identifier.staticElement as PromotableElement);
       }
     }
     // The catch clause may not execute, so create a new scope for
@@ -866,7 +860,7 @@
     expression.accept(this);
     if (expression is SimpleIdentifier) {
       var element = expression.staticElement;
-      if (element is VariableElement) {
+      if (element is PromotableElement) {
         _flowAnalysis.isExpression_end(
             node, element, node.notOperator != null, decoratedType);
       }
@@ -1176,7 +1170,7 @@
   @override
   DecoratedType visitSimpleIdentifier(SimpleIdentifier node) {
     var staticElement = node.staticElement;
-    if (staticElement is VariableElement) {
+    if (staticElement is PromotableElement) {
       if (!node.inDeclarationContext()) {
         var promotedType = _flowAnalysis.promotedType(staticElement);
         if (promotedType != null) return promotedType;
@@ -1372,10 +1366,12 @@
     for (var variable in node.variables) {
       variable.metadata.accept(this);
       var initializer = variable.initializer;
-      _flowAnalysis.add(variable.declaredElement,
-          assigned: initializer != null);
+      var declaredElement = variable.declaredElement;
+      if (declaredElement is PromotableElement && initializer != null) {
+        _flowAnalysis.write(declaredElement);
+      }
       if (initializer != null) {
-        var destinationType = getOrComputeElementType(variable.declaredElement);
+        var destinationType = getOrComputeElementType(declaredElement);
         if (typeAnnotation == null) {
           var initializerType = initializer.accept(this);
           if (initializerType == null) {
@@ -1420,7 +1416,7 @@
   void _addParametersToFlowAnalysis(FormalParameterList parameters) {
     if (parameters != null) {
       for (var parameter in parameters.parameters) {
-        _flowAnalysis.add(parameter.declaredElement, assigned: true);
+        _flowAnalysis.write(parameter.declaredElement);
       }
     }
   }
@@ -1470,7 +1466,7 @@
     assert(_flowAnalysis == null);
     assert(_assignedVariables == null);
     _flowAnalysis =
-        FlowAnalysis<Statement, Expression, VariableElement, DecoratedType>(
+        FlowAnalysis<Statement, Expression, PromotableElement, DecoratedType>(
             const AnalyzerNodeOperations(),
             DecoratedTypeOperations(_typeSystem, _variables, _graph),
             AnalyzerFunctionBodyAccess(node is FunctionBody ? node : null));
@@ -1600,11 +1596,11 @@
         (destinationExpression == null) != (destinationType == null),
         'Either destinationExpression or destinationType should be supplied, '
         'but not both');
-    VariableElement destinationLocalVariable;
+    PromotableElement destinationLocalVariable;
     if (destinationType == null) {
       if (destinationExpression is SimpleIdentifier) {
         var element = destinationExpression.staticElement;
-        if (element is VariableElement) {
+        if (element is PromotableElement) {
           destinationLocalVariable = element;
         }
       }
@@ -1841,7 +1837,6 @@
       if (parts is ForEachPartsWithDeclaration) {
         var variableElement = parts.loopVariable.declaredElement;
         lhsElement = variableElement;
-        _flowAnalysis.add(variableElement, assigned: false);
       } else if (parts is ForEachPartsWithIdentifier) {
         lhsElement = parts.identifier.staticElement;
       } else {
@@ -1863,7 +1858,7 @@
         }
       }
       _flowAnalysis.forEach_bodyBegin(_assignedVariables.writtenInNode(node),
-          lhsElement is VariableElement ? lhsElement : null);
+          lhsElement is PromotableElement ? lhsElement : null);
     }
 
     // The condition may fail/iterable may be empty, so the body gets a new
diff --git a/pkg/nnbd_migration/lib/src/node_builder.dart b/pkg/nnbd_migration/lib/src/node_builder.dart
index 1f5d917..66a9fc2 100644
--- a/pkg/nnbd_migration/lib/src/node_builder.dart
+++ b/pkg/nnbd_migration/lib/src/node_builder.dart
@@ -437,7 +437,7 @@
             hard: true);
         break;
       case _NullabilityComment.question:
-        _graph.connect(_graph.always, decoratedType.node,
+        _graph.union(_graph.always, decoratedType.node,
             NullabilityCommentOrigin(source, node));
         break;
       case _NullabilityComment.none:
diff --git a/pkg/nnbd_migration/lib/src/nullability_migration_impl.dart b/pkg/nnbd_migration/lib/src/nullability_migration_impl.dart
index 247fee8..0f778dd 100644
--- a/pkg/nnbd_migration/lib/src/nullability_migration_impl.dart
+++ b/pkg/nnbd_migration/lib/src/nullability_migration_impl.dart
@@ -8,6 +8,7 @@
 import 'package:meta/meta.dart';
 import 'package:nnbd_migration/instrumentation.dart';
 import 'package:nnbd_migration/nnbd_migration.dart';
+import 'package:nnbd_migration/src/decorated_class_hierarchy.dart';
 import 'package:nnbd_migration/src/edge_builder.dart';
 import 'package:nnbd_migration/src/node_builder.dart';
 import 'package:nnbd_migration/src/nullability_node.dart';
@@ -26,6 +27,8 @@
 
   final NullabilityMigrationInstrumentation _instrumentation;
 
+  DecoratedClassHierarchy _decoratedClassHierarchy;
+
   /// Prepares to perform nullability migration.
   ///
   /// If [permissive] is `true`, exception handling logic will try to proceed
@@ -60,8 +63,11 @@
   }
 
   void prepareInput(ResolvedUnitResult result) {
-    _variables ??= Variables(_graph, result.typeProvider,
-        instrumentation: _instrumentation);
+    if (_variables == null) {
+      _variables = Variables(_graph, result.typeProvider,
+          instrumentation: _instrumentation);
+      _decoratedClassHierarchy = DecoratedClassHierarchy(_variables, _graph);
+    }
     var unit = result.unit;
     unit.accept(NodeBuilder(_variables, unit.declaredElement.source,
         _permissive ? listener : null, _graph, result.typeProvider,
@@ -70,8 +76,14 @@
 
   void processInput(ResolvedUnitResult result) {
     var unit = result.unit;
-    unit.accept(EdgeBuilder(result.typeProvider, result.typeSystem, _variables,
-        _graph, unit.declaredElement.source, _permissive ? listener : null,
+    unit.accept(EdgeBuilder(
+        result.typeProvider,
+        result.typeSystem,
+        _variables,
+        _graph,
+        unit.declaredElement.source,
+        _permissive ? listener : null,
+        _decoratedClassHierarchy,
         instrumentation: _instrumentation));
   }
 
diff --git a/pkg/nnbd_migration/lib/src/nullability_node.dart b/pkg/nnbd_migration/lib/src/nullability_node.dart
index f0122b0..3c057df 100644
--- a/pkg/nnbd_migration/lib/src/nullability_node.dart
+++ b/pkg/nnbd_migration/lib/src/nullability_node.dart
@@ -500,6 +500,9 @@
   /// nullability migration needs to decide whether it is optional or required.
   bool get isPossiblyOptional => _isPossiblyOptional;
 
+  @override
+  Iterable<EdgeInfo> get upstreamEdges => _upstreamEdges;
+
   String get _debugPrefix;
 
   NullabilityState get _state;
diff --git a/pkg/nnbd_migration/test/api_test.dart b/pkg/nnbd_migration/test/api_test.dart
index c0d90a0..0a81426 100644
--- a/pkg/nnbd_migration/test/api_test.dart
+++ b/pkg/nnbd_migration/test/api_test.dart
@@ -1047,6 +1047,16 @@
     await _checkSingleFileChanges(content, expected);
   }
 
+  test_explicit_nullable_overrides_hard_edge() async {
+    var content = '''
+int f(int/*?*/ i) => i + 1;
+''';
+    var expected = '''
+int f(int?/*?*/ i) => i! + 1;
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
   test_field_formal_param_typed() async {
     var content = '''
 class C {
diff --git a/pkg/nnbd_migration/test/decorated_type_test.dart b/pkg/nnbd_migration/test/decorated_type_test.dart
index 61e8b6d..22a2dc0 100644
--- a/pkg/nnbd_migration/test/decorated_type_test.dart
+++ b/pkg/nnbd_migration/test/decorated_type_test.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/testing/test_type_provider.dart';
@@ -38,6 +39,13 @@
 
   ClassElement get listElement => typeProvider.listElement;
 
+  void assertDartType(DartType type, String expected) {
+    // Note: by default DartType.toString doesn't print nullability suffixes,
+    // so we have to override that behavior in order to make sure the
+    // nullability suffixes are correct.
+    expect((type as TypeImpl).toString(withNullability: true), expected);
+  }
+
   void setUp() {
     NullabilityNode.clearDebugNames();
   }
@@ -291,6 +299,227 @@
     expect(list(argType, node: node) == list(argType, node: node), isTrue);
   }
 
+  test_toFinalType_bottom_non_nullable() {
+    var type =
+        DecoratedType(BottomTypeImpl.instance, never).toFinalType(typeProvider);
+    assertDartType(type, 'Never');
+  }
+
+  test_toFinalType_bottom_nullable() {
+    var type = DecoratedType(BottomTypeImpl.instance, always)
+        .toFinalType(typeProvider);
+    assertDartType(type, 'Null');
+  }
+
+  test_toFinalType_dynamic() {
+    var type = dynamic_.toFinalType(typeProvider);
+    assertDartType(type, 'dynamic');
+  }
+
+  test_toFinalType_function_generic_substitute_bounds() {
+    var u = typeParameter('U', object(node: never));
+    var t = typeParameter(
+        'T', list(typeParameterType(u, node: never), node: never));
+    var v = typeParameter(
+        'V', list(typeParameterType(u, node: never), node: never));
+    var type = function(dynamic_, typeFormals: [t, u, v], node: never)
+        .toFinalType(typeProvider) as FunctionType;
+    assertDartType(
+        type,
+        'dynamic Function<T extends List<U>,U extends Object,'
+        'V extends List<U>>()');
+    expect(type.typeFormals[0], isNot(same(t)));
+    expect(type.typeFormals[1], isNot(same(u)));
+    expect(type.typeFormals[2], isNot(same(v)));
+    expect(
+        ((type.typeFormals[0].bound as InterfaceType).typeArguments[0]
+                as TypeParameterType)
+            .element,
+        same(type.typeFormals[1]));
+    expect(
+        ((type.typeFormals[2].bound as InterfaceType).typeArguments[0]
+                as TypeParameterType)
+            .element,
+        same(type.typeFormals[1]));
+  }
+
+  test_toFinalType_function_generic_substitute_named() {
+    var t = typeParameter('T', object(node: never));
+    var type = function(dynamic_,
+            typeFormals: [t],
+            named: {'x': list(typeParameterType(t, node: never), node: never)},
+            node: never)
+        .toFinalType(typeProvider) as FunctionType;
+    assertDartType(type, 'dynamic Function<T extends Object>({x: List<T>})');
+    expect(type.typeFormals[0], isNot(same(t)));
+    expect(
+        ((type.parameters[0].type as InterfaceType).typeArguments[0]
+                as TypeParameterType)
+            .element,
+        same(type.typeFormals[0]));
+  }
+
+  test_toFinalType_function_generic_substitute_optional() {
+    var t = typeParameter('T', object(node: never));
+    var type = function(dynamic_,
+            typeFormals: [t],
+            positional: [list(typeParameterType(t, node: never), node: never)],
+            node: never)
+        .toFinalType(typeProvider) as FunctionType;
+    assertDartType(type, 'dynamic Function<T extends Object>([List<T>])');
+    expect(type.typeFormals[0], isNot(same(t)));
+    expect(
+        ((type.parameters[0].type as InterfaceType).typeArguments[0]
+                as TypeParameterType)
+            .element,
+        same(type.typeFormals[0]));
+  }
+
+  test_toFinalType_function_generic_substitute_required() {
+    var t = typeParameter('T', object());
+    var type = function(dynamic_,
+            typeFormals: [t],
+            required: [list(typeParameterType(t, node: never), node: never)],
+            node: never)
+        .toFinalType(typeProvider) as FunctionType;
+    assertDartType(type, 'dynamic Function<T extends Object>(List<T>)');
+    expect(type.typeFormals[0], isNot(same(t)));
+    expect(
+        ((type.parameters[0].type as InterfaceType).typeArguments[0]
+                as TypeParameterType)
+            .element,
+        same(type.typeFormals[0]));
+  }
+
+  test_toFinalType_function_generic_substitute_return_type() {
+    var t = typeParameter('T', object(node: never));
+    var type = function(list(typeParameterType(t, node: never), node: never),
+            typeFormals: [t], node: never)
+        .toFinalType(typeProvider) as FunctionType;
+    assertDartType(type, 'List<T> Function<T extends Object>()');
+    expect(type.typeFormals[0], isNot(same(t)));
+    expect(
+        ((type.returnType as InterfaceType).typeArguments[0]
+                as TypeParameterType)
+            .element,
+        same(type.typeFormals[0]));
+  }
+
+  test_toFinalType_function_named_parameter_non_nullable() {
+    var xType = int_(node: never);
+    var type = function(dynamic_, named: {'x': xType}, node: never)
+        .toFinalType(typeProvider);
+    assertDartType(type, 'dynamic Function({x: int})');
+  }
+
+  test_toFinalType_function_named_parameter_nullable() {
+    var xType = int_(node: always);
+    var type = function(dynamic_, named: {'x': xType}, node: never)
+        .toFinalType(typeProvider);
+    assertDartType(type, 'dynamic Function({x: int?})');
+  }
+
+  test_toFinalType_function_non_nullable() {
+    var type = function(dynamic_, node: never).toFinalType(typeProvider);
+    assertDartType(type, 'dynamic Function()');
+  }
+
+  test_toFinalType_function_nullable() {
+    var type = function(dynamic_, node: always).toFinalType(typeProvider);
+    assertDartType(type, 'dynamic Function()?');
+  }
+
+  test_toFinalType_function_optional_parameter_non_nullable() {
+    var argType = int_(node: never);
+    var type = function(dynamic_, positional: [argType], node: never)
+        .toFinalType(typeProvider);
+    assertDartType(type, 'dynamic Function([int])');
+  }
+
+  test_toFinalType_function_optional_parameter_nullable() {
+    var argType = int_(node: always);
+    var type = function(dynamic_, positional: [argType], node: never)
+        .toFinalType(typeProvider);
+    assertDartType(type, 'dynamic Function([int?])');
+  }
+
+  test_toFinalType_function_required_parameter_non_nullable() {
+    var argType = int_(node: never);
+    var type = function(dynamic_, required: [argType], node: never)
+        .toFinalType(typeProvider);
+    assertDartType(type, 'dynamic Function(int)');
+  }
+
+  test_toFinalType_function_required_parameter_nullable() {
+    var argType = int_(node: always);
+    var type = function(dynamic_, required: [argType], node: never)
+        .toFinalType(typeProvider);
+    assertDartType(type, 'dynamic Function(int?)');
+  }
+
+  test_toFinalType_function_return_type_non_nullable() {
+    var returnType = int_(node: never);
+    var type = function(returnType, node: never).toFinalType(typeProvider);
+    assertDartType(type, 'int Function()');
+  }
+
+  test_toFinalType_function_return_type_nullable() {
+    var returnType = int_(node: always);
+    var type = function(returnType, node: never).toFinalType(typeProvider);
+    assertDartType(type, 'int? Function()');
+  }
+
+  test_toFinalType_interface_non_nullable() {
+    var type = int_(node: never).toFinalType(typeProvider);
+    assertDartType(type, 'int');
+  }
+
+  test_toFinalType_interface_nullable() {
+    var type = int_(node: always).toFinalType(typeProvider);
+    assertDartType(type, 'int?');
+  }
+
+  test_toFinalType_interface_type_argument_non_nullable() {
+    var argType = int_(node: never);
+    var type = list(argType, node: never).toFinalType(typeProvider);
+    assertDartType(type, 'List<int>');
+  }
+
+  test_toFinalType_interface_type_argument_nullable() {
+    var argType = int_(node: always);
+    var type = list(argType, node: never).toFinalType(typeProvider);
+    assertDartType(type, 'List<int?>');
+  }
+
+  test_toFinalType_null_non_nullable() {
+    var type = DecoratedType(null_.type, never).toFinalType(typeProvider);
+    assertDartType(type, 'Never');
+  }
+
+  test_toFinalType_null_nullable() {
+    var type = DecoratedType(null_.type, always).toFinalType(typeProvider);
+    assertDartType(type, 'Null');
+  }
+
+  test_toFinalType_typeParameter_non_nullable() {
+    var t = typeParameter('T', object(node: never));
+    var type = typeParameterType(t, node: never).toFinalType(typeProvider);
+    expect(type, TypeMatcher<TypeParameterType>());
+    assertDartType(type, 'T');
+  }
+
+  test_toFinalType_typeParameter_nullable() {
+    var t = typeParameter('T', object(node: never));
+    var type = typeParameterType(t, node: always).toFinalType(typeProvider);
+    expect(type, TypeMatcher<TypeParameterType>());
+    assertDartType(type, 'T?');
+  }
+
+  test_toFinalType_void() {
+    var type = void_.toFinalType(typeProvider);
+    assertDartType(type, 'void');
+  }
+
   test_toString_bottom() {
     var node = newNode();
     var decoratedType = DecoratedType(BottomTypeImpl.instance, node);
diff --git a/pkg/nnbd_migration/test/edge_builder_test.dart b/pkg/nnbd_migration/test/edge_builder_test.dart
index e70c987..45fbad0 100644
--- a/pkg/nnbd_migration/test/edge_builder_test.dart
+++ b/pkg/nnbd_migration/test/edge_builder_test.dart
@@ -1167,6 +1167,25 @@
             hard: true));
   }
 
+  test_binaryExpression_plus_substituted() async {
+    await analyze('''
+class _C<T, U> {
+  T operator+(U u) => throw 'foo';
+}
+Object _f(_C<int, String> c, String s) => c + s;
+''');
+    assertEdge(
+        decoratedTypeAnnotation('String s').node,
+        substitutionNode(decoratedTypeAnnotation('String>').node,
+            decoratedTypeAnnotation('U u').node),
+        hard: true);
+    assertEdge(
+        substitutionNode(decoratedTypeAnnotation('int,').node,
+            decoratedTypeAnnotation('T operator').node),
+        decoratedTypeAnnotation('Object _f').node,
+        hard: false);
+  }
+
   test_binaryExpression_questionQuestion() async {
     await analyze('''
 int f(int i, int j) => i ?? j;
diff --git a/pkg/nnbd_migration/test/migration_visitor_test_base.dart b/pkg/nnbd_migration/test/migration_visitor_test_base.dart
index 4c16e02..91219ff 100644
--- a/pkg/nnbd_migration/test/migration_visitor_test_base.dart
+++ b/pkg/nnbd_migration/test/migration_visitor_test_base.dart
@@ -12,6 +12,7 @@
 import 'package:analyzer/src/generated/utilities_dart.dart';
 import 'package:meta/meta.dart';
 import 'package:nnbd_migration/src/conditional_discard.dart';
+import 'package:nnbd_migration/src/decorated_class_hierarchy.dart';
 import 'package:nnbd_migration/src/decorated_type.dart';
 import 'package:nnbd_migration/src/edge_builder.dart';
 import 'package:nnbd_migration/src/expression_checks.dart';
@@ -135,13 +136,16 @@
 }
 
 class EdgeBuilderTestBase extends MigrationVisitorTestBase {
+  DecoratedClassHierarchy decoratedClassHierarchy;
+
   /// Analyzes the given source code, producing constraint variables and
   /// constraints for it.
   @override
   Future<CompilationUnit> analyze(String code) async {
     var unit = await super.analyze(code);
-    unit.accept(EdgeBuilder(
-        typeProvider, typeSystem, variables, graph, testSource, null));
+    decoratedClassHierarchy = DecoratedClassHierarchy(variables, graph);
+    unit.accept(EdgeBuilder(typeProvider, typeSystem, variables, graph,
+        testSource, null, decoratedClassHierarchy));
     return unit;
   }
 }
diff --git a/pkg/nnbd_migration/test/node_builder_test.dart b/pkg/nnbd_migration/test/node_builder_test.dart
index a85aed0..16bef49 100644
--- a/pkg/nnbd_migration/test/node_builder_test.dart
+++ b/pkg/nnbd_migration/test/node_builder_test.dart
@@ -1507,7 +1507,7 @@
     await analyze('''
 void f(int/*?*/ i) {}
 ''');
-    assertEdge(always, decoratedTypeAnnotation('int').node, hard: false);
+    assertUnion(always, decoratedTypeAnnotation('int').node);
   }
 
   test_type_parameter_explicit_bound() async {
diff --git a/pkg/nnbd_migration/tool/trial_migration.dart b/pkg/nnbd_migration/tool/trial_migration.dart
index f207d07..e2f9af1 100644
--- a/pkg/nnbd_migration/tool/trial_migration.dart
+++ b/pkg/nnbd_migration/tool/trial_migration.dart
@@ -107,7 +107,7 @@
     } else if (edit.replacement == "import 'package:meta/meta.dart';\n" &&
         edit.length == 0) {
       ++numMetaImportsAdded;
-    } else if (edit.replacement == '@required ' && edit.length == 0) {
+    } else if (edit.replacement == 'required ' && edit.length == 0) {
       ++numRequiredAnnotationsAdded;
     } else if ((edit.replacement == '/* ' ||
             edit.replacement == ' /*' ||
diff --git a/pkg/pkg.status b/pkg/pkg.status
index 61c2e71..687c3b0 100644
--- a/pkg/pkg.status
+++ b/pkg/pkg.status
@@ -76,6 +76,8 @@
 front_end/test/*: SkipByDesign # Only meant to run on vm, most use dart:mirrors and dart:io
 front_end/tool/*: SkipByDesign # Only meant to run on vm
 modular_test/test/memory_pipeline_test: Slow
+modular_test/test/validate_pipeline_test: Slow
+modular_test/test/validate_suite_test: Slow
 nnbd_migration/test/*: SkipByDesign # Uses mirrors
 smith/test/*: SkipByDesign # Only meant to run on vm
 status_file/test/normalize_test: SkipByDesign # Uses dart:io
diff --git a/pkg/test_runner/lib/src/compiler_configuration.dart b/pkg/test_runner/lib/src/compiler_configuration.dart
index 5ac46ed..9feb36a 100644
--- a/pkg/test_runner/lib/src/compiler_configuration.dart
+++ b/pkg/test_runner/lib/src/compiler_configuration.dart
@@ -590,8 +590,6 @@
 
   bool get _isArm64 => _configuration.architecture == Architecture.arm64;
 
-  bool get _isSimArm64 => _configuration.architecture == Architecture.simarm64;
-
   bool get _isX64 => _configuration.architecture == Architecture.x64;
 
   bool get _isIA32 => _configuration.architecture == Architecture.ia32;
@@ -632,6 +630,15 @@
       }
     }
 
+    if (_configuration.useElf && _isAndroid) {
+      // On Android, run the NDK's "strip" tool with "--strip-unneeded" to copy
+      // Flutter's workflow. Skip this step on tests for DWARF (which may get
+      // stripped).
+      if (!arguments.last.contains("dwarf")) {
+        commands.add(computeStripCommand(tempDir, environmentOverrides));
+      }
+    }
+
     return CommandArtifact(
         commands, '$tempDir', 'application/dart-precompiled');
   }
@@ -702,27 +709,26 @@
         alwaysCompile: !_useSdk);
   }
 
+  static const String ndkPath = "third_party/android_tools/ndk";
+  String get abiTriple => _isArm
+      ? "arm-linux-androideabi"
+      : _isArm64 ? "aarch64-linux-android" : null;
+  String get host =>
+      Platform.isLinux ? "linux" : Platform.isMacOS ? "darwin" : null;
+
   Command computeAssembleCommand(String tempDir, List arguments,
       Map<String, String> environmentOverrides) {
     String cc, shared, ldFlags;
-    if (_isAndroid || _isSimArm || _isSimArm64) {
-      var ndk = "third_party/android_tools/ndk";
-      String triple;
-      if (_isArm || _isSimArm) {
-        triple = "arm-linux-androideabi";
-      } else if (_isArm64 || _isSimArm64) {
-        triple = "aarch64-linux-android";
-      }
-      String host;
-      if (Platform.isLinux) {
-        host = "linux";
-      } else if (Platform.isMacOS) {
-        host = "darwin";
-      }
-      cc = "$ndk/toolchains/$triple-4.9/prebuilt/$host-x86_64/bin/$triple-gcc";
+    if (_isAndroid) {
+      cc = "$ndkPath/toolchains/$abiTriple-4.9/prebuilt/"
+          "$host-x86_64/bin/$abiTriple-gcc";
       shared = '-shared';
     } else if (Platform.isLinux) {
-      cc = 'gcc';
+      if (_isSimArm) {
+        cc = 'arm-linux-gnueabihf-gcc';
+      } else {
+        cc = 'gcc';
+      }
       shared = '-shared';
     } else if (Platform.isMacOS) {
       cc = 'clang';
@@ -764,6 +770,19 @@
         alwaysCompile: !_useSdk);
   }
 
+  Command computeStripCommand(
+      String tempDir, Map<String, String> environmentOverrides) {
+    final String stripTool = "$ndkPath/toolchains/$abiTriple-4.9/prebuilt/"
+        "$host-x86_64/bin/$abiTriple-strip";
+    final List<String> args = [
+      '--strip-unneeded',
+      "$tempDir/out.aotsnapshot",
+    ];
+    return CompilationCommand('strip', tempDir, bootstrapDependencies(),
+        stripTool, args, environmentOverrides,
+        alwaysCompile: !_useSdk);
+  }
+
   /// Creates a command to clean up large temporary assembly files.
   ///
   /// This step reduces the amount of space needed to run the precompilation
diff --git a/pkg/vm/lib/frontend_server.dart b/pkg/vm/lib/frontend_server.dart
index 65164f6..f215187 100644
--- a/pkg/vm/lib/frontend_server.dart
+++ b/pkg/vm/lib/frontend_server.dart
@@ -33,10 +33,12 @@
     show
         asFileUri,
         compileToKernel,
-        parseCommandLineDefines,
         convertFileOrUriArgumentToUri,
-        createFrontEndTarget,
         createFrontEndFileSystem,
+        createFrontEndTarget,
+        forEachPackage,
+        packageFor,
+        parseCommandLineDefines,
         runWithFrontEndCompilerContext,
         setVMEnvironmentDefines,
         writeDepfile;
@@ -341,6 +343,7 @@
     compilerOptions.bytecode = options['gen-bytecode'];
     final BytecodeOptions bytecodeOptions = new BytecodeOptions(
         enableAsserts: options['enable-asserts'],
+        emitSourceFiles: options['embed-source-text'],
         environmentDefines: environmentDefines)
       ..parseCommandLineFlags(options['bytecode-options']);
 
@@ -549,6 +552,59 @@
     }
   }
 
+  bool _elementsIdentical(List a, List b) {
+    if (a.length != b.length) return false;
+    for (int i = 0; i < a.length; i++) {
+      if (!identical(a[i], b[i])) return false;
+    }
+    return true;
+  }
+
+  final _packageLibraries = new Expando();
+  final _packageBytes = new Expando();
+
+  void _writePackage(Component component, String package,
+      List<Library> libraries, IOSink sink) {
+    final canCache = libraries.isNotEmpty &&
+        _compilerOptions.bytecode &&
+        errors.isEmpty &&
+        package != "main";
+
+    if (canCache) {
+      var cachedLibraries = _packageLibraries[libraries.first];
+      if ((cachedLibraries != null) &&
+          _elementsIdentical(cachedLibraries, libraries)) {
+        sink.add(_packageBytes[libraries.first]);
+        return;
+      }
+    }
+
+    Component partComponent = component;
+    if (_compilerOptions.bytecode && errors.isEmpty) {
+      generateBytecode(partComponent,
+          options: _bytecodeOptions,
+          libraries: libraries,
+          coreTypes: _generator.getCoreTypes(),
+          hierarchy: _generator.getClassHierarchy());
+
+      if (_options['drop-ast']) {
+        partComponent = createFreshComponentWithBytecode(partComponent);
+      }
+    }
+
+    final byteSink = new ByteSink();
+    final BinaryPrinter printer = new LimitedBinaryPrinter(byteSink,
+        (lib) => packageFor(lib) == package, false /* excludeUriToSource */);
+    printer.writeComponentFile(partComponent);
+
+    final bytes = byteSink.builder.takeBytes();
+    sink.add(bytes);
+    if (canCache) {
+      _packageLibraries[libraries.first] = libraries;
+      _packageBytes[libraries.first] = bytes;
+    }
+  }
+
   @override
   Future<Null> recompileDelta({String entryPoint}) async {
     final String boundaryKey = new Uuid().generateV4();
@@ -564,8 +620,21 @@
       transformer.transform(deltaProgram);
     }
     final compiledSources = deltaProgram.uriToSource.keys;
-    deltaProgram = await _generateBytecodeIfNeeded(deltaProgram);
-    await writeDillFile(deltaProgram, _kernelBinaryFilename);
+
+    if (_compilerOptions.bytecode) {
+      final IOSink sink = new File(_kernelBinaryFilename).openWrite();
+      await runWithFrontEndCompilerContext(
+          _mainSource, _compilerOptions, deltaProgram, () async {
+        await forEachPackage(deltaProgram,
+            (String package, List<Library> libraries) async {
+          _writePackage(deltaProgram, package, libraries, sink);
+        });
+      });
+      await sink.close();
+    } else {
+      await writeDillFile(deltaProgram, _kernelBinaryFilename);
+    }
+
     _outputStream.writeln(boundaryKey);
     await _outputDependenciesDelta(compiledSources);
     _outputStream
diff --git a/pkg/vm/lib/kernel_front_end.dart b/pkg/vm/lib/kernel_front_end.dart
index 3c71ea3..1a633c6 100644
--- a/pkg/vm/lib/kernel_front_end.dart
+++ b/pkg/vm/lib/kernel_front_end.dart
@@ -595,28 +595,6 @@
   BytecodeOptions bytecodeOptions,
   bool dropAST: false,
 }) async {
-  // Package sharing: make the encoding not depend on the order in which parts
-  // of a package are loaded.
-  component.libraries.sort((Library a, Library b) {
-    return a.importUri.toString().compareTo(b.importUri.toString());
-  });
-  component.computeCanonicalNames();
-  for (Library lib in component.libraries) {
-    lib.additionalExports.sort((Reference a, Reference b) {
-      return a.canonicalName.toString().compareTo(b.canonicalName.toString());
-    });
-  }
-
-  final packagesSet = new Set<String>();
-  for (Library lib in component.libraries) {
-    packagesSet.add(packageFor(lib));
-  }
-  packagesSet.remove('main');
-  packagesSet.remove(null);
-
-  final List<String> packages = packagesSet.toList();
-  packages.add('main'); // Make sure main package is last.
-
   if (bytecodeOptions.showBytecodeSizeStatistics) {
     BytecodeSizeStatistics.reset();
   }
@@ -629,31 +607,24 @@
         new ClassHierarchy(component, onAmbiguousSupertypes: (cls, a, b) {});
   }
 
+  final packages = new List<String>();
   await runWithFrontEndCompilerContext(source, compilerOptions, component,
       () async {
-    for (String package in packages) {
+    await forEachPackage(component,
+        (String package, List<Library> libraries) async {
+      packages.add(package);
       final String filename = '$outputFileName-$package.dilp';
       final IOSink sink = new File(filename).openWrite();
 
-      final main = component.mainMethod;
-      final problems = component.problemsAsJson;
-      if (package != 'main') {
-        component.mainMethod = null;
-        component.problemsAsJson = null;
-      }
-
       Component partComponent = component;
       if (genBytecode) {
-        final List<Library> libraries = component.libraries
-            .where((lib) => packageFor(lib) == package)
-            .toList();
-        generateBytecode(component,
+        generateBytecode(partComponent,
             options: bytecodeOptions,
             libraries: libraries,
             hierarchy: hierarchy);
 
         if (dropAST) {
-          partComponent = createFreshComponentWithBytecode(component);
+          partComponent = createFreshComponentWithBytecode(partComponent);
         }
       }
 
@@ -661,11 +632,8 @@
           (lib) => packageFor(lib) == package, false /* excludeUriToSource */);
       printer.writeComponentFile(partComponent);
 
-      component.mainMethod = main;
-      component.problemsAsJson = problems;
-
       await sink.close();
-    }
+    });
   });
 
   if (bytecodeOptions.showBytecodeSizeStatistics) {
@@ -692,6 +660,47 @@
   return 'main';
 }
 
+Future<Null> forEachPackage<T>(Component component,
+    T action(String package, List<Library> libraries)) async {
+  // Package sharing: make the encoding not depend on the order in which parts
+  // of a package are loaded.
+  component.libraries.sort((Library a, Library b) {
+    return a.importUri.toString().compareTo(b.importUri.toString());
+  });
+  component.computeCanonicalNames();
+  for (Library lib in component.libraries) {
+    lib.additionalExports.sort((Reference a, Reference b) {
+      return a.canonicalName.toString().compareTo(b.canonicalName.toString());
+    });
+  }
+
+  final packages = new Map<String, List<Library>>();
+  for (Library lib in component.libraries) {
+    packages.putIfAbsent(packageFor(lib), () => new List<Library>()).add(lib);
+  }
+  if (packages.containsKey(null)) {
+    packages.remove(null);
+  }
+  if (packages.containsKey('main')) {
+    // Make sure main package is last.
+    packages['main'] = packages.remove('main');
+  }
+
+  for (String package in packages.keys) {
+    final main = component.mainMethod;
+    final problems = component.problemsAsJson;
+    if (package != 'main') {
+      component.mainMethod = null;
+      component.problemsAsJson = null;
+    }
+
+    await action(package, packages[package]);
+
+    component.mainMethod = main;
+    component.problemsAsJson = problems;
+  }
+}
+
 String _escapePath(String path) {
   return path.replaceAll('\\', '\\\\').replaceAll(' ', '\\ ');
 }
diff --git a/pkg/vm_service/CHANGELOG.md b/pkg/vm_service/CHANGELOG.md
index 68ded73..a5de560 100644
--- a/pkg/vm_service/CHANGELOG.md
+++ b/pkg/vm_service/CHANGELOG.md
@@ -1,5 +1,11 @@
 # Changelog
 
+## 2.1.0
+- Added `HeapSnapshotGraph` class which parses the binary events posted to the
+  `HeapSnapshot` stream after a `requestHeapSnapshot` invocation.
+- Fixed issue where listening to `EventStream.kHeapSnapshot` and calling
+  `requestHeapSnapshot` would throw an exception.
+
 ## 2.0.0
 - **breaking**: VM service objects which have fields now have constructors with
   named parameters for each field. Required fields are annotated with `@required`.
diff --git a/pkg/vm_service/lib/src/snapshot_graph.dart b/pkg/vm_service/lib/src/snapshot_graph.dart
new file mode 100644
index 0000000..7265cd4
--- /dev/null
+++ b/pkg/vm_service/lib/src/snapshot_graph.dart
@@ -0,0 +1,373 @@
+// 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 'dart:convert';
+import 'dart:typed_data';
+
+import '../vm_service.dart';
+
+class _ReadStream {
+  final List<ByteData> _chunks;
+  int _chunkIndex = 0;
+  int _byteIndex = 0;
+
+  _ReadStream(this._chunks);
+
+  int readByte() {
+    while (_byteIndex >= _chunks[_chunkIndex].lengthInBytes) {
+      _chunkIndex++;
+      _byteIndex = 0;
+    }
+    return _chunks[_chunkIndex].getUint8(_byteIndex++);
+  }
+
+  /// Read one ULEB128 number.
+  int readUnsigned() {
+    int result = 0;
+    int shift = 0;
+    for (;;) {
+      int part = readByte();
+      result |= (part & 0x7F) << shift;
+      if ((part & 0x80) == 0) {
+        break;
+      }
+      shift += 7;
+    }
+    return result;
+  }
+
+  /// Read one SLEB128 number.
+  int readSigned() {
+    int result = 0;
+    int shift = 0;
+    for (;;) {
+      int part = readByte();
+      result |= (part & 0x7F) << shift;
+      shift += 7;
+      if ((part & 0x80) == 0) {
+        if ((part & 0x40) != 0) {
+          result |= (-1 << shift);
+        }
+        break;
+      }
+    }
+    return result;
+  }
+
+  double readFloat64() {
+    final bytes = Uint8List(8);
+    for (int i = 0; i < 8; i++) {
+      bytes[i] = readByte();
+    }
+    return Float64List.view(bytes.buffer)[0];
+  }
+
+  String readUtf8() {
+    int len = readUnsigned();
+    final bytes = Uint8List(len);
+    for (int i = 0; i < len; i++) {
+      bytes[i] = readByte();
+    }
+    return Utf8Codec(allowMalformed: true).decode(bytes);
+  }
+
+  String readLatin1() {
+    int len = readUnsigned();
+    final codeUnits = Uint8List(len);
+    for (int i = 0; i < len; i++) {
+      codeUnits[i] = readByte();
+    }
+    return String.fromCharCodes(codeUnits);
+  }
+
+  String readUtf16() {
+    int len = readUnsigned();
+    final codeUnits = Uint16List(len);
+    for (int i = 0; i < len; i++) {
+      codeUnits[i] = readByte() | (readByte() << 8);
+    }
+    return String.fromCharCodes(codeUnits);
+  }
+}
+
+/// A representation of a field captured in a memory snapshot.
+class HeapSnapshotField {
+  /// A 0-origin index into [HeapSnapshotObject.references].
+  int get index => _index;
+
+  /// The name of the field.
+  String get name => _name;
+
+  int _index;
+  String _name;
+
+  HeapSnapshotField._read(_ReadStream reader) {
+    // flags (reserved)
+    reader.readUnsigned();
+
+    _index = reader.readUnsigned();
+    _name = reader.readUtf8();
+
+    // reserved
+    reader.readUtf8();
+  }
+}
+
+/// A representation of a class type captured in a memory snapshot.
+class HeapSnapshotClass {
+  /// The simple (not qualified) name of the class.
+  String get name => _name;
+
+  /// The name of the class's library.
+  String get libraryName => _libraryName;
+
+  /// The [Uri] of the class's library.
+  Uri get libraryUri => _libraryUri;
+
+  /// The list of fields in the class.
+  List<HeapSnapshotField> get fields => _fields;
+
+  String _name;
+  String _libraryName;
+  Uri _libraryUri;
+  List<HeapSnapshotField> _fields = <HeapSnapshotField>[];
+
+  HeapSnapshotClass._read(_ReadStream reader) {
+    // flags (reserved).
+    reader.readUnsigned();
+
+    _name = reader.readUtf8();
+    _libraryName = reader.readUtf8();
+    _libraryUri = Uri.parse(reader.readUtf8());
+
+    // reserved
+    reader.readUtf8();
+
+    _populateFields(reader);
+  }
+
+  void _populateFields(_ReadStream reader) {
+    final fieldCount = reader.readUnsigned();
+    for (int i = 0; i < fieldCount; ++i) {
+      _fields.add(HeapSnapshotField._read(reader));
+    }
+  }
+}
+
+/// A representation of an object instance captured in a memory snapshot.
+class HeapSnapshotObject {
+  /// The class ID representing the type of this object.
+  int get classId => _classId;
+
+  /// The space used by this object in bytes.
+  int get shallowSize => _shallowSize;
+
+  /// Data associated with this object.
+  dynamic get data => _data;
+
+  /// A list of 1-origin indicies into [HeapSnapshotGraph.objects].
+  List<int> get references => _references;
+
+  int _classId;
+  int _shallowSize;
+  dynamic _data;
+  List<int> _references = <int>[];
+
+  HeapSnapshotObject._read(_ReadStream reader) {
+    _classId = reader.readUnsigned();
+    _shallowSize = reader.readUnsigned();
+    _data = _getNonReferenceData(reader);
+    _populateReferences(reader);
+  }
+
+  void _populateReferences(_ReadStream reader) {
+    final referencesCount = reader.readUnsigned();
+    for (int i = 0; i < referencesCount; ++i) {
+      _references.add(reader.readUnsigned());
+    }
+  }
+}
+
+/// A representation of an external property captured in a memory snapshot.
+class HeapSnapshotExternalProperty {
+  /// A 1-origin index into [HeapSnapshotGraph.objects].
+  final int object;
+
+  /// The amount of external memory used.
+  final int externalSize;
+
+  /// The name of the external property.
+  final String name;
+
+  HeapSnapshotExternalProperty._read(_ReadStream reader)
+      : object = reader.readUnsigned(),
+        externalSize = reader.readUnsigned(),
+        name = reader.readUtf8();
+}
+
+/// A graph representation of a heap snapshot.
+class HeapSnapshotGraph {
+  /// The name of the isolate represented by this heap snapshot.
+  String get name => _name;
+
+  int get flags => _flags;
+
+  /// The sum of shallow sizes of all objects in this graph in bytes.
+  int get shallowSize => _shallowSize;
+
+  /// The amount of memory reserved for this heap in bytes.
+  ///
+  /// At least as large as [shallowSize].
+  int get capacity => _capacity;
+
+  /// The sum of sizes of all external properties in this graph in bytes.
+  int get externalSize => _externalSize;
+
+  /// The list of classes found in this snapshot.
+  List<HeapSnapshotClass> get classes => _classes;
+
+  /// At least as big as the sum of all [HeapSnapshotObject.referenceCount].
+  int get referenceCount => _referenceCount;
+
+  /// The list of objects found in this snapshot.
+  List<HeapSnapshotObject> get objects => _objects;
+
+  /// The list of external properties found in this snapshot.
+  List<HeapSnapshotExternalProperty> get externalProperties =>
+      _externalProperties;
+
+  String _name;
+  int _flags;
+  int _shallowSize;
+  int _capacity;
+  int _externalSize;
+  List<HeapSnapshotClass> _classes = <HeapSnapshotClass>[];
+  int _referenceCount;
+  List<HeapSnapshotObject> _objects = <HeapSnapshotObject>[];
+  List<HeapSnapshotExternalProperty> _externalProperties =
+      <HeapSnapshotExternalProperty>[];
+
+  /// Requests a heap snapshot for a given isolate and builds a
+  /// [HeapSnapshotGraph].
+  ///
+  /// Note: this method calls [VmService.streamListen] and
+  /// [VmService.streamCancel] on [EventStreams.kHeapSnapshot].
+  static Future<HeapSnapshotGraph> getSnapshot(
+      VmService service, IsolateRef isolate) async {
+    await service.streamListen(EventStreams.kHeapSnapshot);
+
+    final completer = Completer<HeapSnapshotGraph>();
+    final chunks = <ByteData>[];
+    service.onHeapSnapshotEvent.listen((e) async {
+      chunks.add(e.data);
+      if (e.last) {
+        await service.streamCancel(EventStreams.kHeapSnapshot);
+        completer.complete(HeapSnapshotGraph.fromChunks(chunks));
+      }
+    });
+
+    await service.requestHeapSnapshot(isolate.id);
+    return completer.future;
+  }
+
+  /// Populates the [HeapSnapshotGraph] by parsing the events from the
+  /// `HeapSnapshot` stream.
+  HeapSnapshotGraph.fromChunks(List<ByteData> chunks) {
+    final reader = _ReadStream(chunks);
+
+    // Skip magic header
+    for (int i = 0; i < 8; ++i) {
+      reader.readByte();
+    }
+
+    _flags = reader.readUnsigned();
+    _name = reader.readUtf8();
+    _shallowSize = reader.readUnsigned();
+    _capacity = reader.readUnsigned();
+    _externalSize = reader.readUnsigned();
+    _populateClasses(reader);
+    _referenceCount = reader.readUnsigned();
+    _populateObjects(reader);
+    _populateExternalProperties(reader);
+  }
+
+  void _populateClasses(_ReadStream reader) {
+    final classCount = reader.readUnsigned();
+    for (int i = 0; i < classCount; ++i) {
+      _classes.add(HeapSnapshotClass._read(reader));
+    }
+  }
+
+  void _populateObjects(_ReadStream reader) {
+    final objectCount = reader.readUnsigned();
+    for (int i = 0; i < objectCount; ++i) {
+      _objects.add(HeapSnapshotObject._read(reader));
+    }
+  }
+
+  void _populateExternalProperties(_ReadStream reader) {
+    final propertiesCount = reader.readUnsigned();
+    for (int i = 0; i < propertiesCount; ++i) {
+      _externalProperties.add(HeapSnapshotExternalProperty._read(reader));
+    }
+  }
+}
+
+const _kNoData = 0;
+const _kNullData = 1;
+const _kBoolData = 2;
+const _kIntData = 3;
+const _kDoubleData = 4;
+const _kLatin1Data = 5;
+const _kUtf16Data = 6;
+const _kLengthData = 7;
+const _kNameData = 8;
+
+dynamic _getNonReferenceData(_ReadStream reader) {
+  final tag = reader.readUnsigned();
+  switch (tag) {
+    case _kNoData:
+      return const HeapSnapshotObjectNoData();
+    case _kNullData:
+      return const HeapSnapshotObjectNullData();
+    case _kBoolData:
+      return (reader.readByte() == 1);
+    case _kIntData:
+      return reader.readUnsigned();
+    case _kDoubleData:
+      return reader.readFloat64();
+    case _kLatin1Data:
+      final len = reader.readUnsigned();
+      final str = reader.readLatin1();
+      return (str.length < len) ? '$str...' : str;
+    case _kUtf16Data:
+      final len = reader.readUnsigned();
+      final str = reader.readUtf16();
+      return (str.length < len) ? '$str...' : str;
+      return reader.readUtf16();
+    case _kLengthData:
+      return HeapSnapshotObjectLengthData(reader.readUnsigned());
+    case _kNameData:
+      return reader.readUtf8();
+    default:
+      throw 'Invalid tag: $tag';
+  }
+}
+
+/// Represents that no data is associated with an object.
+class HeapSnapshotObjectNoData {
+  const HeapSnapshotObjectNoData();
+}
+
+/// Represents that the data associated with an object is null.
+class HeapSnapshotObjectNullData {
+  const HeapSnapshotObjectNullData();
+}
+
+/// Represents the length of an object.
+class HeapSnapshotObjectLengthData {
+  final int length;
+  HeapSnapshotObjectLengthData(this.length);
+}
diff --git a/pkg/vm_service/lib/vm_service.dart b/pkg/vm_service/lib/vm_service.dart
index 63ab8a8..5133141 100644
--- a/pkg/vm_service/lib/vm_service.dart
+++ b/pkg/vm_service/lib/vm_service.dart
@@ -18,6 +18,16 @@
 import 'src/service_extension_registry.dart';
 
 export 'src/service_extension_registry.dart' show ServiceExtensionRegistry;
+export 'src/snapshot_graph.dart'
+    show
+        HeapSnapshotClass,
+        HeapSnapshotExternalProperty,
+        HeapSnapshotField,
+        HeapSnapshotGraph,
+        HeapSnapshotObject,
+        HeapSnapshotObjectLengthData,
+        HeapSnapshotObjectNoData,
+        HeapSnapshotObjectNullData;
 
 const String vmServiceVersion = '3.27.0';
 
@@ -1736,19 +1746,19 @@
   }
 
   void _processMessageByteData(ByteData bytes) {
-    int offset = 0;
-    int metaSize = bytes.getUint32(offset + 4, Endian.big);
-    offset += 8;
-    String meta = utf8.decode(
-        Uint8List.view(bytes.buffer, bytes.offsetInBytes + offset, metaSize));
-    offset += metaSize;
-    ByteData data = ByteData.view(bytes.buffer, bytes.offsetInBytes + offset,
-        bytes.lengthInBytes - offset);
+    final int metaOffset = 4;
+    final int dataOffset = bytes.getUint32(0, Endian.little);
+    final metaLength = dataOffset - metaOffset;
+    final dataLength = bytes.lengthInBytes - dataOffset;
+    final meta = utf8.decode(Uint8List.view(
+        bytes.buffer, bytes.offsetInBytes + metaOffset, metaLength));
+    final data = ByteData.view(
+        bytes.buffer, bytes.offsetInBytes + dataOffset, dataLength);
     dynamic map = jsonDecode(meta);
     if (map != null && map['method'] == 'streamNotify') {
       String streamId = map['params']['streamId'];
       Map event = map['params']['event'];
-      event['_data'] = data;
+      event['data'] = data;
       _getEventController(streamId)
           .add(createServiceObject(event, const ['Event']));
     }
@@ -3245,6 +3255,20 @@
   @optional
   String newValue;
 
+  /// Specifies whether this event is the last of a group of events.
+  ///
+  /// This is provided for the event kinds:
+  ///  - HeapSnapshot
+  @optional
+  bool last;
+
+  /// Binary data associated with the event.
+  ///
+  /// This is provided for the event kinds:
+  ///   - HeapSnapshot
+  @optional
+  ByteData data;
+
   Event({
     @required this.kind,
     @required this.timestamp,
@@ -3268,6 +3292,8 @@
     this.alias,
     this.flag,
     this.newValue,
+    this.last,
+    this.data,
   });
   Event._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
     kind = json['kind'];
@@ -3298,6 +3324,8 @@
     alias = json['alias'];
     flag = json['flag'];
     newValue = json['newValue'];
+    last = json['last'];
+    data = json['data'];
   }
 
   @override
@@ -3330,6 +3358,8 @@
     _setIfNotNull(json, 'alias', alias);
     _setIfNotNull(json, 'flag', flag);
     _setIfNotNull(json, 'newValue', newValue);
+    _setIfNotNull(json, 'last', last);
+    _setIfNotNull(json, 'data', data);
     return json;
   }
 
diff --git a/pkg/vm_service/pubspec.yaml b/pkg/vm_service/pubspec.yaml
index af6597f..c26a959 100644
--- a/pkg/vm_service/pubspec.yaml
+++ b/pkg/vm_service/pubspec.yaml
@@ -2,7 +2,7 @@
 description: >-
   A library to communicate with a service implementing the Dart VM
   service protocol.
-version: 2.0.0
+version: 2.1.0
 
 author: Dart Team <misc@dartlang.org>
 homepage: https://github.com/dart-lang/sdk/tree/master/pkg/vm_service
diff --git a/pkg/vm_service/test/heap_snapshot_graph_test.dart b/pkg/vm_service/test/heap_snapshot_graph_test.dart
new file mode 100644
index 0000000..6fb85dd
--- /dev/null
+++ b/pkg/vm_service/test/heap_snapshot_graph_test.dart
@@ -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.
+
+import 'dart:async';
+import 'dart:typed_data';
+
+import 'package:vm_service/vm_service.dart';
+import 'package:test/test.dart';
+
+import 'common/service_test_common.dart';
+import 'common/test_helper.dart';
+
+class Foo {
+  dynamic left;
+  dynamic right;
+}
+
+Foo r;
+
+List lst;
+
+void script() {
+  // Create 3 instances of Foo, with out-degrees
+  // 0 (for b), 1 (for a), and 2 (for staticFoo).
+  r = Foo();
+  var a = Foo();
+  var b = Foo();
+  r.left = a;
+  r.right = b;
+  a.left = b;
+
+  lst = List(2);
+  lst[0] = lst; // Self-loop.
+  // Larger than any other fixed-size list in a fresh heap.
+  lst[1] = List(1234569);
+}
+
+var tests = <IsolateTest>[
+  (VmService service, IsolateRef isolate) async {
+    final snapshotGraph = await HeapSnapshotGraph.getSnapshot(service, isolate);
+    expect(snapshotGraph.name, "main");
+    expect(snapshotGraph.flags, isNotNull);
+    expect(snapshotGraph.objects, isNotNull);
+    expect(snapshotGraph.objects.length > 0, isTrue);
+
+    int actualShallowSize = 0;
+    int actualRefCount = 0;
+    snapshotGraph.objects.forEach((HeapSnapshotObject o) {
+      expect(o.classId >= 0, isTrue);
+      expect(o.data, isNotNull);
+      expect(o.references, isNotNull);
+      actualShallowSize += o.shallowSize;
+      actualRefCount += o.references.length;
+    });
+
+    // Some accounting differences in the VM result in the global shallow size
+    // often being greater than the sum of the object shallow sizes.
+    expect(snapshotGraph.shallowSize >= actualShallowSize, isTrue);
+    expect(snapshotGraph.shallowSize <= snapshotGraph.capacity, isTrue);
+    expect(snapshotGraph.referenceCount >= actualRefCount, isTrue);
+
+    int actualExternalSize = 0;
+    expect(snapshotGraph.externalProperties.length > 0, isTrue);
+    snapshotGraph.externalProperties.forEach((HeapSnapshotExternalProperty e) {
+      actualExternalSize += e.externalSize;
+      expect(e.object >= 0, isTrue);
+      expect(e.name, isNotNull);
+    });
+    expect(snapshotGraph.externalSize, actualExternalSize);
+
+    expect(snapshotGraph.classes.length > 0, isTrue);
+    snapshotGraph.classes.forEach((HeapSnapshotClass c) {
+      expect(c.name, isNotNull);
+      expect(c.libraryName, isNotNull);
+      expect(c.libraryUri, isNotNull);
+      expect(c.fields, isNotNull);
+    });
+  },
+];
+
+main(args) async => runIsolateTests(args, tests, testeeBefore: script);
diff --git a/pkg/vm_service/tool/dart/generate_dart.dart b/pkg/vm_service/tool/dart/generate_dart.dart
index 58607c9..6c01c9c 100644
--- a/pkg/vm_service/tool/dart/generate_dart.dart
+++ b/pkg/vm_service/tool/dart/generate_dart.dart
@@ -55,6 +55,14 @@
 import 'src/service_extension_registry.dart';
 
 export 'src/service_extension_registry.dart' show ServiceExtensionRegistry;
+export 'src/snapshot_graph.dart' show HeapSnapshotClass,
+                                      HeapSnapshotExternalProperty,
+                                      HeapSnapshotField,
+                                      HeapSnapshotGraph,
+                                      HeapSnapshotObject,
+                                      HeapSnapshotObjectLengthData,
+                                      HeapSnapshotObjectNoData,
+                                      HeapSnapshotObjectNullData;
 ''';
 
 final String _implCode = r'''
@@ -143,20 +151,21 @@
   }
 
   void _processMessageByteData(ByteData bytes) {
-    int offset = 0;
-    int metaSize = bytes.getUint32(offset + 4, Endian.big);
-    offset += 8;
-    String meta = utf8.decode(Uint8List.view(
-        bytes.buffer, bytes.offsetInBytes + offset, metaSize));
-    offset += metaSize;
-    ByteData data = ByteData.view(bytes.buffer, bytes.offsetInBytes + offset,
-        bytes.lengthInBytes - offset);
+    final int metaOffset = 4;
+    final int dataOffset = bytes.getUint32(0, Endian.little);
+    final metaLength = dataOffset - metaOffset;
+    final dataLength = bytes.lengthInBytes - dataOffset;
+    final meta = utf8.decode(Uint8List.view(
+        bytes.buffer, bytes.offsetInBytes + metaOffset, metaLength));
+    final data = ByteData.view(
+        bytes.buffer, bytes.offsetInBytes + dataOffset, dataLength);
     dynamic map = jsonDecode(meta);
     if (map != null && map['method'] == 'streamNotify') {
       String streamId = map['params']['streamId'];
       Map event = map['params']['event'];
-      event['_data'] = data;
-      _getEventController(streamId).add(createServiceObject(event, const ['Event']));
+      event['data'] = data;
+      _getEventController(streamId)
+          .add(createServiceObject(event, const ['Event']));
     }
   }
 
@@ -1215,7 +1224,8 @@
           name == 'num' ||
           name == 'String' ||
           name == 'bool' ||
-          name == 'double');
+          name == 'double' ||
+          name == 'ByteData');
 
   bool get isListTypeSimple =>
       arrayDepth == 1 &&
@@ -1223,7 +1233,8 @@
           name == 'num' ||
           name == 'String' ||
           name == 'bool' ||
-          name == 'double');
+          name == 'double' ||
+          name == 'ByteData');
 
   String toString() => ref;
 }
@@ -1929,6 +1940,18 @@
       expect(';');
     }
 
+    // Special case for Event in order to expose binary response for
+    // HeapSnapshot events.
+    if (type.rawName == 'Event') {
+      final comment = 'Binary data associated with the event.\n\n'
+          'This is provided for the event kinds:\n  - HeapSnapshot';
+      TypeField dataField = TypeField(type, comment);
+      dataField.type.types.add(TypeRef('ByteData'));
+      dataField.name = 'data';
+      dataField.optional = true;
+      type.fields.add(dataField);
+    }
+
     expect('}');
   }
 }
diff --git a/runtime/BUILD.gn b/runtime/BUILD.gn
index a3cc367..41776f5 100644
--- a/runtime/BUILD.gn
+++ b/runtime/BUILD.gn
@@ -2,7 +2,6 @@
 # for details. All rights reserved. Use of this source code is governed by a
 # BSD-style license that can be found in the LICENSE file.
 
-import("../build/dart/dart_host_sdk_toolchain.gni")
 import("configs.gni")
 import("runtime_args.gni")
 
@@ -67,28 +66,22 @@
 config("dart_os_config") {
   defines = []
 
-  # If dart_host_toolchain is the current toolchain, and it is different from
-  # host_toolchain, then we are building the SDK for the host, and should not
-  # hardcode these defines.
-  if (current_toolchain != dart_host_toolchain ||
-      host_toolchain == dart_host_toolchain) {
-    if (target_os == "android") {
-      defines += [ "TARGET_OS_ANDROID" ]
-    } else if (target_os == "fuchsia") {
-      defines += [ "TARGET_OS_FUCHSIA" ]
-    } else if (target_os == "ios") {
-      defines += [ "TARGET_OS_MACOS" ]
-      defines += [ "TARGET_OS_MACOS_IOS" ]
-    } else if (target_os == "linux") {
-      defines += [ "TARGET_OS_LINUX" ]
-    } else if (target_os == "mac") {
-      defines += [ "TARGET_OS_MACOS" ]
-    } else if (target_os == "win") {
-      defines += [ "TARGET_OS_WINDOWS" ]
-    } else {
-      print("Unknown target_os: $target_os")
-      assert(false)
-    }
+  if (target_os == "android") {
+    defines += [ "TARGET_OS_ANDROID" ]
+  } else if (target_os == "fuchsia") {
+    defines += [ "TARGET_OS_FUCHSIA" ]
+  } else if (target_os == "ios") {
+    defines += [ "TARGET_OS_MACOS" ]
+    defines += [ "TARGET_OS_MACOS_IOS" ]
+  } else if (target_os == "linux") {
+    defines += [ "TARGET_OS_LINUX" ]
+  } else if (target_os == "mac") {
+    defines += [ "TARGET_OS_MACOS" ]
+  } else if (target_os == "win") {
+    defines += [ "TARGET_OS_WINDOWS" ]
+  } else {
+    print("Unknown target_os: $target_os")
+    assert(false)
   }
 }
 
@@ -102,32 +95,26 @@
 config("dart_arch_config") {
   defines = []
 
-  # If dart_host_toolchain is the current toolchain, and it is different from
-  # host_toolchain, then we are building the SDK for the host, and should not
-  # hardcode these defines.
-  if (current_toolchain != dart_host_toolchain ||
-      host_toolchain == dart_host_toolchain) {
-    if (dart_target_arch == "arm") {
-      defines += [ "TARGET_ARCH_ARM" ]
-    } else if (dart_target_arch == "armv6") {
-      defines += [ "TARGET_ARCH_ARM" ]
-      defines += [ "TARGET_ARCH_ARM_6" ]
-    } else if (dart_target_arch == "armv5te") {
-      defines += [ "TARGET_ARCH_ARM" ]
-      defines += [ "TARGET_ARCH_ARM_5TE" ]
-    } else if (dart_target_arch == "arm64") {
-      defines += [ "TARGET_ARCH_ARM64" ]
-    } else if (dart_target_arch == "x64") {
-      defines += [ "TARGET_ARCH_X64" ]
-    } else if (dart_target_arch == "ia32" || dart_target_arch == "x86") {
-      defines += [ "TARGET_ARCH_IA32" ]
-    } else if (dart_target_arch == "dbc") {
-      defines += [ "TARGET_ARCH_DBC" ]
-      defines += [ "USING_SIMULATOR" ]
-    } else {
-      print("Invalid dart_target_arch: $dart_target_arch")
-      assert(false)
-    }
+  if (dart_target_arch == "arm") {
+    defines += [ "TARGET_ARCH_ARM" ]
+  } else if (dart_target_arch == "armv6") {
+    defines += [ "TARGET_ARCH_ARM" ]
+    defines += [ "TARGET_ARCH_ARM_6" ]
+  } else if (dart_target_arch == "armv5te") {
+    defines += [ "TARGET_ARCH_ARM" ]
+    defines += [ "TARGET_ARCH_ARM_5TE" ]
+  } else if (dart_target_arch == "arm64") {
+    defines += [ "TARGET_ARCH_ARM64" ]
+  } else if (dart_target_arch == "x64") {
+    defines += [ "TARGET_ARCH_X64" ]
+  } else if (dart_target_arch == "ia32" || dart_target_arch == "x86") {
+    defines += [ "TARGET_ARCH_IA32" ]
+  } else if (dart_target_arch == "dbc") {
+    defines += [ "TARGET_ARCH_DBC" ]
+    defines += [ "USING_SIMULATOR" ]
+  } else {
+    print("Invalid dart_target_arch: $dart_target_arch")
+    assert(false)
   }
 }
 
diff --git a/runtime/bin/BUILD.gn b/runtime/bin/BUILD.gn
index 6570f8b..87e6415 100644
--- a/runtime/bin/BUILD.gn
+++ b/runtime/bin/BUILD.gn
@@ -291,7 +291,10 @@
           "$fuchsia_sdk_root/pkg:fdio",
         ]
       } else {
-        deps += [ "//sdk/fidl/fuchsia.netstack" ]
+        deps += [
+          "//sdk/fidl/fuchsia.netstack",
+          "//sdk/lib/sys/cpp",
+        ]
         public_deps = [
           "//zircon/public/lib/fdio",
         ]
@@ -416,7 +419,10 @@
           "$fuchsia_sdk_root/pkg:fdio",
         ]
       } else {
-        deps += [ "//sdk/fidl/fuchsia.netstack" ]
+        deps += [
+          "//sdk/fidl/fuchsia.netstack",
+          "//sdk/lib/sys/cpp",
+        ]
         public_deps = [
           "//zircon/public/lib/fdio",
         ]
@@ -902,13 +908,12 @@
   depfile = "$target_gen_dir/gen_kernel_bytecode.dill.d"
   outputs = [
     output,
-    depfile,
   ]
 
   script = "../../pkg/vm/bin/gen_kernel.dart"
 
   abs_depfile = rebase_path(depfile)
-  rebased_output = rebase_path(output, root_out_dir)
+  rebased_output = rebase_path(output, root_build_dir)
   vm_args = [
     "--depfile=$abs_depfile",
     "--depfile_output_filename=$rebased_output",
diff --git a/runtime/bin/elf_loader.cc b/runtime/bin/elf_loader.cc
index 9672dbe..b74fe3a 100644
--- a/runtime/bin/elf_loader.cc
+++ b/runtime/bin/elf_loader.cc
@@ -224,6 +224,7 @@
 bool LoadedElf::LoadSegments() {
   // Calculate the total amount of virtual memory needed.
   uword total_memory = 0;
+  uword maximum_alignment = PageSize();
   for (uword i = 0; i < header_.num_program_headers; ++i) {
     const dart::elf::ProgramHeader header = program_table_[i];
 
@@ -235,13 +236,13 @@
         total_memory);
     CHECK_ERROR(Utils::IsPowerOfTwo(header.alignment),
                 "Alignment must be a power of two.");
-    CHECK_ERROR(header.alignment <= PageSize(),
-                "Cannot align greater than page size.")
+    maximum_alignment =
+        Utils::Maximum(maximum_alignment, static_cast<uword>(header.alignment));
   }
   total_memory = Utils::RoundUp(total_memory, PageSize());
 
   base_.reset(VirtualMemory::AllocateAligned(
-      total_memory, /*alignment=*/PageSize(),
+      total_memory, /*alignment=*/maximum_alignment,
       /*is_executable=*/false, /*mapping name=*/filename_.get()));
   CHECK_ERROR(base_ != nullptr, "Could not reserve virtual memory.");
 
diff --git a/runtime/bin/gen_snapshot.cc b/runtime/bin/gen_snapshot.cc
index d7a2a4e..b497db8 100644
--- a/runtime/bin/gen_snapshot.cc
+++ b/runtime/bin/gen_snapshot.cc
@@ -745,8 +745,8 @@
     isolate_flags.entry_points = no_entry_points;
   }
 
-  auto isolate_group_data =
-      new IsolateGroupData(nullptr, nullptr, nullptr, nullptr, false);
+  auto isolate_group_data = std::unique_ptr<IsolateGroupData>(
+      new IsolateGroupData(nullptr, nullptr, nullptr, nullptr, false));
   Dart_Isolate isolate;
   char* error = NULL;
   if (isolate_snapshot_data == NULL) {
@@ -755,17 +755,17 @@
     isolate_flags.load_vmservice_library = true;
     isolate = Dart_CreateIsolateGroupFromKernel(
         NULL, NULL, kernel_buffer, kernel_buffer_size, &isolate_flags,
-        isolate_group_data, /*isolate_data=*/nullptr, &error);
+        isolate_group_data.get(), /*isolate_data=*/nullptr, &error);
   } else {
     isolate = Dart_CreateIsolateGroup(NULL, NULL, isolate_snapshot_data,
                                       isolate_snapshot_instructions, NULL, NULL,
-                                      &isolate_flags, isolate_group_data,
+                                      &isolate_flags, isolate_group_data.get(),
                                       /*isolate_data=*/nullptr, &error);
   }
   if (isolate == NULL) {
-    delete isolate_group_data;
     Syslog::PrintErr("%s\n", error);
     free(error);
+    free(kernel_buffer);
     return kErrorExitCode;
   }
 
@@ -827,6 +827,8 @@
 
   Dart_ExitScope();
   Dart_ShutdownIsolate();
+
+  free(kernel_buffer);
   return 0;
 }
 
diff --git a/runtime/lib/wasm.cc b/runtime/lib/wasm.cc
index a94aac9..0094e6b 100644
--- a/runtime/lib/wasm.cc
+++ b/runtime/lib/wasm.cc
@@ -85,6 +85,54 @@
   }
 }
 
+static Dart_Handle ToWasmValue(Dart_Handle value,
+                               wasmer_value_tag type,
+                               wasmer_value* out) {
+  switch (type) {
+    case wasmer_value_tag::WASM_I32: {
+      int64_t i64;
+      Dart_Handle result = Dart_IntegerToInt64(value, &i64);
+      out->I32 = i64;
+      if (out->I32 != i64) {
+        return Dart_NewApiError("Int doesn't fit into 32-bits");
+      }
+      return result;
+    }
+    case wasmer_value_tag::WASM_I64:
+      return Dart_IntegerToInt64(value, &out->I64);
+    case wasmer_value_tag::WASM_F32: {
+      double f64;
+      Dart_Handle result = Dart_DoubleValue(value, &f64);
+      out->F32 = f64;
+      return result;
+    }
+    case wasmer_value_tag::WASM_F64:
+      return Dart_DoubleValue(value, &out->F64);
+    default:
+      FATAL("Unknown WASM type");
+      return nullptr;
+  }
+}
+
+static bool ToWasmValueTag(classid_t type, wasmer_value_tag* out) {
+  switch (type) {
+    case kWasmInt32Cid:
+      *out = wasmer_value_tag::WASM_I32;
+      return true;
+    case kWasmInt64Cid:
+      *out = wasmer_value_tag::WASM_I64;
+      return true;
+    case kWasmFloatCid:
+      *out = wasmer_value_tag::WASM_F32;
+      return true;
+    case kWasmDoubleCid:
+      *out = wasmer_value_tag::WASM_F64;
+      return true;
+    default:
+      return false;
+  }
+}
+
 static RawObject* ToDartObject(wasmer_value_t ret) {
   switch (ret.tag) {
     case wasmer_value_tag::WASM_I32:
@@ -101,6 +149,22 @@
   }
 }
 
+static Dart_Handle ToDartApiObject(wasmer_value value, wasmer_value_tag type) {
+  switch (type) {
+    case wasmer_value_tag::WASM_I32:
+      return Dart_NewInteger(value.I32);
+    case wasmer_value_tag::WASM_I64:
+      return Dart_NewInteger(value.I64);
+    case wasmer_value_tag::WASM_F32:
+      return Dart_NewDouble(value.F32);
+    case wasmer_value_tag::WASM_F64:
+      return Dart_NewDouble(value.F64);
+    default:
+      FATAL("Unknown WASM type");
+      return nullptr;
+  }
+}
+
 RawExternalTypedData* WasmMemoryToExternalTypedData(wasmer_memory_t* memory) {
   uint8_t* data = wasmer_memory_data(memory);
   uint32_t size = wasmer_memory_data_length(memory);
@@ -158,52 +222,174 @@
   return String::New(desc.str().c_str());
 }
 
+class WasmImports;
+
+struct WasmFunctionImport {
+  WasmImports* imports;
+  std::unique_ptr<wasmer_value_tag[]> args;
+  intptr_t num_args;
+  wasmer_value_tag ret;
+  intptr_t num_rets;
+  int64_t fn_id;
+  wasmer_import_func_t* wasm_fn;
+  wasmer_trampoline_buffer_t* buffer;
+  WasmFunctionImport(WasmImports* imports_,
+                     std::unique_ptr<wasmer_value_tag[]> args_,
+                     intptr_t num_args_,
+                     wasmer_value_tag ret_,
+                     intptr_t num_rets_,
+                     int64_t fn_id_)
+      : imports(imports_),
+        args(std::move(args_)),
+        num_args(num_args_),
+        ret(ret_),
+        num_rets(num_rets_),
+        fn_id(fn_id_),
+        wasm_fn(nullptr),
+        buffer(nullptr) {}
+  ~WasmFunctionImport() {
+    wasmer_trampoline_buffer_destroy(buffer);
+    wasmer_import_func_destroy(wasm_fn);
+  }
+};
+
+extern "C" {
+int64_t Trampoline(void* context, int64_t* args);
+}
+
 class WasmImports {
  public:
-  explicit WasmImports(std::unique_ptr<char[]> module_name)
-      : _module_name(std::move(module_name)) {}
+  WasmImports() {}
 
   ~WasmImports() {
     for (wasmer_global_t* global : _globals) {
       wasmer_global_destroy(global);
     }
+    for (WasmFunctionImport* fn_imp : _functions) {
+      delete fn_imp;
+    }
     for (const char* name : _import_names) {
       delete[] name;
     }
   }
 
+  void SetHandle(FinalizablePersistentHandle* handle) { _handle = handle; }
   size_t NumImports() const { return _imports.length(); }
   wasmer_import_t* RawImports() { return _imports.data(); }
 
-  void AddMemory(std::unique_ptr<char[]> name, wasmer_memory_t* memory) {
-    AddImport(std::move(name), wasmer_import_export_kind::WASM_MEMORY)->memory =
-        memory;
+  void AddMemory(std::unique_ptr<char[]> module_name,
+                 std::unique_ptr<char[]> name,
+                 wasmer_memory_t* memory) {
+    AddImport(std::move(module_name), std::move(name),
+              wasmer_import_export_kind::WASM_MEMORY)
+        ->memory = memory;
   }
 
-  void AddGlobal(std::unique_ptr<char[]> name,
+  void AddGlobal(std::unique_ptr<char[]> module_name,
+                 std::unique_ptr<char[]> name,
                  wasmer_value_t value,
                  bool mutable_) {
     wasmer_global_t* global = wasmer_global_new(value, mutable_);
     _globals.Add(global);
-    AddImport(std::move(name), wasmer_import_export_kind::WASM_GLOBAL)->global =
-        global;
+    AddImport(std::move(module_name), std::move(name),
+              wasmer_import_export_kind::WASM_GLOBAL)
+        ->global = global;
+  }
+
+  void AddFunction(std::unique_ptr<char[]> module_name,
+                   std::unique_ptr<char[]> name,
+                   int64_t fn_id,
+                   std::unique_ptr<wasmer_value_tag[]> args,
+                   intptr_t num_args,
+                   wasmer_value_tag ret,
+                   intptr_t num_rets) {
+    // Trampoline args include the context pointer.
+    const intptr_t num_trampoline_args = num_args + 1;
+
+    WasmFunctionImport* fn_imp = new WasmFunctionImport(
+        this, std::move(args), num_args, ret, num_rets, fn_id);
+    _functions.Add(fn_imp);
+
+    wasmer_trampoline_buffer_builder_t* builder =
+        wasmer_trampoline_buffer_builder_new();
+    uintptr_t trampoline_id =
+        wasmer_trampoline_buffer_builder_add_callinfo_trampoline(
+            builder,
+            reinterpret_cast<wasmer_trampoline_callable_t*>(Trampoline),
+            reinterpret_cast<void*>(fn_imp), num_trampoline_args);
+    fn_imp->buffer = wasmer_trampoline_buffer_builder_build(builder);
+
+    const wasmer_trampoline_callable_t* trampoline =
+        wasmer_trampoline_buffer_get_trampoline(fn_imp->buffer, trampoline_id);
+    fn_imp->wasm_fn = wasmer_import_func_new(
+        reinterpret_cast<void (*)(void*)>(
+            const_cast<wasmer_trampoline_callable_t*>(trampoline)),
+        fn_imp->args.get(), num_args, &ret, num_rets);
+
+    AddImport(std::move(module_name), std::move(name),
+              wasmer_import_export_kind::WASM_FUNCTION)
+        ->func = fn_imp->wasm_fn;
+  }
+
+  int64_t CallImportedFunction(WasmFunctionImport* fn_imp, int64_t* raw_args) {
+    wasmer_value* wasm_args = reinterpret_cast<wasmer_value*>(raw_args);
+    Dart_Handle inst = Dart_HandleFromWeakPersistent(_handle->apiHandle());
+    Dart_Handle dart_args[2] = {
+        inst,
+        Dart_NewInteger(fn_imp->fn_id),
+    };
+    Dart_Handle closure = Dart_Invoke(Dart_InstanceGetType(inst),
+                                      Dart_NewStringFromCString("getFunction"),
+                                      ARRAY_SIZE(dart_args), dart_args);
+    if (Dart_IsError(closure)) {
+      Dart_ThrowException(closure);
+      UNREACHABLE();
+    }
+    Dart_Handle result;
+    {
+      auto args =
+          std::unique_ptr<Dart_Handle[]>(new Dart_Handle[fn_imp->num_args]);
+      for (intptr_t i = 0; i < fn_imp->num_args; ++i) {
+        args[i] = ToDartApiObject(wasm_args[i], fn_imp->args[i]);
+      }
+      result = Dart_InvokeClosure(closure, fn_imp->num_args, args.get());
+    }
+    if (Dart_IsError(result)) {
+      Dart_ThrowException(result);
+      UNREACHABLE();
+    }
+    if (fn_imp->num_rets == 0) {
+      // Wasmer ignores the result of this function if it expects no results,
+      // so skip the converters below (we get errors if we run them).
+      return 0;
+    }
+    wasmer_value wasm_result;
+    result = ToWasmValue(result, fn_imp->ret, &wasm_result);
+    if (Dart_IsError(result)) {
+      Dart_ThrowException(result);
+      UNREACHABLE();
+    }
+    return wasm_result.I64;
   }
 
  private:
-  std::unique_ptr<char[]> _module_name;
+  FinalizablePersistentHandle* _handle;
   MallocGrowableArray<const char*> _import_names;
   MallocGrowableArray<wasmer_global_t*> _globals;
+  MallocGrowableArray<WasmFunctionImport*> _functions;
   MallocGrowableArray<wasmer_import_t> _imports;
 
-  wasmer_import_export_value* AddImport(std::unique_ptr<char[]> name,
+  wasmer_import_export_value* AddImport(std::unique_ptr<char[]> module_name,
+                                        std::unique_ptr<char[]> name,
                                         wasmer_import_export_kind tag) {
     wasmer_import_t import;
     import.module_name.bytes =
-        reinterpret_cast<const uint8_t*>(_module_name.get());
-    import.module_name.bytes_len = (uint32_t)strlen(_module_name.get());
+        reinterpret_cast<const uint8_t*>(module_name.get());
+    import.module_name.bytes_len = (uint32_t)strlen(module_name.get());
     import.import_name.bytes = reinterpret_cast<const uint8_t*>(name.get());
     import.import_name.bytes_len = (uint32_t)strlen(name.get());
     import.tag = tag;
+    _import_names.Add(module_name.release());
     _import_names.Add(name.release());
     _imports.Add(import);
     return &_imports.Last().value;
@@ -212,6 +398,14 @@
   DISALLOW_COPY_AND_ASSIGN(WasmImports);
 };
 
+extern "C" {
+int64_t Trampoline(void* context, int64_t* args) {
+  WasmFunctionImport* fn_imp = reinterpret_cast<WasmFunctionImport*>(context);
+  // Skip the first arg (it's another context pointer).
+  return fn_imp->imports->CallImportedFunction(fn_imp, args + 1);
+}
+}
+
 class WasmFunction {
  public:
   WasmFunction(MallocGrowableArray<classid_t> args,
@@ -459,25 +653,26 @@
   return DescribeModule(module);
 }
 
-DEFINE_NATIVE_ENTRY(Wasm_initImports, 0, 2) {
+DEFINE_NATIVE_ENTRY(Wasm_initImports, 0, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(Instance, imp_wrap, arguments->NativeArgAt(0));
-  GET_NON_NULL_NATIVE_ARGUMENT(String, module_name, arguments->NativeArgAt(1));
 
   ASSERT(imp_wrap.NumNativeFields() == 1);
 
-  WasmImports* imports = new WasmImports(ToUTF8(module_name));
+  WasmImports* imports = new WasmImports();
 
   imp_wrap.SetNativeField(0, reinterpret_cast<intptr_t>(imports));
-  FinalizablePersistentHandle::New(thread->isolate(), imp_wrap, imports,
-                                   Finalize<WasmImports>, sizeof(WasmImports));
+  imports->SetHandle(FinalizablePersistentHandle::New(
+      thread->isolate(), imp_wrap, imports, Finalize<WasmImports>,
+      sizeof(WasmImports)));
 
   return Object::null();
 }
 
-DEFINE_NATIVE_ENTRY(Wasm_addMemoryImport, 0, 3) {
+DEFINE_NATIVE_ENTRY(Wasm_addMemoryImport, 0, 4) {
   GET_NON_NULL_NATIVE_ARGUMENT(Instance, imp_wrap, arguments->NativeArgAt(0));
-  GET_NON_NULL_NATIVE_ARGUMENT(String, name, arguments->NativeArgAt(1));
-  GET_NON_NULL_NATIVE_ARGUMENT(Instance, mem_wrap, arguments->NativeArgAt(2));
+  GET_NON_NULL_NATIVE_ARGUMENT(String, module_name, arguments->NativeArgAt(1));
+  GET_NON_NULL_NATIVE_ARGUMENT(String, name, arguments->NativeArgAt(2));
+  GET_NON_NULL_NATIVE_ARGUMENT(Instance, mem_wrap, arguments->NativeArgAt(3));
 
   ASSERT(imp_wrap.NumNativeFields() == 1);
   ASSERT(mem_wrap.NumNativeFields() == 1);
@@ -487,17 +682,18 @@
   wasmer_memory_t* memory =
       reinterpret_cast<wasmer_memory_t*>(mem_wrap.GetNativeField(0));
 
-  imports->AddMemory(ToUTF8(name), memory);
+  imports->AddMemory(ToUTF8(module_name), ToUTF8(name), memory);
 
   return Object::null();
 }
 
-DEFINE_NATIVE_ENTRY(Wasm_addGlobalImport, 0, 5) {
+DEFINE_NATIVE_ENTRY(Wasm_addGlobalImport, 0, 6) {
   GET_NON_NULL_NATIVE_ARGUMENT(Instance, imp_wrap, arguments->NativeArgAt(0));
-  GET_NON_NULL_NATIVE_ARGUMENT(String, name, arguments->NativeArgAt(1));
-  GET_NON_NULL_NATIVE_ARGUMENT(Number, value, arguments->NativeArgAt(2));
-  GET_NON_NULL_NATIVE_ARGUMENT(Type, type, arguments->NativeArgAt(3));
-  GET_NON_NULL_NATIVE_ARGUMENT(Bool, mutable_, arguments->NativeArgAt(4));
+  GET_NON_NULL_NATIVE_ARGUMENT(String, module_name, arguments->NativeArgAt(1));
+  GET_NON_NULL_NATIVE_ARGUMENT(String, name, arguments->NativeArgAt(2));
+  GET_NON_NULL_NATIVE_ARGUMENT(Number, value, arguments->NativeArgAt(3));
+  GET_NON_NULL_NATIVE_ARGUMENT(Type, type, arguments->NativeArgAt(4));
+  GET_NON_NULL_NATIVE_ARGUMENT(Bool, mutable_, arguments->NativeArgAt(5));
 
   ASSERT(imp_wrap.NumNativeFields() == 1);
 
@@ -505,12 +701,62 @@
       reinterpret_cast<WasmImports*>(imp_wrap.GetNativeField(0));
   wasmer_value_t wasm_value;
   if (!ToWasmValue(value, type.type_class_id(), &wasm_value)) {
-    Exceptions::ThrowArgumentError(String::Handle(String::NewFormatted(
-        "Can't convert dart value to WASM global variable")));
+    Exceptions::ThrowArgumentError(String::Handle(
+        zone, String::NewFormatted(
+                  "Can't convert dart value to WASM global variable")));
     UNREACHABLE();
   }
 
-  imports->AddGlobal(ToUTF8(name), wasm_value, mutable_.value());
+  imports->AddGlobal(ToUTF8(module_name), ToUTF8(name), wasm_value,
+                     mutable_.value());
+
+  return Object::null();
+}
+
+DEFINE_NATIVE_ENTRY(Wasm_addFunctionImport, 0, 5) {
+  GET_NON_NULL_NATIVE_ARGUMENT(Instance, imp_wrap, arguments->NativeArgAt(0));
+  GET_NON_NULL_NATIVE_ARGUMENT(String, module_name, arguments->NativeArgAt(1));
+  GET_NON_NULL_NATIVE_ARGUMENT(String, name, arguments->NativeArgAt(2));
+  GET_NON_NULL_NATIVE_ARGUMENT(Integer, fn_id, arguments->NativeArgAt(3));
+  GET_NON_NULL_NATIVE_ARGUMENT(Type, fn_type, arguments->NativeArgAt(4));
+
+  ASSERT(imp_wrap.NumNativeFields() == 1);
+
+  Function& sig = Function::Handle(zone, fn_type.signature());
+
+  classid_t ret = AbstractType::Handle(zone, sig.result_type()).type_class_id();
+  intptr_t num_rets = ret == kWasmVoidCid ? 0 : 1;
+  wasmer_value_tag wasm_ret = wasmer_value_tag::WASM_I64;
+  if (num_rets != 0) {
+    if (!ToWasmValueTag(ret, &wasm_ret)) {
+      Exceptions::ThrowArgumentError(String::Handle(
+          zone, String::NewFormatted("Return type is not a valid WASM type")));
+      UNREACHABLE();
+    }
+  }
+
+  Array& args = Array::Handle(zone, sig.parameter_types());
+  AbstractType& arg_type = AbstractType::Handle(zone);
+  intptr_t first_arg_index = sig.NumImplicitParameters();
+  intptr_t num_args = args.Length() - first_arg_index;
+  auto wasm_args =
+      std::unique_ptr<wasmer_value_tag[]>(new wasmer_value_tag[num_args]);
+  for (intptr_t i = 0; i < num_args; ++i) {
+    arg_type ^= args.At(i + first_arg_index);
+    classid_t dart_arg = arg_type.type_class_id();
+    if (!ToWasmValueTag(dart_arg, &wasm_args[i])) {
+      wasm_args.reset();
+      Exceptions::ThrowArgumentError(String::Handle(
+          zone, String::NewFormatted(
+                    "Type of arg %" Pd " is not a valid WASM type", i)));
+      UNREACHABLE();
+    }
+  }
+
+  WasmImports* imports =
+      reinterpret_cast<WasmImports*>(imp_wrap.GetNativeField(0));
+  imports->AddFunction(ToUTF8(module_name), ToUTF8(name), fn_id.AsInt64Value(),
+                       std::move(wasm_args), num_args, wasm_ret, num_rets);
 
   return Object::null();
 }
@@ -610,15 +856,16 @@
   String& error = String::Handle(zone);
 
   {
-    Function& sig = Function::Handle(fn_type.signature());
-    Array& args = Array::Handle(sig.parameter_types());
+    Function& sig = Function::Handle(zone, fn_type.signature());
+    Array& args = Array::Handle(zone, sig.parameter_types());
+    AbstractType& arg_type = AbstractType::Handle(zone);
     MallocGrowableArray<classid_t> dart_args;
     for (intptr_t i = sig.NumImplicitParameters(); i < args.Length(); ++i) {
-      dart_args.Add(
-          AbstractType::Cast(Object::Handle(args.At(i))).type_class_id());
+      arg_type ^= args.At(i);
+      dart_args.Add(arg_type.type_class_id());
     }
     classid_t dart_ret =
-        AbstractType::Handle(sig.result_type()).type_class_id();
+        AbstractType::Handle(zone, sig.result_type()).type_class_id();
 
     std::unique_ptr<char[]> name_raw = ToUTF8(name);
     fn = inst->GetFunction(name_raw.get(), dart_args, dart_ret, &error);
@@ -643,19 +890,21 @@
   WasmFunction* fn = reinterpret_cast<WasmFunction*>(fn_wrap.GetNativeField(0));
 
   if (args.Length() != fn->args().length()) {
-    Exceptions::ThrowArgumentError(String::Handle(String::NewFormatted(
-        "Wrong number of args. Expected %" Pu " but found %" Pd ".",
-        fn->args().length(), args.Length())));
+    Exceptions::ThrowArgumentError(String::Handle(
+        zone, String::NewFormatted("Wrong number of args. Expected %" Pu
+                                   " but found %" Pd ".",
+                                   fn->args().length(), args.Length())));
     UNREACHABLE();
   }
   auto params = std::unique_ptr<wasmer_value_t[]>(
       new wasmer_value_t[fn->args().length()]);
+  Number& arg_num = Number::Handle(zone);
   for (intptr_t i = 0; i < args.Length(); ++i) {
-    if (!ToWasmValue(Number::Cast(Object::Handle(args.At(i))), fn->args()[i],
-                     &params[i])) {
+    arg_num ^= args.At(i);
+    if (!ToWasmValue(arg_num, fn->args()[i], &params[i])) {
       params.reset();
       Exceptions::ThrowArgumentError(String::Handle(
-          String::NewFormatted("Arg %" Pd " is the wrong type.", i)));
+          zone, String::NewFormatted("Arg %" Pd " is the wrong type.", i)));
       UNREACHABLE();
     }
   }
@@ -694,17 +943,22 @@
   return nullptr;
 }
 
-DEFINE_NATIVE_ENTRY(Wasm_initImports, 0, 2) {
+DEFINE_NATIVE_ENTRY(Wasm_initImports, 0, 1) {
   Exceptions::ThrowUnsupportedError("WASM is disabled");
   return nullptr;
 }
 
-DEFINE_NATIVE_ENTRY(Wasm_addMemoryImport, 0, 3) {
+DEFINE_NATIVE_ENTRY(Wasm_addMemoryImport, 0, 4) {
   Exceptions::ThrowUnsupportedError("WASM is disabled");
   return nullptr;
 }
 
-DEFINE_NATIVE_ENTRY(Wasm_addGlobalImport, 0, 5) {
+DEFINE_NATIVE_ENTRY(Wasm_addGlobalImport, 0, 6) {
+  Exceptions::ThrowUnsupportedError("WASM is disabled");
+  return nullptr;
+}
+
+DEFINE_NATIVE_ENTRY(Wasm_addFunctionImport, 0, 5) {
   Exceptions::ThrowUnsupportedError("WASM is disabled");
   return nullptr;
 }
diff --git a/runtime/tools/dartfuzz/dartfuzz.dart b/runtime/tools/dartfuzz/dartfuzz.dart
index 56730f1..21f0a79 100644
--- a/runtime/tools/dartfuzz/dartfuzz.dart
+++ b/runtime/tools/dartfuzz/dartfuzz.dart
@@ -9,12 +9,12 @@
 
 import 'dartfuzz_values.dart';
 import 'dartfuzz_api_table.dart';
-import 'dartfuzz_ffiapi.dart';
+import 'dartfuzz_ffi_api.dart';
 
 // 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.52';
+const String version = '1.53';
 
 // Restriction on statements and expressions.
 const int stmtDepth = 1;
@@ -542,13 +542,18 @@
       emit('X${classFields.length - 1}().run()');
     }, () {
       emitLn("print('X${classFields.length - 1}().run() throws');");
-    }, finallyBody: () {
-      emitLn("print('", newline: false);
+    });
+
+    emitTryCatchFinally(() {
+      emit("print('", newline: false);
       for (int i = 0; i < globalVars.length; i++) {
         emit('\$$varName$i\\n');
       }
-      emit("');", newline: true);
+      emit("')");
+    }, () {
+      emitLn("print('print throws');");
     });
+
     indent -= 2;
     emitLn('}');
   }
diff --git a/runtime/tools/dartfuzz/dartfuzz_ffiapi.dart b/runtime/tools/dartfuzz/dartfuzz_ffi_api.dart
similarity index 100%
rename from runtime/tools/dartfuzz/dartfuzz_ffiapi.dart
rename to runtime/tools/dartfuzz/dartfuzz_ffi_api.dart
diff --git a/runtime/vm/bootstrap_natives.h b/runtime/vm/bootstrap_natives.h
index 336163a..f3ae235 100644
--- a/runtime/vm/bootstrap_natives.h
+++ b/runtime/vm/bootstrap_natives.h
@@ -393,9 +393,10 @@
   V(TransferableTypedData_materialize, 1)                                      \
   V(Wasm_initModule, 2)                                                        \
   V(Wasm_describeModule, 1)                                                    \
-  V(Wasm_initImports, 2)                                                       \
-  V(Wasm_addMemoryImport, 3)                                                   \
-  V(Wasm_addGlobalImport, 5)                                                   \
+  V(Wasm_initImports, 1)                                                       \
+  V(Wasm_addMemoryImport, 4)                                                   \
+  V(Wasm_addGlobalImport, 6)                                                   \
+  V(Wasm_addFunctionImport, 5)                                                 \
   V(Wasm_initMemory, 3)                                                        \
   V(Wasm_growMemory, 2)                                                        \
   V(Wasm_initInstance, 3)                                                      \
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
index c142b3f..80df237 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
@@ -1323,6 +1323,13 @@
   return kLegacy;
 }
 
+Variance KernelReaderHelper::ReadVariance() {
+  if (translation_helper_.info().kernel_binary_version() >= 34) {
+    return reader_.ReadVariance();
+  }
+  return kCovariant;
+}
+
 void StreamingFlowGraphBuilder::loop_depth_inc() {
   ++flow_graph_builder_->loop_depth_;
 }
diff --git a/runtime/vm/compiler/frontend/kernel_fingerprints.cc b/runtime/vm/compiler/frontend/kernel_fingerprints.cc
index a6b9762..d089309 100644
--- a/runtime/vm/compiler/frontend/kernel_fingerprints.cc
+++ b/runtime/vm/compiler/frontend/kernel_fingerprints.cc
@@ -163,6 +163,11 @@
   CalculateListOfExpressionsFingerprint();
   helper.SetJustRead(TypeParameterHelper::kAnnotations);
 
+  helper.ReadUntilExcluding(TypeParameterHelper::kVariance);
+  Variance variance = ReadVariance();
+  BuildHash(variance);
+  helper.SetJustRead(TypeParameterHelper::kVariance);
+
   helper.ReadUntilExcluding(TypeParameterHelper::kBound);
   // The helper isn't needed after this point.
   CalculateDartTypeFingerprint();
diff --git a/runtime/vm/compiler/frontend/kernel_translation_helper.cc b/runtime/vm/compiler/frontend/kernel_translation_helper.cc
index eb23c65..e5b6bf2 100644
--- a/runtime/vm/compiler/frontend/kernel_translation_helper.cc
+++ b/runtime/vm/compiler/frontend/kernel_translation_helper.cc
@@ -911,6 +911,9 @@
       case kAnnotations:
         helper_->SkipListOfExpressions();  // read annotations.
         break;
+      case kVariance:
+        helper_->ReadVariance();
+        break;
       case kName:
         name_index_ = helper_->ReadStringReference();  // read name index.
         break;
diff --git a/runtime/vm/compiler/frontend/kernel_translation_helper.h b/runtime/vm/compiler/frontend/kernel_translation_helper.h
index 6187caa..b8152f4 100644
--- a/runtime/vm/compiler/frontend/kernel_translation_helper.h
+++ b/runtime/vm/compiler/frontend/kernel_translation_helper.h
@@ -317,6 +317,7 @@
     kStart,  // tag.
     kFlags,
     kAnnotations,
+    kVariance,
     kName,
     kBound,
     kDefaultType,
@@ -1087,6 +1088,7 @@
   Tag ReadTag(uint8_t* payload = NULL);
   uint8_t ReadFlags() { return reader_.ReadFlags(); }
   Nullability ReadNullability();
+  Variance ReadVariance();
 
   intptr_t SourceTableSize();
   intptr_t GetOffsetForSourceInfo(intptr_t index);
diff --git a/runtime/vm/compiler/recognized_methods_list.h b/runtime/vm/compiler/recognized_methods_list.h
index 3af03f5..848564d 100644
--- a/runtime/vm/compiler/recognized_methods_list.h
+++ b/runtime/vm/compiler/recognized_methods_list.h
@@ -15,8 +15,8 @@
   V(::, identical, ObjectIdentical, 0xc6e9467a)                                \
   V(ClassID, getID, ClassIDgetID, 0xf0376ced)                                  \
   V(Object, Object., ObjectConstructor, 0x8f3ae7ea)                            \
-  V(List, ., ListFactory, 0xd834242d)                                          \
-  V(_List, ., ObjectArrayAllocate, 0xe9c6d2be)                                 \
+  V(List, ., ListFactory, 0xda0d774c)                                          \
+  V(_List, ., ObjectArrayAllocate, 0x704c8d5d)                                 \
   V(_TypedList, _getInt8, ByteArrayBaseGetInt8, 0xa24c2704)                    \
   V(_TypedList, _getUint8, ByteArrayBaseGetUint8, 0xa491df3e)                  \
   V(_TypedList, _getInt16, ByteArrayBaseGetInt16, 0xb65ae1fc)                  \
@@ -69,8 +69,8 @@
   V(_Double, _sub, DoubleSub, 0x6d3cec71)                                      \
   V(_Double, _mul, DoubleMul, 0x648e67af)                                      \
   V(_Double, _div, DoubleDiv, 0x6d72d7d4)                                      \
-  V(::, min, MathMin, 0x07168bf9)                                              \
-  V(::, max, MathMax, 0xc7dbc9a0)                                              \
+  V(::, min, MathMin, 0x3ccbc098)                                              \
+  V(::, max, MathMax, 0x4e398e7f)                                              \
   V(::, _doublePow, MathDoublePow, 0x5ae04e61)                                 \
   V(::, _intPow, MathIntPow, 0x569ffd3f)                                       \
   V(Float32x4, Float32x4., Float32x4Constructor, 0xdf9f0693)                   \
@@ -143,8 +143,8 @@
   V(::, _classRangeCheck, ClassRangeCheck, 0xca52e30a)                         \
   V(::, _asyncStackTraceHelper, AsyncStackTraceHelper, 0xaeaed5cb)             \
   V(::, _abi, FfiAbi, 0xf2e89620)                                              \
-  V(::, _asFunctionInternal, FfiAsFunctionInternal, 0x82525e9e)                \
-  V(::, _nativeCallbackFunction, FfiNativeCallbackFunction, 0x591fb33c)        \
+  V(::, _asFunctionInternal, FfiAsFunctionInternal, 0x92a67518)                \
+  V(::, _nativeCallbackFunction, FfiNativeCallbackFunction, 0x59cc5edb)        \
 
 // List of intrinsics:
 // (class-name, function-name, intrinsification method, fingerprint).
@@ -177,7 +177,7 @@
   V(_Double, get:isNegative, Double_getIsNegative, 0xb15ff274)                 \
   V(_Double, _mulFromInteger, Double_mulFromInteger, 0xe2853768)               \
   V(_Double, .fromInteger, DoubleFromInteger, 0x89504536)                      \
-  V(_GrowableList, ._withData, GrowableArray_Allocate, 0x55981e03)             \
+  V(_GrowableList, ._withData, GrowableArray_Allocate, 0x57717122)             \
   V(_RegExp, _ExecuteMatch, RegExp_ExecuteMatch, 0xb961fc8d)                   \
   V(_RegExp, _ExecuteMatchSticky, RegExp_ExecuteMatchSticky, 0xb22daf53)       \
   V(Object, ==, ObjectEquals, 0x91ead0d6)                                      \
@@ -404,9 +404,9 @@
 // (factory-name-symbol, class-name-string, constructor-name-string,
 //  result-cid, fingerprint).
 #define RECOGNIZED_LIST_FACTORY_LIST(V)                                        \
-  V(_ListFactory, _List, ., kArrayCid, 0xe9c6d2be)                             \
+  V(_ListFactory, _List, ., kArrayCid, 0x704c8d5d)                             \
   V(_GrowableListWithData, _GrowableList, ._withData, kGrowableObjectArrayCid, \
-    0x55981e03)                                                                \
+    0x57717122)                                                                \
   V(_GrowableListFactory, _GrowableList, ., kGrowableObjectArrayCid,           \
     0x3eed680b)                                                                \
   V(_Int8ArrayFactory, Int8List, ., kTypedDataInt8ArrayCid, 0x6ce2f102)        \
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index fc85292..e78124c 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -65,6 +65,14 @@
 DECLARE_FLAG(bool, trace_service);
 DECLARE_FLAG(bool, warn_on_pause_with_no_debugger);
 
+// TODO(bkonyi): remove this flag around Nov 2019 after UX studies are
+// complete. See issue 38535.
+DEFINE_FLAG(int,
+            object_id_ring_size,
+            ObjectIdRing::kDefaultCapacity,
+            "(EXPERIMENTAL) Manually set the size of the service protocol's "
+            "object ID ring buffer. Set to be removed by Nov 2019.");
+
 // Reload flags.
 DECLARE_FLAG(int, reload_every);
 #if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
@@ -1296,7 +1304,12 @@
 
 #ifndef PRODUCT
   if (FLAG_support_service) {
-    ObjectIdRing::Init(result);
+    if (FLAG_object_id_ring_size != ObjectIdRing::kDefaultCapacity) {
+      OS::Print(
+          "WARNING: this flag is temporary, is not supported, and should"
+          " only be used for UX studies. Use at your own risk!\n");
+    }
+    ObjectIdRing::Init(result, FLAG_object_id_ring_size);
   }
 #endif  // !PRODUCT
 
diff --git a/runtime/vm/kernel_binary.h b/runtime/vm/kernel_binary.h
index 03415ac..2ed72dd 100644
--- a/runtime/vm/kernel_binary.h
+++ b/runtime/vm/kernel_binary.h
@@ -20,7 +20,7 @@
 
 // Both version numbers are inclusive.
 static const uint32_t kMinSupportedKernelFormatVersion = 18;
-static const uint32_t kMaxSupportedKernelFormatVersion = 33;
+static const uint32_t kMaxSupportedKernelFormatVersion = 34;
 
 // Keep in sync with package:kernel/lib/binary/tag.dart
 #define KERNEL_TAG_LIST(V)                                                     \
@@ -170,6 +170,14 @@
   kLegacy = 3,
 };
 
+// Keep in sync with package:kernel/lib/ast.dart
+enum Variance {
+  kUnrelated = 0,
+  kCovariant = 1,
+  kContravariant = 2,
+  kInvariant = 3,
+};
+
 static const int SpecializedIntLiteralBias = 3;
 static const int LibraryCountFieldCountFromEnd = 1;
 static const int SourceTableFieldCountFromFirstLibraryOffset = 6;
@@ -332,6 +340,11 @@
     return static_cast<Nullability>(byte);
   }
 
+  Variance ReadVariance() {
+    uint8_t byte = ReadByte();
+    return static_cast<Variance>(byte);
+  }
+
   void EnsureEnd() {
     if (offset_ != size_) {
       FATAL2(
diff --git a/runtime/vm/service/service.md b/runtime/vm/service/service.md
index c37a63f..25b08e9 100644
--- a/runtime/vm/service/service.md
+++ b/runtime/vm/service/service.md
@@ -1854,6 +1854,12 @@
   // This is provided for the event kinds:
   //   VMFlagUpdate
   String newValue [optional];
+
+  // Specifies whether this event is the last of a group of events.
+  //
+  // This is provided for the event kinds:
+  //   HeapSnapshot
+  bool last [optional];
 }
 ```
 
diff --git a/sdk/lib/_http/http_headers.dart b/sdk/lib/_http/http_headers.dart
index 7601485..0a5e478 100644
--- a/sdk/lib/_http/http_headers.dart
+++ b/sdk/lib/_http/http_headers.dart
@@ -255,7 +255,7 @@
   }
 
   ContentType get contentType {
-    var values = _headers["content-type"];
+    var values = _headers[HttpHeaders.contentTypeHeader];
     if (values != null) {
       return ContentType.parse(values[0]);
     } else {
diff --git a/sdk/lib/_http/http_impl.dart b/sdk/lib/_http/http_impl.dart
index cdf2412..46611c0 100644
--- a/sdk/lib/_http/http_impl.dart
+++ b/sdk/lib/_http/http_impl.dart
@@ -261,7 +261,7 @@
       if (hostList != null) {
         host = hostList.first;
       } else {
-        hostList = headers['host'];
+        hostList = headers[HttpHeaders.hostHeader];
         if (hostList != null) {
           host = hostList.first;
         } else {
@@ -840,7 +840,9 @@
   _HttpResponse(Uri uri, String protocolVersion, _HttpOutgoing outgoing,
       HttpHeaders defaultHeaders, String serverHeader)
       : super(uri, protocolVersion, outgoing, initialHeaders: defaultHeaders) {
-    if (serverHeader != null) headers.set('server', serverHeader);
+    if (serverHeader != null) {
+      headers.set(HttpHeaders.serverHeader, serverHeader);
+    }
   }
 
   bool get _isConnectionClosed => _httpRequest._httpConnection._isClosing;
@@ -865,7 +867,7 @@
   Future redirect(Uri location, {int status: HttpStatus.movedTemporarily}) {
     if (_outgoing.headersWritten) throw new StateError("Header already sent");
     statusCode = status;
-    headers.set("location", location.toString());
+    headers.set(HttpHeaders.locationHeader, location.toString());
     return close();
   }
 
@@ -1704,7 +1706,7 @@
       ..port = port
       .._add(HttpHeaders.acceptEncodingHeader, "gzip");
     if (_httpClient.userAgent != null) {
-      request.headers._add('user-agent', _httpClient.userAgent);
+      request.headers._add(HttpHeaders.userAgentHeader, _httpClient.userAgent);
     }
     if (proxy.isAuthenticated) {
       // If the proxy configuration contains user information use that
diff --git a/sdk/lib/_http/http_parser.dart b/sdk/lib/_http/http_parser.dart
index bd85b2b..f0444c2 100644
--- a/sdk/lib/_http/http_parser.dart
+++ b/sdk/lib/_http/http_parser.dart
@@ -658,11 +658,11 @@
           } else {
             String headerField = new String.fromCharCodes(_headerField);
             String headerValue = new String.fromCharCodes(_headerValue);
-            if (headerField == "transfer-encoding" &&
+            if (headerField == HttpHeaders.transferEncodingHeader &&
                 _caseInsensitiveCompare("chunked".codeUnits, _headerValue)) {
               _chunked = true;
             }
-            if (headerField == "connection") {
+            if (headerField == HttpHeaders.connectionHeader) {
               List<String> tokens = _tokenizeFieldValue(headerValue);
               final bool isResponse = _messageType == _MessageType.RESPONSE;
               final bool isUpgradeCode =
diff --git a/sdk/lib/_internal/js_runtime/lib/js_rti.dart b/sdk/lib/_internal/js_runtime/lib/js_rti.dart
index fd82931..f581bd8 100644
--- a/sdk/lib/_internal/js_runtime/lib/js_rti.dart
+++ b/sdk/lib/_internal/js_runtime/lib/js_rti.dart
@@ -94,7 +94,11 @@
 // more compact that the inlined expansion.
 @pragma('dart2js:noInline')
 Object setRuntimeTypeInfo(Object target, var rti) {
-  assert(rti == null || isJsArray(rti));
+  if (JS_GET_FLAG('USE_NEW_RTI')) {
+    assert(rti != null);
+  } else {
+    assert(rti == null || isJsArray(rti));
+  }
   String rtiName = JS_GET_NAME(JsGetName.RTI_NAME);
   JS('var', r'#[#] = #', target, rtiName, rti);
   return target;
diff --git a/sdk/lib/_internal/js_runtime/lib/rti.dart b/sdk/lib/_internal/js_runtime/lib/rti.dart
index 15d13e2..dba3d2a 100644
--- a/sdk/lib/_internal/js_runtime/lib/rti.dart
+++ b/sdk/lib/_internal/js_runtime/lib/rti.dart
@@ -1207,9 +1207,17 @@
   static Object typeRules(universe) =>
       JS('', '#.#', universe, RtiUniverseFieldNames.typeRules);
 
-  static Object findRule(universe, String targetType) =>
+  static Object _findRule(universe, String targetType) =>
       JS('', '#.#', typeRules(universe), targetType);
 
+  static Object findRule(universe, String targetType) {
+    Object rule = _findRule(universe, targetType);
+    while (_Utils.isString(rule)) {
+      rule = _findRule(universe, _Utils.asString(rule));
+    }
+    return rule;
+  }
+
   static void addRules(universe, rules) {
     // TODO(fishythefish): Use `Object.assign()` when IE11 is deprecated.
     var keys = JS('JSArray', 'Object.keys(#)', rules);
diff --git a/sdk/lib/_internal/vm/lib/wasm_patch.dart b/sdk/lib/_internal/vm/lib/wasm_patch.dart
index 1637384..5ae21c4 100644
--- a/sdk/lib/_internal/vm/lib/wasm_patch.dart
+++ b/sdk/lib/_internal/vm/lib/wasm_patch.dart
@@ -45,8 +45,8 @@
 @patch
 class WasmImports {
   @patch
-  factory WasmImports(String moduleName) {
-    return _NativeWasmImports(moduleName);
+  factory WasmImports() {
+    return _NativeWasmImports();
   }
 }
 
@@ -66,24 +66,42 @@
 class _NativeWasmImports extends NativeFieldWrapperClass1
     implements WasmImports {
   List<WasmMemory> _memories;
+  List<Function> _fns;
 
-  _NativeWasmImports(String moduleName) : _memories = [] {
-    _init(moduleName);
+  _NativeWasmImports()
+      : _memories = [],
+        _fns = [] {
+    _init();
   }
 
-  void addMemory(String name, WasmMemory memory) {
+  void addMemory(String moduleName, String name, WasmMemory memory) {
     _memories.add(memory);
-    _addMemory(name, memory);
+    _addMemory(moduleName, name, memory);
   }
 
-  void addGlobal<T>(String name, num value, bool mutable) {
-    _addGlobal(name, value, T, mutable);
+  void addGlobal<T>(String moduleName, String name, num value, bool mutable) {
+    _addGlobal(moduleName, name, value, T, mutable);
   }
 
-  void _init(String moduleName) native 'Wasm_initImports';
-  void _addMemory(String name, WasmMemory memory) native 'Wasm_addMemoryImport';
-  void _addGlobal(String name, num value, Type type, bool mutable)
-      native 'Wasm_addGlobalImport';
+  void addFunction<T extends Function>(
+      String moduleName, String name, Function fn) {
+    int id = _fns.length;
+    _fns.add(fn);
+    _addFunction(moduleName, name, id, T);
+  }
+
+  @pragma("vm:entry-point")
+  static Function getFunction(_NativeWasmImports imp, int id) {
+    return imp._fns[id];
+  }
+
+  void _init() native 'Wasm_initImports';
+  void _addMemory(String moduleName, String name, WasmMemory memory)
+      native 'Wasm_addMemoryImport';
+  void _addGlobal(String moduleName, String name, num value, Type type,
+      bool mutable) native 'Wasm_addGlobalImport';
+  void _addFunction(String moduleName, String name, int id, Type type)
+      native 'Wasm_addFunctionImport';
 }
 
 class _NativeWasmMemory extends NativeFieldWrapperClass1 implements WasmMemory {
diff --git a/sdk/lib/wasm/wasm.dart b/sdk/lib/wasm/wasm.dart
index 9fe5ba1..f5814ca 100644
--- a/sdk/lib/wasm/wasm.dart
+++ b/sdk/lib/wasm/wasm.dart
@@ -38,13 +38,17 @@
 // WasmImports holds all the imports for a WasmInstance.
 abstract class WasmImports {
   // Create an imports object.
-  external factory WasmImports(String moduleName);
+  external factory WasmImports();
 
   // Add a global variable to the imports.
-  void addGlobal<T>(String name, num value, bool mutable);
+  void addGlobal<T>(String moduleName, String name, num value, bool mutable);
 
   // Add a memory to the imports.
-  void addMemory(String name, WasmMemory memory);
+  void addMemory(String moduleName, String name, WasmMemory memory);
+
+  // Add a function to the imports.
+  void addFunction<T extends Function>(
+      String moduleName, String name, Function fn);
 }
 
 // WasmMemory is a sandbox for a WasmInstance to run in.
diff --git a/sdk_nnbd/lib/_http/http_headers.dart b/sdk_nnbd/lib/_http/http_headers.dart
index 58fe2af..f383790 100644
--- a/sdk_nnbd/lib/_http/http_headers.dart
+++ b/sdk_nnbd/lib/_http/http_headers.dart
@@ -257,7 +257,7 @@
   }
 
   ContentType get contentType {
-    var values = _headers["content-type"];
+    var values = _headers[HttpHeaders.contentTypeHeader];
     if (values != null) {
       return ContentType.parse(values[0]);
     } else {
diff --git a/sdk_nnbd/lib/_http/http_impl.dart b/sdk_nnbd/lib/_http/http_impl.dart
index 9741981..dbbddb6 100644
--- a/sdk_nnbd/lib/_http/http_impl.dart
+++ b/sdk_nnbd/lib/_http/http_impl.dart
@@ -263,7 +263,7 @@
       if (hostList != null) {
         host = hostList.first;
       } else {
-        hostList = headers['host'];
+        hostList = headers[HttpHeaders.hostHeader];
         if (hostList != null) {
           host = hostList.first;
         } else {
@@ -842,7 +842,9 @@
   _HttpResponse(Uri uri, String protocolVersion, _HttpOutgoing outgoing,
       HttpHeaders defaultHeaders, String serverHeader)
       : super(uri, protocolVersion, outgoing, initialHeaders: defaultHeaders) {
-    if (serverHeader != null) headers.set('server', serverHeader);
+    if (serverHeader != null) {
+      headers.set(HttpHeaders.serverHeader, serverHeader);
+    }
   }
 
   bool get _isConnectionClosed => _httpRequest._httpConnection._isClosing;
@@ -867,7 +869,7 @@
   Future redirect(Uri location, {int status: HttpStatus.movedTemporarily}) {
     if (_outgoing.headersWritten) throw new StateError("Header already sent");
     statusCode = status;
-    headers.set("location", location.toString());
+    headers.set(HttpHeaders.locationHeader, location.toString());
     return close();
   }
 
@@ -1706,7 +1708,7 @@
       ..port = port
       .._add(HttpHeaders.acceptEncodingHeader, "gzip");
     if (_httpClient.userAgent != null) {
-      request.headers._add('user-agent', _httpClient.userAgent);
+      request.headers._add(HttpHeaders.userAgentHeader, _httpClient.userAgent);
     }
     if (proxy.isAuthenticated) {
       // If the proxy configuration contains user information use that
diff --git a/sdk_nnbd/lib/_http/http_parser.dart b/sdk_nnbd/lib/_http/http_parser.dart
index f3c619d..bc5623b 100644
--- a/sdk_nnbd/lib/_http/http_parser.dart
+++ b/sdk_nnbd/lib/_http/http_parser.dart
@@ -660,11 +660,11 @@
           } else {
             String headerField = new String.fromCharCodes(_headerField);
             String headerValue = new String.fromCharCodes(_headerValue);
-            if (headerField == "transfer-encoding" &&
+            if (headerField == HttpHeaders.transferEncodingHeader &&
                 _caseInsensitiveCompare("chunked".codeUnits, _headerValue)) {
               _chunked = true;
             }
-            if (headerField == "connection") {
+            if (headerField == HttpHeaders.connectionHeader) {
               List<String> tokens = _tokenizeFieldValue(headerValue);
               final bool isResponse = _messageType == _MessageType.RESPONSE;
               final bool isUpgradeCode =
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/js_rti.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/js_rti.dart
index 9487c0d..2f06cbc 100644
--- a/sdk_nnbd/lib/_internal/js_runtime/lib/js_rti.dart
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/js_rti.dart
@@ -96,7 +96,11 @@
 // more compact that the inlined expansion.
 @pragma('dart2js:noInline')
 Object setRuntimeTypeInfo(Object target, var rti) {
-  assert(rti == null || isJsArray(rti));
+  if (JS_GET_FLAG('USE_NEW_RTI')) {
+    assert(rti != null);
+  } else {
+    assert(rti == null || isJsArray(rti));
+  }
   String rtiName = JS_GET_NAME(JsGetName.RTI_NAME);
   JS('var', r'#[#] = #', target, rtiName, rti);
   return target;
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/rti.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/rti.dart
index 67f1d0b..f74d8dd 100644
--- a/sdk_nnbd/lib/_internal/js_runtime/lib/rti.dart
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/rti.dart
@@ -1209,9 +1209,17 @@
   static Object typeRules(universe) =>
       JS('', '#.#', universe, RtiUniverseFieldNames.typeRules);
 
-  static Object findRule(universe, String targetType) =>
+  static Object _findRule(universe, String targetType) =>
       JS('', '#.#', typeRules(universe), targetType);
 
+  static Object findRule(universe, String targetType) {
+    Object rule = _findRule(universe, targetType);
+    while (_Utils.isString(rule)) {
+      rule = _findRule(universe, _Utils.asString(rule));
+    }
+    return rule;
+  }
+
   static void addRules(universe, rules) {
     // TODO(fishythefish): Use `Object.assign()` when IE11 is deprecated.
     var keys = JS('JSArray', 'Object.keys(#)', rules);
diff --git a/sdk_nnbd/lib/_internal/vm/lib/wasm_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/wasm_patch.dart
index 8339229..df3e33e 100644
--- a/sdk_nnbd/lib/_internal/vm/lib/wasm_patch.dart
+++ b/sdk_nnbd/lib/_internal/vm/lib/wasm_patch.dart
@@ -47,8 +47,8 @@
 @patch
 class WasmImports {
   @patch
-  factory WasmImports(String moduleName) {
-    return _NativeWasmImports(moduleName);
+  factory WasmImports() {
+    return _NativeWasmImports();
   }
 }
 
@@ -68,24 +68,42 @@
 class _NativeWasmImports extends NativeFieldWrapperClass1
     implements WasmImports {
   List<WasmMemory> _memories;
+  List<Function> _fns;
 
-  _NativeWasmImports(String moduleName) : _memories = [] {
-    _init(moduleName);
+  _NativeWasmImports()
+      : _memories = [],
+        _fns = [] {
+    _init();
   }
 
-  void addMemory(String name, WasmMemory memory) {
+  void addMemory(String moduleName, String name, WasmMemory memory) {
     _memories.add(memory);
-    _addMemory(name, memory);
+    _addMemory(moduleName, name, memory);
   }
 
-  void addGlobal<T>(String name, num value, bool mutable) {
-    _addGlobal(name, value, T, mutable);
+  void addGlobal<T>(String moduleName, String name, num value, bool mutable) {
+    _addGlobal(moduleName, name, value, T, mutable);
   }
 
-  void _init(String moduleName) native 'Wasm_initImports';
-  void _addMemory(String name, WasmMemory memory) native 'Wasm_addMemoryImport';
-  void _addGlobal(String name, num value, Type type, bool mutable)
-      native 'Wasm_addGlobalImport';
+  void addFunction<T extends Function>(
+      String moduleName, String name, Function fn) {
+    int id = _fns.length;
+    _fns.add(fn);
+    _addFunction(moduleName, name, id, T);
+  }
+
+  @pragma("vm:entry-point")
+  static Function getFunction(_NativeWasmImports imp, int id) {
+    return imp._fns[id];
+  }
+
+  void _init() native 'Wasm_initImports';
+  void _addMemory(String moduleName, String name, WasmMemory memory)
+      native 'Wasm_addMemoryImport';
+  void _addGlobal(String moduleName, String name, num value, Type type,
+      bool mutable) native 'Wasm_addGlobalImport';
+  void _addFunction(String moduleName, String name, int id, Type type)
+      native 'Wasm_addFunctionImport';
 }
 
 class _NativeWasmMemory extends NativeFieldWrapperClass1 implements WasmMemory {
diff --git a/sdk_nnbd/lib/core/function.dart b/sdk_nnbd/lib/core/function.dart
index 6c0462b..7c34bf5 100644
--- a/sdk_nnbd/lib/core/function.dart
+++ b/sdk_nnbd/lib/core/function.dart
@@ -47,23 +47,26 @@
   /**
    * Test whether another object is equal to this function.
    *
-   * System-created function objects are only equal to other functions.
+   * Function objects are only equal to other function objects
+   * (an object satisfying `object is Function`),
+   * and never to non-function objects.
    *
-   * Two function objects are known to represent the same function if
+   * Some function objects are considered equal by `==`
+   * because they are recognized as representing the "same function":
    *
    * - It is the same object. Static and top-level functions are compile time
    *   constants when used as values, so referring to the same function twice
-   *   always give the same object,
-   * - or if they refer to the same member method extracted from the same object.
-   *   Extracting a member method as a function value twice gives equal, but
-   *   not necessarily identical, function values.
+   *   always give the same object, as does referring to a local function
+   *   declaration twice in the same scope where it was declared.
+   * - if they refer to the same member method extracted from the same object.
+   *   Repeatedly extracting an instance method of an object as a function value
+   *   gives equal, but not necessarily identical, function values.
    *
-   * Function expressions never give rise to equal function objects. Each time
-   * a function expression is evaluated, it creates a new closure value that
-   * is not known to be equal to other closures created by the same expression.
-   *
-   * Classes implementing `Function` by having a `call` method should have their
-   * own `operator==` and `hashCode` depending on the object.
+   * Different evaluations of function literals
+   * never give rise to equal function objects.
+   * Each time a function literal is evaluated,
+   * it creates a new function value that is not equal to any other function
+   * value, not even ones created by the same expression.
    */
   bool operator ==(Object other);
 }
diff --git a/sdk_nnbd/lib/wasm/wasm.dart b/sdk_nnbd/lib/wasm/wasm.dart
index 3830d56..4394189 100644
--- a/sdk_nnbd/lib/wasm/wasm.dart
+++ b/sdk_nnbd/lib/wasm/wasm.dart
@@ -40,13 +40,17 @@
 // WasmImports holds all the imports for a WasmInstance.
 abstract class WasmImports {
   // Create an imports object.
-  external factory WasmImports(String moduleName);
+  external factory WasmImports();
 
   // Add a global variable to the imports.
-  void addGlobal<T>(String name, num value, bool mutable);
+  void addGlobal<T>(String moduleName, String name, num value, bool mutable);
 
   // Add a memory to the imports.
-  void addMemory(String name, WasmMemory memory);
+  void addMemory(String moduleName, String name, WasmMemory memory);
+
+  // Add a function to the imports.
+  void addFunction<T extends Function>(
+      String moduleName, String name, Function fn);
 }
 
 // WasmMemory is a sandbox for a WasmInstance to run in.
diff --git a/tests/language_2/extension_methods/static_extension_getter_setter_conflicts_test.dart b/tests/language_2/extension_methods/static_extension_getter_setter_conflicts_test.dart
index 664916f..ad98f03 100644
--- a/tests/language_2/extension_methods/static_extension_getter_setter_conflicts_test.dart
+++ b/tests/language_2/extension_methods/static_extension_getter_setter_conflicts_test.dart
@@ -153,11 +153,17 @@
   c1b.m1 += 0;
   //  ^^
   // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+  //  ^^
+  // [cfe] unspecified
+  //  ^^
   // [cfe] unspecified
 
   c1b.m1++;
   //  ^^
   // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+  //  ^^
+  // [cfe] unspecified
+  //  ^^
   // [cfe] unspecified
 
   c1b.m2;
@@ -165,7 +171,6 @@
   // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
   // [cfe] unspecified
 
-
   c1b[0];
   //  ^^
   // [analyzer] unspecified
@@ -179,11 +184,17 @@
   c1b[0] += 0;
   //  ^^
   // [analyzer] unspecified
+  // ^
+  // [cfe] unspecified
+  // ^
   // [cfe] unspecified
 
   c1b[0]++;
   //  ^^
   // [analyzer] unspecified
+  // ^
+  // [cfe] unspecified
+  // ^
   // [cfe] unspecified
 }
 
diff --git a/tests/language_2/extension_methods/static_extension_internal_name_conflict_error_test.dart b/tests/language_2/extension_methods/static_extension_internal_name_conflict_error_test.dart
index 0e55982..6e4ebdfb 100644
--- a/tests/language_2/extension_methods/static_extension_internal_name_conflict_error_test.dart
+++ b/tests/language_2/extension_methods/static_extension_internal_name_conflict_error_test.dart
@@ -112,23 +112,18 @@
   static int method() => 0;
   //         ^^^^^^
   // [analyzer] COMPILE_TIME_ERROR.EXTENSION_CONFLICTING_STATIC_AND_INSTANCE
-  // [cfe] unspecified
   static int get property => 1;
   //             ^^^^^^^^
   // [analyzer] COMPILE_TIME_ERROR.EXTENSION_CONFLICTING_STATIC_AND_INSTANCE
-  // [cfe] unspecified
   static void set property(int value) {}
   //              ^^^^^^^^
   // [analyzer] COMPILE_TIME_ERROR.EXTENSION_CONFLICTING_STATIC_AND_INSTANCE
-  // [cfe] unspecified
   static int get property2 => 1;
   //             ^^^^^^^^^
   // [analyzer] COMPILE_TIME_ERROR.EXTENSION_CONFLICTING_STATIC_AND_INSTANCE
-  // [cfe] unspecified
   static void set property3(int x) {}
   //              ^^^^^^^^^
   // [analyzer] COMPILE_TIME_ERROR.EXTENSION_CONFLICTING_STATIC_AND_INSTANCE
-  // [cfe] unspecified
   static int field = 3;
   //         ^^^^^
   // [analyzer] COMPILE_TIME_ERROR.EXTENSION_CONFLICTING_STATIC_AND_INSTANCE
@@ -136,15 +131,28 @@
   static int field2 = 3;
   //         ^^^^^^
   // [analyzer] COMPILE_TIME_ERROR.EXTENSION_CONFLICTING_STATIC_AND_INSTANCE
-  // [cfe] unspecified
 
   int method() => 0;
+  //  ^^^^^^
+  // [cfe] unspecified
   int get property => 1;
+  //      ^^^^^^^^
+  // [cfe] unspecified
   void set property(int value) {}
+  //       ^^^^^^^^
+  // [cfe] unspecified
   void set property2(int value) {}
+  //       ^^^^^^^^^
+  // [cfe] unspecified
   int get property3 => 1;
+  //      ^^^^^^^^^
+  // [cfe] unspecified
   void set field(int value) {}
+  //       ^^^^^
+  // [cfe] unspecified
   int get field2 => 1;
+  //      ^^^^^^
+  // [cfe] unspecified
 }
 
 // Check a static method colliding with a static getter.
@@ -159,6 +167,8 @@
 // Check a static method colliding with a static setter.
 extension E7 on int {
   static int method() => 0;
+  //         ^^^^^^
+  // [cfe] unspecified
   static void set method(int value) {}
   //              ^^^^^^
   // [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
@@ -197,8 +207,9 @@
   static int method() => 0;
   //         ^^^^^^
   // [analyzer] COMPILE_TIME_ERROR.EXTENSION_CONFLICTING_STATIC_AND_INSTANCE
-  // [cfe] unspecified
   int get method => 1;
+  //      ^^^^^^
+  // [cfe] unspecified
 }
 
 // Check a static method colliding with an instance setter.
@@ -206,8 +217,9 @@
   static int method() => 0;
   //         ^^^^^^
   // [analyzer] COMPILE_TIME_ERROR.EXTENSION_CONFLICTING_STATIC_AND_INSTANCE
-  // [cfe] unspecified
   void set method(int value) {}
+  //       ^^^^^^
+  // [cfe] unspecified
 }
 
 // Check an instance method colliding with a static getter.
diff --git a/tests/lib_2/lib_2.status b/tests/lib_2/lib_2.status
index 097b176..8aadd79 100644
--- a/tests/lib_2/lib_2.status
+++ b/tests/lib_2/lib_2.status
@@ -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.
 html/cross_frame_test: Skip # Issue 32039, test reloads itself (not by design - investigate)
+wasm/*: Skip # dart:wasm is currently behind a Dart SDK build flag.
 
 [ $arch == simarm64 ]
 convert/utf85_test: Skip # Pass, Slow Issue 20111.
diff --git a/tests/lib_2/wasm/basic_test.dart b/tests/lib_2/wasm/basic_test.dart
index 34ae182..4ab1e7c 100644
--- a/tests/lib_2/wasm/basic_test.dart
+++ b/tests/lib_2/wasm/basic_test.dart
@@ -20,9 +20,9 @@
     0x7e, 0x0b,
   ]);
 
-  var inst = WasmModule(data).instantiate(WasmImports("env")
-    ..addMemory("memory", WasmMemory(256, 1024))
-    ..addGlobal<Int32>("__memory_base", 1024, false));
+  var inst = WasmModule(data).instantiate(WasmImports()
+    ..addMemory("env", "memory", WasmMemory(256, 1024))
+    ..addGlobal<Int32>("env", "__memory_base", 1024, false));
   var fn = inst.lookupFunction<Int64 Function(Int64)>("square");
   int n = fn.call([1234]);
 
diff --git a/tests/lib_2/wasm/fn_call_error_test.dart b/tests/lib_2/wasm/fn_call_error_test.dart
index e1d2441..db696d7 100644
--- a/tests/lib_2/wasm/fn_call_error_test.dart
+++ b/tests/lib_2/wasm/fn_call_error_test.dart
@@ -20,9 +20,9 @@
     0x7e, 0x0b,
   ]);
 
-  var inst = WasmModule(data).instantiate(WasmImports("env")
-    ..addMemory("memory", WasmMemory(256, 1024))
-    ..addGlobal<Int32>("__memory_base", 1024, false));
+  var inst = WasmModule(data).instantiate(WasmImports()
+    ..addMemory("env", "memory", WasmMemory(256, 1024))
+    ..addGlobal<Int32>("env", "__memory_base", 1024, false));
   var fn = inst.lookupFunction<Int64 Function(Int64)>("square");
 
   Expect.throwsArgumentError(() => fn.call([]));
diff --git a/tests/lib_2/wasm/fn_import_error_test.dart b/tests/lib_2/wasm/fn_import_error_test.dart
new file mode 100644
index 0000000..40466fb
--- /dev/null
+++ b/tests/lib_2/wasm/fn_import_error_test.dart
@@ -0,0 +1,60 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test errors thrown by function imports.
+
+import "package:expect/expect.dart";
+import "dart:wasm";
+import "dart:typed_data";
+
+void main() {
+  // This module expects a function import like:
+  // int64_t someFn(int32_t a, int64_t b, float c, double d);
+  var data = Uint8List.fromList([
+    0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0c, 0x02, 0x60,
+    0x04, 0x7f, 0x7e, 0x7d, 0x7c, 0x01, 0x7e, 0x60, 0x00, 0x00, 0x02, 0x0e,
+    0x01, 0x03, 0x65, 0x6e, 0x76, 0x06, 0x73, 0x6f, 0x6d, 0x65, 0x46, 0x6e,
+    0x00, 0x00, 0x03, 0x02, 0x01, 0x01, 0x04, 0x05, 0x01, 0x70, 0x01, 0x01,
+    0x01, 0x05, 0x03, 0x01, 0x00, 0x02, 0x06, 0x08, 0x01, 0x7f, 0x01, 0x41,
+    0x80, 0x88, 0x04, 0x0b, 0x07, 0x11, 0x02, 0x06, 0x6d, 0x65, 0x6d, 0x6f,
+    0x72, 0x79, 0x02, 0x00, 0x04, 0x62, 0x6c, 0x61, 0x68, 0x00, 0x01, 0x0a,
+    0x1d, 0x01, 0x1b, 0x00, 0x41, 0x01, 0x42, 0x02, 0x43, 0x00, 0x00, 0x40,
+    0x40, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x40, 0x10, 0x80,
+    0x80, 0x80, 0x80, 0x00, 0x1a, 0x0b,
+  ]);
+
+  var mod = WasmModule(data);
+  var imp = WasmImports()
+    ..addFunction<Int64 Function(Int32, Int64, Float, Double)>(
+        "env", "someFn", (num a, num b, num c, num d) => 123);
+  mod.instantiate(imp);
+
+  imp = WasmImports();
+  Expect.throwsArgumentError(() => mod.instantiate(imp));
+
+  imp = WasmImports()
+    ..addFunction<Int64 Function(Int32)>("env", "someFn", (num a) => 123);
+  Expect.throwsArgumentError(() => mod.instantiate(imp));
+
+  imp = WasmImports()
+    ..addFunction<Double Function(Int32, Int64, Float, Double)>(
+        "env", "someFn", (num a, num b, num c, num d) => 123);
+  Expect.throwsArgumentError(() => mod.instantiate(imp));
+
+  imp = WasmImports()
+    ..addFunction<Int64 Function(Int32, Int64, Float, Float)>(
+        "env", "someFn", (num a, num b, num c, num d) => 123);
+  Expect.throwsArgumentError(() => mod.instantiate(imp));
+
+  Expect.throwsArgumentError(() => WasmImports()
+    ..addFunction<dynamic Function(Int32, Int64, Float, Double)>(
+        "env", "someFn", (num a, num b, num c, num d) => 123));
+
+  Expect.throwsArgumentError(() => WasmImports()
+    ..addFunction<Int64 Function(Int32, Int64, dynamic, Double)>(
+        "env", "someFn", (num a, num b, num c, num d) => 123));
+
+  imp = WasmImports()..addGlobal<Int64>("env", "someFn", 123, false);
+  Expect.throwsArgumentError(() => mod.instantiate(imp));
+}
diff --git a/tests/lib_2/wasm/fn_import_exception_test.dart b/tests/lib_2/wasm/fn_import_exception_test.dart
new file mode 100644
index 0000000..73298d9
--- /dev/null
+++ b/tests/lib_2/wasm/fn_import_exception_test.dart
@@ -0,0 +1,47 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test throwing exceptions from an imported function.
+
+import "package:expect/expect.dart";
+import "dart:wasm";
+import "dart:typed_data";
+
+void main() {
+  // int64_t fn(int64_t x) { return throwIfNegative(x); }
+  var data = Uint8List.fromList([
+    0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x06, 0x01, 0x60,
+    0x01, 0x7e, 0x01, 0x7e, 0x02, 0x17, 0x01, 0x03, 0x65, 0x6e, 0x76, 0x0f,
+    0x74, 0x68, 0x72, 0x6f, 0x77, 0x49, 0x66, 0x4e, 0x65, 0x67, 0x61, 0x74,
+    0x69, 0x76, 0x65, 0x00, 0x00, 0x03, 0x02, 0x01, 0x00, 0x04, 0x05, 0x01,
+    0x70, 0x01, 0x01, 0x01, 0x05, 0x03, 0x01, 0x00, 0x02, 0x06, 0x08, 0x01,
+    0x7f, 0x01, 0x41, 0x80, 0x88, 0x04, 0x0b, 0x07, 0x0f, 0x02, 0x06, 0x6d,
+    0x65, 0x6d, 0x6f, 0x72, 0x79, 0x02, 0x00, 0x02, 0x66, 0x6e, 0x00, 0x01,
+    0x0a, 0x0c, 0x01, 0x0a, 0x00, 0x20, 0x00, 0x10, 0x80, 0x80, 0x80, 0x80,
+    0x00, 0x0b,
+  ]);
+
+  dynamic override = null;
+  var inst = WasmModule(data).instantiate(WasmImports()
+    ..addMemory("env", "memory", WasmMemory(256, 1024))
+    ..addGlobal<Int32>("env", "__memory_base", 1024, false)
+    ..addFunction<Int64 Function(Int64)>("env", "throwIfNegative", (int x) {
+      if (x < 0) {
+        throw Exception(x);
+      }
+      if (override != null) {
+        return override;
+      }
+      return x;
+    }));
+  var fn = inst.lookupFunction<Int64 Function(Int64)>("fn");
+
+  Expect.equals(123, fn.call([123]));
+  Expect.throws(() => fn.call([-456]), (Exception e) => "$e".contains("-456"));
+
+  override = "Not an integer";
+  Expect.throwsArgumentError(() => fn.call([789]));
+  override = 0.123;
+  Expect.throwsArgumentError(() => fn.call([789]));
+}
diff --git a/tests/lib_2/wasm/fn_import_test.dart b/tests/lib_2/wasm/fn_import_test.dart
new file mode 100644
index 0000000..8172c20
--- /dev/null
+++ b/tests/lib_2/wasm/fn_import_test.dart
@@ -0,0 +1,39 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test that we can load a wasm module, find a function, and call it.
+
+import "package:expect/expect.dart";
+import "dart:wasm";
+import "dart:typed_data";
+
+void main() {
+  // void reportStuff() { report(123, 456); }
+  var data = Uint8List.fromList([
+    0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x09, 0x02, 0x60,
+    0x02, 0x7e, 0x7e, 0x00, 0x60, 0x00, 0x00, 0x02, 0x0e, 0x01, 0x03, 0x65,
+    0x6e, 0x76, 0x06, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x00, 0x00, 0x03,
+    0x02, 0x01, 0x01, 0x04, 0x05, 0x01, 0x70, 0x01, 0x01, 0x01, 0x05, 0x03,
+    0x01, 0x00, 0x02, 0x06, 0x08, 0x01, 0x7f, 0x01, 0x41, 0x80, 0x88, 0x04,
+    0x0b, 0x07, 0x18, 0x02, 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x02,
+    0x00, 0x0b, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x53, 0x74, 0x75, 0x66,
+    0x66, 0x00, 0x01, 0x0a, 0x10, 0x01, 0x0e, 0x00, 0x42, 0xfb, 0x00, 0x42,
+    0xc8, 0x03, 0x10, 0x80, 0x80, 0x80, 0x80, 0x00, 0x0b,
+  ]);
+
+  int report_x = -1;
+  int report_y = -1;
+
+  var inst = WasmModule(data).instantiate(WasmImports()
+    ..addMemory("env", "memory", WasmMemory(256, 1024))
+    ..addGlobal<Int32>("env", "__memory_base", 1024, false)
+    ..addFunction<Void Function(Int64, Int64)>("env", "report", (int x, int y) {
+      report_x = x;
+      report_y = y;
+    }));
+  var fn = inst.lookupFunction<Void Function()>("reportStuff");
+  fn.call([]);
+  Expect.equals(report_x, 123);
+  Expect.equals(report_y, 456);
+}
diff --git a/tests/lib_2/wasm/fn_mismatch_error_test.dart b/tests/lib_2/wasm/fn_mismatch_error_test.dart
index b12d515..01e825b 100644
--- a/tests/lib_2/wasm/fn_mismatch_error_test.dart
+++ b/tests/lib_2/wasm/fn_mismatch_error_test.dart
@@ -20,9 +20,9 @@
     0x7e, 0x0b,
   ]);
 
-  var inst = WasmModule(data).instantiate(WasmImports("env")
-    ..addMemory("memory", WasmMemory(256, 1024))
-    ..addGlobal<Int32>("__memory_base", 1024, false));
+  var inst = WasmModule(data).instantiate(WasmImports()
+    ..addMemory("env", "memory", WasmMemory(256, 1024))
+    ..addGlobal<Int32>("env", "__memory_base", 1024, false));
   Expect.isNotNull(inst.lookupFunction<Int64 Function(Int64)>("square"));
   Expect.throwsArgumentError(
       () => inst.lookupFunction<Int64 Function(Int64)>("blah"));
diff --git a/tests/lib_2/wasm/import_error_test.dart b/tests/lib_2/wasm/import_error_test.dart
new file mode 100644
index 0000000..071dc4b
--- /dev/null
+++ b/tests/lib_2/wasm/import_error_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test errors thrown by WasmImports.
+
+import "package:expect/expect.dart";
+import "dart:wasm";
+import "dart:typed_data";
+
+void main() {
+  var imp = WasmImports();
+  Expect.throwsArgumentError(() => imp.addGlobal<int>("env", "a", 1, true));
+  Expect.throwsArgumentError(() => imp.addGlobal<double>("env", "b", 2, true));
+  Expect.throwsArgumentError(() => imp.addGlobal<dynamic>("env", "c", 3, true));
+}
diff --git a/tests/lib_2/wasm/memory_error_test.dart b/tests/lib_2/wasm/memory_error_test.dart
new file mode 100644
index 0000000..e866bf0
--- /dev/null
+++ b/tests/lib_2/wasm/memory_error_test.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test errors thrown by WasmMemory.
+
+import "package:expect/expect.dart";
+import "dart:wasm";
+import "dart:typed_data";
+
+void main() {
+  Expect.throwsArgumentError(() => WasmMemory(1000000000));
+  var mem = WasmMemory(1000);
+  Expect.throwsArgumentError(() => mem.grow(1000000000));
+}
diff --git a/tests/lib_2/wasm/memory_test.dart b/tests/lib_2/wasm/memory_test.dart
index 1160aca..52d12c3 100644
--- a/tests/lib_2/wasm/memory_test.dart
+++ b/tests/lib_2/wasm/memory_test.dart
@@ -20,4 +20,7 @@
   Expect.equals(1100, mem.lengthInPages);
   Expect.equals(1100 * WasmMemory.kPageSizeInBytes, mem.lengthInBytes);
   Expect.equals(45, mem[123]);
+
+  Expect.throwsArgumentError(() => WasmMemory(1000000000));
+  Expect.throwsArgumentError(() => mem.grow(1000000000));
 }
diff --git a/tests/lib_2/wasm/numerics_test.dart b/tests/lib_2/wasm/numerics_test.dart
index 1d7a199..6255d20 100644
--- a/tests/lib_2/wasm/numerics_test.dart
+++ b/tests/lib_2/wasm/numerics_test.dart
@@ -29,9 +29,9 @@
     0x01, 0x92, 0x0b,
   ]);
 
-  var inst = WasmModule(data).instantiate(WasmImports("env")
-    ..addMemory("memory", WasmMemory(256, 1024))
-    ..addGlobal<Int32>("__memory_base", 1024, false));
+  var inst = WasmModule(data).instantiate(WasmImports()
+    ..addMemory("env", "memory", WasmMemory(256, 1024))
+    ..addGlobal<Int32>("env", "__memory_base", 1024, false));
   var addI64 = inst.lookupFunction<Int64 Function(Int64, Int64)>("addI64");
   var addI32 = inst.lookupFunction<Int32 Function(Int32, Int32)>("addI32");
   var addF64 = inst.lookupFunction<Double Function(Double, Double)>("addF64");
diff --git a/tests/lib_2/wasm/void_test.dart b/tests/lib_2/wasm/void_test.dart
index c2f0707..210c9b0 100644
--- a/tests/lib_2/wasm/void_test.dart
+++ b/tests/lib_2/wasm/void_test.dart
@@ -25,9 +25,9 @@
     0x80, 0x08, 0x0b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   ]);
 
-  var inst = WasmModule(data).instantiate(WasmImports("env")
-    ..addMemory("memory", WasmMemory(256, 1024))
-    ..addGlobal<Int32>("__memory_base", 1024, false));
+  var inst = WasmModule(data).instantiate(WasmImports()
+    ..addMemory("env", "memory", WasmMemory(256, 1024))
+    ..addGlobal<Int32>("env", "__memory_base", 1024, false));
   var setFn = inst.lookupFunction<Void Function(Int64, Int64)>("set");
   var getFn = inst.lookupFunction<Int64 Function()>("get");
   Expect.isNull(setFn.call([123, 456]));
diff --git a/tools/VERSION b/tools/VERSION
index e6b0140..f4e2a13 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -33,7 +33,7 @@
 MAJOR 2
 MINOR 6
 PATCH 0
-PRERELEASE 3
+PRERELEASE 4
 PRERELEASE_PATCH 0
 ABI_VERSION 16
 OLDEST_SUPPORTED_ABI_VERSION 16
diff --git a/tools/bots/test_matrix.json b/tools/bots/test_matrix.json
index aca2268..201302b 100644
--- a/tools/bots/test_matrix.json
+++ b/tools/bots/test_matrix.json
@@ -202,6 +202,8 @@
       "samples-dev/",
       "tools/",
       "third_party/android_tools/sdk/platform-tools/adb",
+      "third_party/android_tools/ndk/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/aarch64-linux-android-strip",
+      "third_party/android_tools/ndk/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-strip",
       "third_party/pkg/",
       "third_party/pkg_tested/",
       "third_party/observatory_pub_packages/packages/",
@@ -780,14 +782,18 @@
           "name": "build dart",
           "script": "tools/build.py",
           "arguments": ["runtime"],
-          "environment": {"DART_USE_ASAN": 1}
+          "environment": {
+            "DART_USE_ASAN": 1,
+            "ASAN_OPTIONS": "handle_segv=0:detect_leaks=1:detect_stack_use_after_return=0:disable_coredump=0",
+            "ASAN_SYMBOLIZER_PATH": "buildtools/linux-x64/clang/bin/llvm-symbolizer"
+          }
         },
         {
           "name": "vm tests",
           "arguments": [
             "-ndartk-asan-linux-release-${arch}"],
           "environment": {
-            "ASAN_OPTIONS": "handle_segv=0:detect_stack_use_after_return=0:disable_coredump=0",
+            "ASAN_OPTIONS": "handle_segv=0:detect_leaks=1:detect_stack_use_after_return=0:disable_coredump=0",
             "ASAN_SYMBOLIZER_PATH": "buildtools/linux-x64/clang/bin/llvm-symbolizer"
           }
         }
diff --git a/tools/generate_idefiles.py b/tools/generate_idefiles.py
index 6e8ead5..a7b89d8 100755
--- a/tools/generate_idefiles.py
+++ b/tools/generate_idefiles.py
@@ -84,7 +84,7 @@
 
   To prevent dartanalyzer from tripping on the non-Dart files when it is
   started from the root dart-sdk directory.
-  https://github.com/Dart-Code/Dart-Code/issues/1295
+  https://github.com/dart-lang/sdk/issues/35562
 
   Args:
     options: supported options include: force, dir
@@ -96,6 +96,7 @@
     - runtime/**
     - samples-dev/swarm/**
     - sdk/lib/**
+    - sdk_nnbd/lib/**
     - tests/**
     - third_party/observatory_pub_packages/**
     - third_party/pkg/**
@@ -106,7 +107,7 @@
     - tools/dom/**
     - tools/sdks/dart-sdk/lib/**
     - tools/status_clean.dart
-    - xcodebuild / **"""
+    - xcodebuild/**"""
 
     fname = os.path.join(options.dir, "analysis_options.yaml")
 
diff --git a/utils/application_snapshot.gni b/utils/application_snapshot.gni
index 4356f1c..c012046 100644
--- a/utils/application_snapshot.gni
+++ b/utils/application_snapshot.gni
@@ -78,11 +78,10 @@
   # Build the kernel file using the prebuilt VM to speed up the debug and
   # simulator builds.
   prebuilt_dart_action(target_name + "_dill") {
-    deps =
-        extra_deps + [
-          "$_dart_root/runtime/vm:kernel_platform_files($dart_host_toolchain)",
-          "$_dart_root/runtime/vm:vm_platform",
-        ]
+    deps = extra_deps + [
+             "$_dart_root/runtime/vm:kernel_platform_files($host_toolchain)",
+             "$_dart_root/runtime/vm:vm_platform",
+           ]
     gen_kernel_script = "$_dart_root/pkg/vm/bin/gen_kernel.dart"
     platform_dill = "$root_out_dir/vm_platform_strong.dill"
 
diff --git a/utils/kernel-service/BUILD.gn b/utils/kernel-service/BUILD.gn
index 9ed386a..c65d570 100644
--- a/utils/kernel-service/BUILD.gn
+++ b/utils/kernel-service/BUILD.gn
@@ -3,7 +3,6 @@
 # BSD-style license that can be found in the LICENSE file.
 
 import("../../build/dart/dart_action.gni")
-import("../../build/dart/dart_host_sdk_toolchain.gni")
 import("../../runtime/runtime_args.gni")
 import("../application_snapshot.gni")
 
@@ -50,7 +49,7 @@
 application_snapshot("frontend_server") {
   main_dart = "../../pkg/vm/bin/frontend_server_starter.dart"
   deps = [
-    "../../runtime/vm:kernel_platform_files($dart_host_toolchain)",
+    "../../runtime/vm:kernel_platform_files($host_toolchain)",
   ]
   sdk_root = rebase_path("$root_out_dir")
   training_args = [
@@ -65,7 +64,7 @@
 template("kernel_service_dill") {
   prebuilt_dart_action("kernel_service" + target_name + "_dill") {
     deps = [
-      "../../runtime/vm:kernel_platform_files($dart_host_toolchain)",
+      "../../runtime/vm:kernel_platform_files($host_toolchain)",
       "../../runtime/vm:vm_platform",
     ]
     kernel_service_script = "../../pkg/vm/bin/kernel_service.dart"